Android M Camera Intent + Permission Bug

Android M Camera Intent + permission bug?

I had the same issue and find this doc from google:
https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE

"Note: if you app targets M and above and declares as using the CAMERA permission which is not granted, then atempting to use this action will result in a SecurityException."

This is really weird.
Don't make sense at all.
The app declares Camera permission using intent with action IMAGE_CAPTURE just run into SecurityException. But if your app doesn't declare Camera permission using intent with action IMAGE_CAPTURE can launch Camera app without issue.

The workaround would be check is the app has camera permission included in the manifest, if it's , request camera permission before launching intent.

Here is the way to check if the permission is included in the manifest, doesn't matter the permission is granted or not.

public boolean hasPermissionInManifest(Context context, String permissionName) {
final String packageName = context.getPackageName();
try {
final PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
final String[] declaredPermisisons = packageInfo.requestedPermissions;
if (declaredPermisisons != null && declaredPermisisons.length > 0) {
for (String p : declaredPermisisons) {
if (p.equals(permissionName)) {
return true;
}
}
}
} catch (NameNotFoundException e) {

}
return false;
}

Android: Permission Error on Capture using Camera

If camera n external storage both are required for your app you should || them in if condition.

 if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
} else {
Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
}

Camera intent permission, android, Why this do not work?

So, i think problem is in android permission.

CODE works well under or equal android 5.xx

But do not works on over or equal android 6.xx

For this you have to add Runtime Permission for Android 6.0 and up.

Example.

final private int REQUEST_CODE_ASK_PERMISSIONS_CAMERA = 100;
final private int REQUEST_CODE_ASK_PERMISSIONS_EXTERNAL_STORAGE = 200;

// For Check Camera Permission
if (Build.VERSION.SDK_INT >= 23) {
int hasPermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
if (hasPermission != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
// Display UI and wait for user interaction
getErrorDialog("You need to allow Camera permission." +
"\nIf you disable this permission, You will not able to add attachment.", getActivity(), true).show();
} else {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_ASK_PERMISSIONS_CAMERA);
}
return;
}
}

// For Check Read External Permission.
if (Build.VERSION.SDK_INT >= 23) {
int hasPermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
if (hasPermission != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Display UI and wait for user interaction
getErrorDialog("You need to allow Read External Storage permission." +
"\nIf you disable this permission, You will not able to add attachment.", getActivity(), false).show();
} else {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSIONS_EXTERNAL_STORAGE);
}
return;
}
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS_CAMERA:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
Toast.makeText(getActivity(), "Permission Grant", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + ".jpg";
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), imageFileName);
uri = Uri.fromFile(imageStorageDir);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 1);

} else {
// Permission Denied
Toast.makeText(getActivity(), "Required permission is disable.", Toast.LENGTH_SHORT).show();
}
break;

case REQUEST_CODE_ASK_PERMISSIONS_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
Toast.makeText(getActivity(), "Permission Grant", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, 2);

} else {
// Permission Denied
Toast.makeText(getActivity(), "Required permission is disable.", Toast.LENGTH_SHORT).show();
}
break;

default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

public AlertDialog.Builder getErrorDialog(String message, Context context, final boolean isFromCamera) {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle(getString(R.string.app_name)).setMessage(message);
alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();
if (Build.VERSION.SDK_INT >= 23) {
if(isFromCamera){
requestPermissions(new String[]{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS_CAMERA);
}else {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS_EXTERNAL_STORAGE);
}
}

}
});
return alertDialog;
}

Camera permissions are not requested but are still working

The reason this works is that your app is not getting access to any of:

  • The camera itself
  • The user's internal/external storage
  • The user's existing photos

All you're getting is the opportunity to ask the user to take a photo and return that photo to you. Because the user needs to affirmatively consent as part of the process, no permission is required.

This model also has the benefit of allowing apps to capture photos even if the user would not entrust them with camera or storage permissions. They can rest assured that the app only got access to the single photo that the user took. The same principle applies when asking the user to select a photo as well.

Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA

Remove this permission

  <uses-permission android:name="android.permission.CAMERA"/>

I faced this error executing my app in android 7. After tests I noticed user permission wasn't in project A but it was in project B, that I only tested in android 5 devices. So I remove that permission in project B in order to run it on other device that targets android 7 and it finally could open.

In adittion I added the fileprovider code that Android suggests here https://developer.android.com/training/camera/photobasics.html
Hope this helps.

Camera Intent not working with multiple camera apps

The problem was that in manifest I have option:
android:launchMode="singleInstance" for my activity.

<activity
android:name="MyActivity"
android:launchMode="singleInstance"
>

For solving above issue you should remove singleInstance option from manifest file (or replace it within singleTask option).
This is resolve the issue and onActivityResult is properly working.

revoked permission android.permission.CAMERA

Here's how I solved this problem.

Contrary to what most answers say, REMOVE this from your Manifest file.

 <uses-permission android:name="android.permission.CAMERA"/>

Why?

Starting Android M (API 23), if your app has CAMERA permission declared in the manifest, then, it needs that CAMERA permission to be GRANTED in order to access ACTION_IMAGE_CAPTURE
etc... too (which normally do not require the CAMERA permission on their own). If not, then it automatically raises a SecurityException.

╔═════════════════════════════════════════════════╦════════════════════╗
║ Usage ║ Permissions needed ║
╠═════════════════════════════════════════════════╬════════════════════╣
║ ACTION_IMAGE_CAPTURE ║ none ║
║ ACTION_VIDEO_CAPTURE ║ none ║
║ INTENT_ACTION_STILL_IMAGE_CAMERA ║ none ║
║ android.hardware.camera2 ║ CAMERA ║
║ android.hardware.camera2 + ACTION_IMAGE_CAPTURE ║ CAMERA ║
║ android.hardware.camera2 + ACTION_VIDEO_CAPTURE ║ CAMERA ║
║ ... ║ ... ║
╚═════════════════════════════════════════════════╩════════════════════╝

Above table is only for API 23+

tl;dr What to do?

Option 1- If you only use ACTION_IMAGE_CAPTURE etc...

Remove the CAMERA permission from manifest and you would be fine

Option 2- If you use other CAMERA functions:

Check for CAMERA permission at runtime and only start the intent when the permission is available

Android M - camera permissions issue

First, you are not calling your Camerapermission() method, at least in terms of the code shown in your question.

Second, you are allowing the user to do something strange with a RadioButton that triggers a call to openCamera(), without checking to see that you have permission to use the camera. For example, you could use checkSelfPermission() to see if you have permission, and only enable that RadioButton if you do.

You may wish to read more about the runtime permission system.



Related Topics



Leave a reply



Submit