I am trying to open a camera on my Cordova app since moving it over to Android Studio and now it has stopped working.
I get no popup of permissions, or anything on the user side to show me otherwise.
I get the following error in the Android Monitor
com.ontrac.nutshellmobile E/ViewRootImpl: sendUserActionEvent() returned.
E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=8324, uid=10182 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:616)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:487)
at android.content.ContentProvider$Transport.query(ContentProvider.java:216)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:573)
My manifest has the following permissions
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="26" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
I am running API 26 for the compile SDK version on the project structure.
My build gradle files contain the SDK versions of
minSdkVersion 23
targetSdkVersion 25
compileSdkVersion 26
buildToolsVersion '26.0.0'
I have tried moving the permissions over to the Cordova Android manifest but no luck. I cant seem to figure out what is causing the error.
Any help would be greatly appreciated. I can give more information if needed.
In order to open camera, you have to install cordova-plugin-android-permissions.
you have to ask for 2 permissions: READ_EXTERNAL_STORAGE and CAMERA, and open the camera in the callback function of the 2 functions.
example of the js code:
function takePicture() {
var permissions = cordova.plugins.permissions;
permissions.requestPermission(permissions.READ_EXTERNAL_STORAGE,
function (status) {
if (!status.hasPermission)
error();
else
permissions.requestPermission(permissions.CAMERA, success.bind(this),
error);
function error() {
console.warn('CAMERA permission is not turned on');
}
}
, error);
function error() {
console.warn('READ_EXTERNAL_STORAGE permission is not turned on');
}
function success(status) {
if (!status.hasPermission)
error();
else
openCamera();
}
}
function openCamera() {
navigator.camera.getPicture(onSuccess, onFail, {
quality: 25,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
var src = "data:image/png;base64," + imageData;
console.log(src);
alert('got picture!!!');
}
function onFail(message) {
alert('error ' + message);
}
}
takePicture();
Related
I am making an video app in kotlin and making my own camera using surfaceview. But whenever I run my app its showing white screen and the buttons which I have added. Its returning an error
E/SurfaceView: Exception configuring surface
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:519)
at android.hardware.Camera.open(Camera.java:383)
at com.example.videoapp.Chooses.surfaceCreated(Chooses.kt:174)
at android.view.SurfaceView.updateSurface(SurfaceView.java:663)
at android.view.SurfaceView$2.onPreDraw(SurfaceView.java:143)
and its saying that the error is from this code
override fun surfaceCreated(holder: SurfaceHolder?) {
println("onsurfacecreated")
if (usecamera) {
camera = Camera.open()
try {
camera?.setPreviewDisplay(holder)
camera?.startPreview()
previewRunning = true
} catch (e: IOException) {
e.printStackTrace()
}
}
}
and here is my manifest file permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="Manifest.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I'm using ionic 1 .
My app is displaying a camera realtime using the Cordova Plugin Camera Preview (9.0.0 (cordova-lib#9.0.1))
I am previewing the apk with this command from my desktop :
ionic cordova run android
My code works really well with a homtom phone using android 5 .
But on my Android 7 Doggee phone, it is displaying a big triangle, I can't even click on it to take a picture .
This is my code :
var videoElement = document.getElementById("video");
var videoSrc = undefined;
navigator.mediaDevices.enumerateDevices()
.then(getDevices).then(getStream).catch(handleError);
function getDevices(deviceInfos) {
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
if (deviceInfo.kind === 'videoinput') {
videoSrc = deviceInfo.deviceId;
break;
}
}
}
function getStream() {
navigator.mediaDevices.getUserMedia({
video: {
deviceId: {
exact: videoSrc
}
}
}).
then(gotStream).catch(handleError);
}
function gotStream(stream) {
videoElement.srcObject = stream;
}
function handleError(error) {
console.log('Error: ', error);
}
And my myproject/platforms/android/app/src/amin/AndroidManifest.xml
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="io.ionic.starter" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:networkSecurityConfig="#xml/network_security_config" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="#string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="#string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.cordovaplugincamerapreview.CameraActivity" android:screenOrientation="portrait" android:theme="#style/CameraPreviewTheme" />
</application>
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-feature android:name="android.hardware.camera2.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.webkit.PermissionRequest" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
</manifest>
Then in my \myproject\platforms\android\app\src\main\res\xml\config.xml
I only have this camera feature :
<feature name="CameraPreview">
<param name="android-package" value="com.cordovaplugincamerapreview.CameraPreview" />
<param name="onload" value="true" />
</feature>
This is the error in the phone console
Error: DOMException: Could not start source
EDIT : Finally solved partially :
I have to go into the settings for the application
and give it access to the camera. I thought that I had permission in the
manifest file, but it didn’t seem to grant it for me.
Scott
Use diagnose plugin to check and ask android permission solved my issue.
checkpermission()
{
this.diagnostic.getPermissionAuthorizationStatus(this.diagnostic.permission.CAMERA)
.then((status) => {
switch(status){
case this.diagnostic.permissionStatus.GRANTED:
console.log("Permission granted to use the camera");
break;
case this.diagnostic.permissionStatus.NOT_REQUESTED:
console.log("Permission to use the camera has not been requested yet");
break;
case this.diagnostic.permissionStatus.DENIED:
console.log("Permission denied to use the camera - ask again?");
break;
case this.diagnostic.permissionStatus.DENIED_ALWAYS:
console.log("Permission permanently denied to use the camera - guess we won't be using it then!");
break;
}
})
.catch((error) => {
console.error("The following error occurred: "+error);
});
this.diagnostic.requestRuntimePermission(this.diagnostic.permission.CAMERA)
.then((status) => {
switch(status){
case this.diagnostic.permissionStatus.GRANTED:
console.log("Permission granted to use the camera");
break;
case this.diagnostic.permissionStatus.NOT_REQUESTED:
console.log("Permission to use the camera has not been requested yet");
break;
case this.diagnostic.permissionStatus.DENIED:
console.log("Permission denied to use the camera - ask again?");
break;
case this.diagnostic.permissionStatus.DENIED_ALWAYS:
console.log("Permission permanently denied to use the camera - guess we won't be using it then!");
break;
}
})
.catch((error) => {
console.error("The following error occurred: "+error);
});
}
This question already has answers here:
How to fix "Fail to connect to camera service" exception in Android emulator
(7 answers)
Closed 1 year ago.
i am developing an android app which has an flash option which is set to auto mode,but it crashes at camera.open.I have used intent to open camera
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
int result = context.checkCallingOrSelfPermission(Manifest.permission.CAMERA);
int result2 = context.checkCallingOrSelfPermission(Manifest.permission.FLASHLIGHT);
if((result==PackageManager.PERMISSION_GRANTED) && (result2==PackageManager.PERMISSION_GRANTED)) {
cam = Camera.open();
Camera.Parameters p = cam.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
cam.setParameters(p);
cam.startPreview();
}
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(cameraIntent,CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}});
HERE IS LOGCAT
04-10 15:44:58.928 13248-13248/com.t4u.aapam E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.t4u.aapam, PID: 13248
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:529)
at android.hardware.Camera.open(Camera.java:379)
at com.t4u.aapam.ListViewDisplay$1.onItemClick(ListViewDisplay.java:402)
at android.widget.AdapterView.performItemClick(AdapterView.java:305)
at android.widget.AbsListView.performItemClick(AbsListView.java:1148)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3059)
at android.widget.AbsListView$3.run(AbsListView.java:3866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
here is my manifest file.i have added camera permission and flashlight permisssion.I have also added camera hardware permisssion
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.t4u.aapam">
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.telematics4u.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash"
android:required="false" />
<application
android:name="com.t4u.aapam.App"
android:allowBackup="true"
android:icon="#drawable/launcher_logo"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I may be wrong(because I don't see your Manifest.xml file) but there are two solutions I can see
1) The camera cannot be connected to because it is already being used by a different application
You cannot fix that. If the camera is occupied, you can't open it.
2) You haven't requested the Camera-permission.
This can be solved. In your manifest:
<uses-permission android:name="android.permission.CAMERA"/>
And if you are targeting android 6 you have to request the permission at runtime. For that, see this link.
EDIT:
Make sure you add all of these. This will give your app access to the camera and flashlight in software and hardware.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.flash"/>
Using these without requiring them makes the app not work if the device (against all odds) doesn't have a camera
you should use all these permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash"
android:required="false" />
Maybe this can help but i am not sure
<permission android:name="android.permission.FLASHLIGHT"
android:permissionGroup="android.permission-
group.HARDWARE_CONTROLS"
android:protectionLevel="normal"/>
I have found a few other questions about this issue but none of the answers have solved it for me. I'm trying to request the fine location permission, but there is no dialog shown. Here's what I'm doing:
int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION);
if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
Log.d("Location","Location permission already granted"); // Not logged
// Do other stuff
}
else {
Log.d("Location", "Requesting location permission"); // This is logged
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ENABLE_LOCATION);
}
No dialog appears, and onRequestPermissionsResult is not called.
This is the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.common" android:installLocation="auto">
<!-- Normal permissions -->
<uses-permission android:name="android.permission.ACCESS_GPS" android:required="false"/>
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.android.vending.billing.IN_APP_NOTIFY" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" >
</supports-screens>
<application
android:name="com.company.common.App"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<meta-data android:name="AA_DB_NAME" android:value="propertyforce.db" />
<meta-data android:name="AA_DB_VERSION" android:value="11" />
<meta-data android:name="AA_SERIALIZERS"
android:value="com.company.common.utils.db.JSONObjectSerializer,
com.company.common.utils.db.JSONArraySerializer,
com.company.common.utils.db.AddressSerializer" />
<meta-data
android:name="AA_MODELS"
android:value="com.company.common.utils.db.Model" />
<activity
android:name="com.company.common.Name"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_label"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.AnActivity"/>
<!-- Other activities -->
<service
android:name="com.company.common.utils.services.LogDeleter"
android:icon="#drawable/icon"
android:label="Log Deleter" >
</service>
</application>
</manifest>
Here are some tidbits from the gradle file:
compileSdkVersion 23
buildToolsVersion '21.1.2'
defaultConfig {
minSdkVersion 12
targetSdkVersion 23
}
This is in a FragmentActivity, don't know if that matters. I have uninstalled the app and run it so there should be no permissions already accepted. This is on a Nexus 7 running 6.0.
Why not try this library: https://github.com/tajchert/Nammu. It worked for me.
Nammu.askForPermission(activity, String[] permissions, new PermissionCallback() {
#Override
public void permissionGranted() {}
#Override
public void permissionRefused() {}
});
EDIT
I created a library that encapsulates the whole thing and makes it much more easier. It also shows a customisable explanation dialog before the actual request.
Use this library: https://github.com/ayz4sci/permissionHelper
Usage:
To perform an action that requires Android permission, call permissionHelper.verifyPermission. It accepts the following parameters:
String [] - description of each permission required, this will be displayed to the user in the explanation dialog.
String [] - an array of Manifest permissions
PermissionCallback - you put the actions you want to perform when permission is granted or rejected.
See example below:
permissionHelper.verifyPermission(
new String[]{"dial this number", "take picture"},
new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA},
new PermissionCallback() {
#Override
public void permissionGranted() {
//action to perform when permission granteed
}
#Override
public void permissionRefused() {
//action to perform when permission refused
}
}
);
In my Cordova2.9.0 based Android Application i have include camera functionality.When i take Camera using Galazy S3 the application restarts,I found some solution links like
1.Link1 2.Link2
and added changes with
Android manifest file
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:alwaysRetainTaskState="true" android:launchMode="singleTask"/>
But still the is not fixed.Here my camera Code
function capturePhoto()
{
navigator.camera.getPicture(onPhotoURISuccess,fail, {
quality: 50,
destinationType:Camera.DestinationType.FILE_URI
}
);
}
Can any one please help me to solve this issue.
Here I share my working code.
Please try with that and tell me if you got solution.
JS Part:
<script type="text/javascript" charset="utf-8">
var pictureSource;
var destinationType;
document.addEventListener("deviceready",onDeviceReady,false);
function onDeviceReady() {
pictureSource=navigator.camera.PictureSourceType;
destinationType=navigator.camera.DestinationType;
}
function onPhotoURISuccess(imageURI) {
var largeImage = document.getElementById('largeImage');
largeImage.style.display = 'block';
largeImage.src = imageURI;
}
function capturePhoto() {
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50, destinationType: destinationType.FILE_URI });
}
function onFail(message) {
alert('Failed because: ' + message);
}
</script>
HTML Part:
<button onclick="capturePhoto();">Capture Photo</button><br />
<img style="display:none;width:60px;height:60px;" id="largeImage" src="" />
Rest of them config.xml and manifest.xml are same what you mentioned.
app/res/xml/config.xml
<plugin name="Camera" value="org.apache.cordova.CameraLauncher" />
have you placed it.....
It solved after I restart the phone (Samsung Grant android 4.1.2)