Reputation: 1083
GoodDay.
Using help gotten from the developers guide, I was able to get my app's photo capture working. The activity usually involves capturing one or more images(something like in photogrid camera collage app). It works most of the time, and on most devices, except on my own device(Android 5.0.1). Issue is, the camera/gallery app crashes, giving me a Security permission denial error in the stack trace, and I've searched for solutions and implemented them, but to no avail. The crash is usually random, but is more likely to occur when: 1. I'm taking the second photo 2. My camera settings are on the highest resolution :13MP (Hardly ever happens on lower resolutions)
It rarely occurs in other cases though, but its occurrence drives me crazy. Here's my code:
Fragment
private void dispatchTakePictureIntent(boolean isQuestionImage) {
Intent takePictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile(isQuestionImage);
} catch (IOException ex) {
Log.e("photofile part", "Error: "+ex);
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.operator.u_learn.fileprovider", photoFile);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
List<ResolveInfo> resolvedIntentActivities = getActivity()
.getPackageManager()
.queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
String packageName = resolvedIntentInfo.activityInfo.packageName;
getActivity().grantUriPermission(packageName,
photoURI,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
if(isQuestionImage)
startActivityForResult(takePictureIntent, REQUEST_QUESTION_IMAGE_CAPTURE);
else
startActivityForResult(takePictureIntent, REQUEST_EXPLANATION_IMAGE_CAPTURE);
//revoke permissions after use
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
getActivity().revokeUriPermission(photoURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
}
}
AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.operator.u_learn.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-
data>
</provider>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths
xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images"
path="Android/data/com.operator.u_learn/files/Pictures" />
</paths>
And here's the error i get
E/AndroidRuntime: FATAL EXCEPTION: main
Process:
com.android.gallery3d, PID: 18974
java.lang.SecurityException: Permission Denial: opening
provider android.support.v4.content.FileProvider from
ProcessRecord{3b596555 18974:com.android.gallery3d/u0a42}
(pid=18974, uid=10042) that is not exported from uid 10221
at
android.os.Parcel.readException(Parcel.java:1540)
at
android.os.Parcel.readException(Parcel.java:1493)
Upvotes: 1
Views: 1552
Reputation: 25080
In my experience, your Camera module is locked by previous Activity. You can check it by running preview another camera app and switching immediately to your camera app preview screen.
Possibly, highest resolution could make it occur more frequently as it requires more time to be released.
As you know, there are several different implementations in Android devices among manufacturers+hardware+camera driver+OS+manufacturer's default Camera app combination. Some allow camera api to be accessed by releasing previous accessed app automatically (LG Nexus 5), while some others are crashed (LG G2 phone).
To fix this problem, if my diagnostics are correct, I recommend you to add sleep counter for about Thread.sleep(500);
before launching it.
Or, try-catch Camera.open() method. It could give RuntimeException
if it is locked by other processor. But in my experience, Camera API is very unreliable so make us wrap try-catch codes at almost every line of api commands.
Though this answer cannot be a solution for Gallery crash issue, but Camera could be.
Upvotes: 1