Android M Kamera Intent + Berechtigungsfehler?

Ich versuche, meine App bereit für die neuen Android M Berechtigungen Änderungen und fand einige seltsame Verhalten. Meine App nutzt den Kamera-Intent-Mechanismus, damit der Benutzer ein Bild von der Kamera bekommen kann. Aber in einer anderen Aktivität muss die Kamera selbst mit Kamera-Berechtigung nutzen (wegen einer Bibliotheksabhängigkeit card.io, die dies erfordert).

Allerdings mit M in der Aktivität, die nur eine Kamera Absicht braucht, wenn ich versuche, die Kamera-Absicht zu starten, sehe ich den folgenden Absturz (dies geschieht nicht, wenn ich die Kamera-Erlaubnis aus dem Manifest entfernen)

  • Wie man android progress bar in der Mitte des Bildschirms setzt
  • JNI-Fehler: Lokaler Referenztabellenüberlauf 512 Einträge
  • Android: Ausrichtung von vier Quadraten
  • DexIndexOverflowException nur beim Ausführen von Tests
  • Android Native - Wann soll man 64-Bit NDK verwenden?
  • Android Studio kompilieren Fehler: Enum Konstante INSTANT_RUN_REPLACEMENT existiert nicht in der Klasse
  • > 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)} from 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) } from null (pid=-1, uid=10098) with revoked > permission android.permission.CAMERA 09-25 21:57:55.263 32657-32657/? > E/ResolverActivity: Unable to launch as 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) } from null (pid=-1, uid=10098) with revoked > permission android.permission.CAMERA 09-25 21:57:55.263 32657-32657/? > E/ResolverActivity: at > android.os.Parcel.readException(Parcel.java:1599) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.os.Parcel.readException(Parcel.java:1552) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.app.ActivityManagerProxy.startActivityAsCaller(ActivityManagerNative.java:2730) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > android.app.Instrumentation.execStartActivityAsCaller(Instrumentation.java:1725) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > android.app.Activity.startActivityAsCaller(Activity.java:4047) 09-25 > 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ResolverActivity$DisplayResolveInfo.startAsCaller(ResolverActivity.java:983) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ResolverActivity.safelyStartActivity(ResolverActivity.java:772) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ResolverActivity.onTargetSelected(ResolverActivity.java:754) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ChooserActivity.onTargetSelected(ChooserActivity.java:305) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ResolverActivity.startSelected(ResolverActivity.java:603) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ChooserActivity.startSelected(ChooserActivity.java:310) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > com.android.internal.app.ChooserActivity$ChooserRowAdapter$2.onClick(ChooserActivity.java:990) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > android.view.View.performClick(View.java:5198) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.view.View$PerformClick.run(View.java:21147) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.os.Handler.handleCallback(Handler.java:739) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.os.Handler.dispatchMessage(Handler.java:95) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.os.Looper.loop(Looper.java:148) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > android.app.ActivityThread.main(ActivityThread.java:5417) 09-25 > 21:57:55.263 32657-32657/? E/ResolverActivity: at > java.lang.reflect.Method.invoke(Native Method) 09-25 21:57:55.263 > 32657-32657/? E/ResolverActivity: at > com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) > 09-25 21:57:55.263 32657-32657/? E/ResolverActivity: at > 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 

    Ist das ein bekanntes Problem mit Android M? Und noch wichtiger, wie gehe ich das um?

    In dem Manifest habe ich folgendes,

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

    Und das ist der Code, den ich benutze, um den Benutzer mit der Kamera auf ein Bild zu klicken und / oder ein Bild auszuwählen

     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 the camera options. chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{})); return chooserIntent; } 

    Ich rufe die openImageIntent() auf eine Schaltfläche klicken in meiner Aktivität. Wenn ich nicht die CAMERA-Erlaubnis in meiner App habe, funktioniert es gut, aber mit diesem hinzugefügt bekomme ich die Ausnahme, die oben geschrieben wurde.

      @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(); } } 

  • Einstellung Anwendungsthema textColor to white verursacht Kontext Menüpunkt Text weiß (unsichtbar)
  • Android Material Design Profil Seite
  • Gibt es ein Repo, wo man Android virtuelle Geräte herunterladen kann?
  • Welche Grenzen gibt es auf die Anzahl der Android-Ressourcen?
  • Transparent AlertDialog hat schwarzen Hintergrund
  • Emulator auf Android Studio startet nicht nach der Aktualisierung von SDK-Tools auf 25.3.1
  • 8 Solutions collect form web for “Android M Kamera Intent + Berechtigungsfehler?”

    Ich hatte das gleiche Problem und finde dieses doc von google: https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE

    "Hinweis: Wenn Sie App-Ziele M und höher und erklärt, wie mit der CAMERA-Berechtigung, die nicht gewährt wird, dann versuchen, diese Aktion zu verwenden, wird eine SecurityException führen."

    Das ist wirklich komisch. Machen Sie überhaupt keinen Sinn. Die App erklärt Kamera-Berechtigung mit Absicht mit Aktion IMAGE_CAPTURE nur in SecurityException laufen. Aber wenn Ihre App nicht erklärt, Kamera-Erlaubnis mit Absicht mit Aktion IMAGE_CAPTURE kann Kamera-App ohne Problem starten.

    Der Workaround wäre Scheck ist die App hat Kamera Erlaubnis in das Manifest enthalten, wenn es ist, fordern Kamera Erlaubnis vor dem Start der Absicht.

    Hier ist der Weg zu überprüfen, ob die Erlaubnis in das Manifest aufgenommen ist, ist egal, dass die Erlaubnis erteilt wird oder nicht.

     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; } 

    Wenn Sie das Android M-Berechtigungsmodell verwenden, müssen Sie zuerst überprüfen, ob die App diese Berechtigung zur Laufzeit hat und muss den Benutzer für diese Berechtigung zur Laufzeit auffordern. Die Berechtigung, die Sie auf Ihrem Manifest definieren, wird bei der Installationszeit nicht automatisch erteilt.

     if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_REQUEST_CODE); } 

    MY_REQUEST_CODE ist eine statische Konstante, die Sie definieren können, die wieder für den Rückruf des RequestPermission-Dialogs verwendet wird.

    Sie benötigen einen Rückruf für das Dialogergebnis:

     @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == MY_REQUEST_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Now user should be able to use camera } else { // Your app will not have this permission. Turn off all functions // that require this permission or it will force close like your // original question } } } 

    bearbeiten

    Lesen aus der Stack-Trace, sieht es aus wie Google-Kamera hat nicht die CAMERA-Berechtigung aktiviert. Das könnte tatsächlich wie eine Rückwärtskompatibilität dahin aussehen.

    Nehmen wir an, dass Google-Kamera (oder was auch immer andere Anwendung, die Ihre ACTION-Absicht behandelt) eine bestimmte Erlaubnis erfordert.

    Wenn deine App nicht über die CAMERA-Berechtigung verfügt, läßt sie einfach die Google-Kamera mit dem alten Berechtigungsmodell machen.

    Allerdings, mit der CAMERA-Berechtigung in Ihrem Manifest erklärt, es ist auch die Durchsetzung der CAMERA-Erlaubnis in Google Camera (die nicht über Android M Berechtigungen Modell), um die Android M Berechtigungen Modell (ich denke)

    Also, das heißt, mit der oben genannten Methode, müssen Sie Ihre App-Berechtigung zur Laufzeit zur Verfügung stellen, was bedeutet, dass seine untergeordnete Aufgabe (in diesem Fall Google Camera) nun auch diese Berechtigung haben wird.

    Soweit deine Frage "Ist das ein bekanntes Problem in M?" Ein Google Dev antwortete auf jemanden, der dieses Problem als Bug meldete.

    Siehe hier: https://code.google.com/p/android/issues/detail?id=188073&q=label%3APriority-Medium&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&start=100

    Hier ist das Wort aus dem Google-Kerl: "Dies ist beabsichtigt Verhalten zu vermeiden Benutzer Frustration, wo sie widerrufen die Kamera Erlaubnis von einer App und die App noch in der Lage, Fotos über die Absicht zu nehmen. Die Benutzer sind sich nicht bewusst, dass das Foto, das nach dem Erlaubnisaufruf genommen wurde, über einen anderen Mechanismus erfolgt und die Richtigkeit des Berechtigungsmodells in Frage stellt. Dies gilt für MediaStore.ACTION_IMAGE_CAPTURE, MediaStore.ACTION_VIDEO_CAPTURE und Intent.ACTION_CALL die Dokumente, für die das Verhalten für Apps, die auf "

    Da Google es nicht kennt, die Mechanik der Verwendung der Kamera von deinem Benutzer zu abstrahieren, kannst du auch die erste Anforderung für die Kamerahlaubnis strategisch auslösen und auf die Funktionalität der Aktivität verweisen, die die Kamera als Ihr Argument für die Anfrage verwendet. Wenn Sie es Ihrer App erlauben, diese Berechtigungsanforderung zuerst zu machen, wenn der Benutzer einfach versucht, ein Bild zu machen, kann der Benutzer denken, dass Ihre App sich seltsam verhält, da ein Foto nicht in der Regel die Erlaubnis erteilt hat.

    Wenn Sie Google M verwenden, gehen Sie zu Einstellungen -> Apps -> Ihre App -> und geben die entsprechenden Berechtigungen an.

    Ich habe mich auf dieses Problem gesetzt und ich habe bereits JTYs Antwort benutzt. Das Problem ist, dass irgendwann der Request-Berechtigungsdialog auf "Never ask again" überprüft wurde. Ich entwickle auf SDK 24.

    Mein vollständiger Code, um Berechtigungen zu behandeln (die Kamera in meinem Fall) war die folgende:

     public void checksCameraPermission(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Log.d("MyApp", "SDK >= 23"); if (this.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { Log.d("MyApp", "Request permission"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_REQUEST_CODE); if (! shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { showMessageOKCancel("You need to allow camera usage", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(FotoPerfil.this, new String[] {Manifest.permission.CAMERA}, MY_REQUEST_CODE); } }); } } else { Log.d("MyApp", "Permission granted: taking pic"); takePicture(); } } else { Log.d("MyApp", "Android < 6.0"); } } 

    dann

     private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(this) .setMessage(message) .setPositiveButton("OK", okListener) .setNegativeButton("Cancel", null) .create() .show(); } 

    und dann

     @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_REQUEST_CODE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { criarFoto(); } else { Toast.makeText(this, "You did not allow camera usage :(", Toast.LENGTH_SHORT).show(); noFotoTaken(); } return; } } } 

    Das beabsichtigte Verhalten ist, dass im Falle der Benutzer aus Versehen überprüft "nie wieder fragen" Ihre App wird stecken (die Anfrage Dialog wird nicht angezeigt) und der Benutzer könnte sich frustriert fühlen. Auf diese Weise sagt ihm eine Nachricht, dass er diese Erlaubnis braucht.

    Ich entfernte:

     uses-permission android:name="android.permission.CAMERA" 

    Und nur verließ sich auf:

     uses-feature android:name="android.hardware.camera" android:required="true" 

    In der Manifestdatei.

    Diese Methode von mir überprüft nicht nur Kamera, sondern alle Berechtigungen, die von meiner App während des Startvorgangs benötigt werden … Ich habe das in meiner Helper.java Datei, auch beachten Sie, dass für den Dialog ich diese Bibliothek verwende: https: // github. Com / afollestad / material-dialogs

      ///check camera permission public static boolean hasPermissions(final Activity activity){ //add your permissions here String[] AppPermissions = { Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; //ungranted permissions ArrayList<String> ungrantedPerms = new ArrayList<String>(); //loop //lets set a boolean of hasUngrantedPerm to false Boolean needsPermRequest = false; //permissionGranted int permGranted = PackageManager.PERMISSION_GRANTED; //permission required content String permRequestStr = activity.getString(R.string.the_following_perm_required); //loop for(String permission : AppPermissions){ //check if perm is granted int checkPerm = ContextCompat.checkSelfPermission(activity,permission); //if the permission is not granted if(ContextCompat.checkSelfPermission(activity,permission) != permGranted){ needsPermRequest = true; //add the permission to the ungranted permission list ungrantedPerms.add(permission); //permssion name String[] splitPerm = permission.split(Pattern.quote(".")); String permName = splitPerm[splitPerm.length-1].concat("\n"); permRequestStr = permRequestStr.concat(permName); }//end if }//end loop //if all permission is granted end exec //then continue code exec if(!needsPermRequest) { return true; }//end if //convert array list to array string final String[] ungrantedPermsArray = ungrantedPerms.toArray(new String[ungrantedPerms.size()]); //show alert Dialog requesting permission new MaterialDialog.Builder(activity) .title(R.string.permission_required) .content(permRequestStr) .positiveText(R.string.enable) .negativeText(R.string.cancel) .onPositive(new MaterialDialog.SingleButtonCallback(){ @Override public void onClick(@NonNull MaterialDialog dialog,@NonNull DialogAction which){ //request the permission now ActivityCompat.requestPermissions(activity,ungrantedPermsArray,0); } }) .show(); //return false so that code exec in that script will not be allowed //to continue return false; }//end checkPermissions 

    So werden Sie Ihre Erlaubnis hinzufügen oder entfernen. Listen hier:

     //add your permissions here String[] AppPermissions = { Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; 

    In meiner Aktivität Datei Ich überprüfe die Erlaubnis wie diese, die Helper-Klasse ist, wo ich die Methode hasPermissions gehalten habe

      if(Helper.hasPermissions(this) == false){ return; }//end if 

    Bedeutet, dass wir die Ausführung nicht fortsetzen müssen, wenn keine Erlaubnis erteilt wird. Wieder müssen wir die Erlaubnisanforderung anhören, nachdem sie fertig ist, um dies zu tun, fügen Sie den Code unten zu Ihrer Aktivitätsdatei hinzu (optional)

     //Listen to Permission request completion //put in your activity file @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { int permGranted = PackageManager.PERMISSION_GRANTED; Boolean permissionRequired = false; for(int perm : grantResults){ if(perm != permGranted){ permissionRequired = true; } } //if permission is still required if(permissionRequired){ //recheck and enforce permission again Helper.hasPermissions(this); }//end if }//end method 

    Es ist ein bisschen spät. Aber ich möchte noch eine Sache hinzufügen. Wann immer Sie Methoden anrufen, die Kamera-Funktionalität verwenden, verwenden Sie es in try catch Block. Wenn nicht App wird auf einigen Geräten wie Moto G4 plus oder ein plus abstürzen.

     private static final int CAMERA_REQUEST_CODE = 10; //TODO add camera opening functionality here. try { captureImage(); Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(intent,CAMERA_REQUEST_CODE); } catch (Exception e){ e.printStackTrace(); } private void captureImage(){ if( ContextCompat.checkSelfPermission(getContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{android.Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE); } else { // Open your camera here. } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CAMERA_REQUEST_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Now user should be able to use camera } else { // Your app will not have this permission. Turn off all functions // that require this permission or it will force close like your // original question } } } 

    PS: Vergewissern Sie sich, dass Sie die überschriebene Methode nicht kopieren möchten.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.