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
Post a Comment