Android M Camera Intent + permission bug? -


i'm trying app ready new android m permissions changes , found weird behaviour. app uses camera intent mechanism allow user picture form camera. in activity needs make use of camera camera permission (because of library dependency card.io requires this).

however m in activity needs camera intent when try launch camera intent see following crash (this not happen if remove camera permission manifest),

> 09-25 21:57:55.260 774-8053/? i/activitymanager: start u0 > {act=android.media.action.image_capture flg=0x3000003 > pkg=com.google.android.googlecamera > cmp=com.google.android.googlecamera/com.android.camera.captureactivity > (has clip) (has extras)} uid 10098 on display 0 09-25 > 21:57:55.261 774-8053/? w/activitymanager: permission denial: starting > intent { act=android.media.action.image_capture flg=0x3000003 > pkg=com.google.android.googlecamera > cmp=com.google.android.googlecamera/com.android.camera.captureactivity > (has clip) (has extras) } null (pid=-1, uid=10098) revoked > permission android.permission.camera 09-25 21:57:55.263 32657-32657/? > e/resolveractivity: unable launch uid 10098 package > com.example.me.mycamerselectapp, while running in android:ui 09-25 > 21:57:55.263 32657-32657/? e/resolveractivity: > java.lang.securityexception: permission denial: starting intent { > act=android.media.action.image_capture flg=0x3000003 > pkg=com.google.android.googlecamera > cmp=com.google.android.googlecamera/com.android.camera.captureactivity > (has clip) (has extras) } null (pid=-1, uid=10098) revoked > permission android.permission.camera 09-25 21:57:55.263 32657-32657/? > e/resolveractivity:     @ > android.os.parcel.readexception(parcel.java:1599) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.os.parcel.readexception(parcel.java:1552) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.app.activitymanagerproxy.startactivityascaller(activitymanagernative.java:2730) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > android.app.instrumentation.execstartactivityascaller(instrumentation.java:1725) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > android.app.activity.startactivityascaller(activity.java:4047) 09-25 > 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.resolveractivity$displayresolveinfo.startascaller(resolveractivity.java:983) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.resolveractivity.safelystartactivity(resolveractivity.java:772) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.resolveractivity.ontargetselected(resolveractivity.java:754) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.chooseractivity.ontargetselected(chooseractivity.java:305) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.resolveractivity.startselected(resolveractivity.java:603) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.chooseractivity.startselected(chooseractivity.java:310) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.app.chooseractivity$chooserrowadapter$2.onclick(chooseractivity.java:990) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > android.view.view.performclick(view.java:5198) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.view.view$performclick.run(view.java:21147) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.os.handler.handlecallback(handler.java:739) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.os.handler.dispatchmessage(handler.java:95) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.os.looper.loop(looper.java:148) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > android.app.activitythread.main(activitythread.java:5417) 09-25 > 21:57:55.263 32657-32657/? e/resolveractivity:     @ > java.lang.reflect.method.invoke(native method) 09-25 21:57:55.263 > 32657-32657/? e/resolveractivity:     @ > com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:726) > 09-25 21:57:55.263 32657-32657/? e/resolveractivity:     @ > com.android.internal.os.zygoteinit.main(zygoteinit.java:616) 09-25 > 21:57:55.286 1159-1159/? i/keyboard.facilitator: onfinishinput() 09-25 > 21:57:55.297 32657-32676/? e/surface: getslotfrombufferlocked: unknown > buffer: 0xaec352e0 09-25 21:57:55.344 325-349/? v/renderscript: > 0xb3693000 launching thread(s), cpus 4 09-25 21:57:57.290 325-349/? > e/surface: getslotfrombufferlocked: unknown buffer: 0xb3f88240 

is known problem android m? , more importantly how work around this?

in manifest have following,

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

and code use let user click pic camera and/or select image

public static intent openimageintent(context context, uri cameraoutputfile) {      // camera.     final list<intent> cameraintents = new arraylist<intent>();     final intent captureintent = new intent(android.provider.mediastore.action_image_capture);     final packagemanager packagemanager = context.getpackagemanager();     final list<resolveinfo> listcam = packagemanager.queryintentactivities(captureintent, 0);     for(resolveinfo res : listcam) {         final string packagename = res.activityinfo.packagename;         final intent intent = new intent(captureintent);         intent.setcomponent(new componentname(res.activityinfo.packagename, res.activityinfo.name));         intent.setpackage(packagename);         intent.putextra(mediastore.extra_output, cameraoutputfile);         cameraintents.add(intent);     }      // filesystem.     final intent galleryintent = new intent();     galleryintent.settype("image/*");     galleryintent.setaction(intent.action_get_content);      // chooser of filesystem options.     final intent chooserintent = intent.createchooser(galleryintent, "take or select pic");      // add camera options.     chooserintent.putextra(intent.extra_initial_intents, cameraintents.toarray(new parcelable[]{}));     return chooserintent; } 

i call openimageintent() on button click in activity. when not have camera permission in app works fine, added exception posted above.

    @override     public void onclick(view v) {         intent piccaptureintenet = openimageintent(mainactivity.this, gettempimagefileuri(mainactivity.this));         try {             startactivityforresult(piccaptureintenet, 100);         } catch(exception e) {             toast.maketext(mainactivity.this, e.getmessage(), toast.length_short).show();         }     } 

i had same issue , find doc google: https://developer.android.com/reference/android/provider/mediastore.html#action_image_capture

"note: if app targets m , above , declares using camera permission not granted, atempting use action result in securityexception."

this weird. don't make sense @ all. app declares camera permission using intent action image_capture run securityexception. if app doesn't declare camera permission using intent action image_capture can launch camera app without issue.

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

here way check if permission included in manifest, doesn't matter permission 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) {             (string p : declaredpermisisons) {                 if (p.equals(permissionname)) {                     return true;                 }             }         }     } catch (namenotfoundexception e) {      }     return false; } 

Comments