2015-10-10 4 views
18

So habe ich unter Code, der Kamera öffnen, erfassen Sie das Bild und speichern Sie es auf SDCard.Android: Kamera öffnet nicht in Marshmallow

public void getPhotoFromCamera() { 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    File mediaStorageDir = new File(
      Environment.getExternalStorageDirectory() 
        + File.separator 
        + getString(R.string.directory_name_corp_chat) 
        + File.separator 
        + getString(R.string.directory_name_temp) 
    ); 

    if (!mediaStorageDir.exists()) { 
     mediaStorageDir.mkdirs(); 
    } 

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", 
      Locale.getDefault()).format(new Date()); 
    try { 
     mediaFile = File.createTempFile(
       "TEMP_FULL_IMG_" + timeStamp, 
       ".jpg", 
       mediaStorageDir 
     ); 
     takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile)); 
     startActivityForResult(takePictureIntent, PICK_FROM_CAMERA); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void performCrop(Uri picUri) { 
    try { 
     Intent cropIntent = new Intent("com.android.camera.action.CROP"); 
     cropIntent.setDataAndType(picUri, "image/*"); 
     cropIntent.putExtra("crop", "true"); 
     cropIntent.putExtra("aspectX", 1); 
     cropIntent.putExtra("aspectY", 1); 
     cropIntent.putExtra("outputX", 128); 
     cropIntent.putExtra("outputY", 128); 
     // retrieve data on return 
     cropIntent.putExtra("return-data", true); 

     File mediaStorageDir = new File(
       Environment.getExternalStorageDirectory() 
         + File.separator 
         + getString(R.string.directory_name_corp_chat) 
         + File.separator 
         + getString(R.string.directory_name_temp) 
     ); 

     if (!mediaStorageDir.exists()) { 
      mediaStorageDir.mkdirs(); 
     } 

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", 
       Locale.getDefault()).format(new Date()); 
     try { 
      croppedFile = File.createTempFile(
        "TEMP_CROPPED_IMG_" + timeStamp, 
        ".jpg", 
        mediaStorageDir 
      ); 
      cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(croppedFile)); 
      startActivityForResult(cropIntent, PIC_CROP); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    // respond to users whose devices do not support the crop action 
    catch (ActivityNotFoundException anfe) { 
     // display an error message 
     String errorMessage = "Whoops - your device doesn't support the crop action!"; 
     Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); 
     toast.show(); 
    } 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (requestCode == PICK_FROM_CAMERA) { 
     if (resultCode == RESULT_OK) { 
      performCrop(Uri.fromFile(mediaFile)); 
     } else { 
      Log.i("Camera", "result cancel. Hence, deleting file: " + mediaFile.getPath()); 
      Log.i("File deleted ", mediaFile.delete() + ""); 
     } 
    } 

    if (requestCode == PICK_FROM_GALLERY) { 
     if (resultCode == RESULT_OK) { 
      performCrop(data.getData()); 
     } else { 
      Log.i("Gallery", "result cancel"); 
     } 
    } 

    if (requestCode == PIC_CROP) { 
     if (resultCode == RESULT_OK) { 
      imageView.setImageBitmap(BitmapFactory.decodeFile(croppedFile.getAbsolutePath())); 
      if (mediaFile != null) { 
       Log.i("Camera", "result cancel. Hence, deleting file: " + mediaFile.getPath()); 
       Log.i("File deleted ", mediaFile.delete() + ""); 
      } 
     } else { 
      if (croppedFile != null) { 
       Log.i("Camera", "result cancel. Hence, deleting file: " + croppedFile.getPath()); 
       Log.i("File deleted ", croppedFile.delete() + ""); 
      } 
      if (mediaFile != null) { 
       Log.i("Camera", "result cancel. Hence, deleting file: " + mediaFile.getPath()); 
       Log.i("File deleted ", mediaFile.delete() + ""); 
      } 
     } 
    } 
} 

Alles funktioniert perfekt wie erwartet unter Android 6.0. Aber es funktioniert nicht auf Android 6.0 Marshmallow. Tatsächlich öffnet es nicht einmal die Kamera :(

Ich weiß nicht, ob ich etwas besonderes für Marshmallow machen muss. Ich bekomme auch keinen Fehler, dass ich es hier posten kann. Bitte helfen me out

Dank

Antwort

34

So, Ich erfüllte meine Aufgabe wie folgt:

Zum Überprüfen der Berechtigung habe ich eine separate Klasse wie folgt erstellt:

public class MarshMallowPermission { 

    public static final int RECORD_PERMISSION_REQUEST_CODE = 1; 
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2; 
    public static final int CAMERA_PERMISSION_REQUEST_CODE = 3; 
    Activity activity; 

    public MarshMallowPermission(Activity activity) { 
     this.activity = activity; 
    } 

    public boolean checkPermissionForRecord(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public boolean checkPermissionForExternalStorage(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public boolean checkPermissionForCamera(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public void requestPermissionForRecord(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.RECORD_AUDIO)){ 
      Toast.makeText(activity, "Microphone permission needed for recording. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.RECORD_AUDIO},RECORD_PERMISSION_REQUEST_CODE); 
     } 
    } 

    public void requestPermissionForExternalStorage(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){ 
      Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); 
     } 
    } 

    public void requestPermissionForCamera(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){ 
      Toast.makeText(activity, "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE); 
     } 
    } 
} 

Dann wird für immer

... 
MarshMallowPermission marshMallowPermission = new MarshMallowPermission(this); 
... 

public void getPhotoFromCamera() { 

    if (!marshMallowPermission.checkPermissionForCamera()) { 
     marshMallowPermission.requestPermissionForCamera(); 
    } else { 
     if (!marshMallowPermission.checkPermissionForExternalStorage()) { 
      marshMallowPermission.requestPermissionForExternalStorage(); 
     } else { 
      Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      File mediaStorageDir = new File(
        Environment.getExternalStorageDirectory() 
          + File.separator 
          + getString(R.string.directory_name_corp_chat) 
          + File.separator 
          + getString(R.string.directory_name_images) 
      ); 

      if (!mediaStorageDir.exists()) { 
       mediaStorageDir.mkdirs(); 
      } 

      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", 
        Locale.getDefault()).format(new Date()); 
      try { 
       mediaFile = File.createTempFile(
         "IMG_" + timeStamp, /* prefix */ 
         ".jpg",   /* suffix */ 
         mediaStorageDir  /* directory */ 
       ); 
       takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile)); 
       startActivityForResult(takePictureIntent, PICK_FROM_CAMERA); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

Ich hatte App auf einem Gerät mit Lollipop, dann auf zwei Geräten mit Marshmallow fehlgeschlagen. Ich habe beim Start eine Meldung erhalten - Es scheint, dass Ihr Gerät die Kamera nicht unterstützt (oder es ist gesperrt). Ich verfolgte den Fehler durch Camera.open() den ganzen Weg zu Camera.cameraInitVersion(), wo es Fehler zurückgab, nicht auf Camera-Dienst zugreifen zu können. Habe nicht bemerkt, dass Codierungsänderungen für das Erlaubnismodell auf Marshmallow notwendig waren. – medloh

+0

@ChintanSoni ist es Zeigen Sie eine Anfrage Nur einmal in der App? – RushDroid

+1

Was ist MediaFile? Ist es eine Datei? Danke für das Beispiel! –

7

developers.android.com Zitiert:..

Ab Android 6.0 (API-Ebene 23), Benutzer Berechtigungen erteilen Anwendungen, während die App ausgeführt wird, nicht, wenn sie die App installieren Diese Annäherung rationalisiert th e App-Installationsprozess, da der Benutzer keine Berechtigungen erteilen muss, wenn er die App installiert oder aktualisiert. Es gibt auch dem Benutzer mehr Kontrolle über die Funktionalität der App; Zum Beispiel könnte ein Benutzer wählen, um einer Kamera-App Zugriff auf die Kamera zu geben, aber nicht zum Gerätestandort. Der Benutzer kann die Berechtigungen unter einer beliebigen Zeit widerrufen, indem er zum Bildschirm Einstellungen der App geht.

Berechtigungen sind in zwei Kategorien unterteilt, normal und gefährlich:

  • Normale Berechtigungen nicht direkt die Privatsphäre des Nutzers riskieren. Wenn Ihre App in ihrem Manifest eine normale Berechtigung auflistet, erteilt das System automatisch die Berechtigung .

  • Gefährliche Berechtigungen können der App Zugriff auf die vertraulichen Daten des Benutzers geben. Wenn Ihre App in ihrem Manifest eine normale -Berechtigung auflistet, erteilt das System automatisch die Berechtigung . Wenn Sie eine gefährliche Berechtigung auflisten, muss der Nutzer der App explizit die Freigabe " " erteilen.

WRITE_EXTERNAL_STORAGE ist in der gefährlichen Kategorie, aus diesem Grunde Sie mediaStorageDir.mkdirs() oder File.createTempFile sonst die Erlaubnis für den Benutzer vor Aufruf beantragen müssen Sie Absturz mit dieser Ausnahme programmieren:

W/System.err: java.io.IOException: open failed: EACCES (Permission denied) 
W/System.err:  at java.io.File.createNewFile(File.java:939) 
W/System.err:  at java.io.File.createTempFile(File.java:1004) 
W/System.err:  at com.example.MainActivity.getPhotoFromCamera(MainActivity.java:98) 
W/System.err:  at com.example.MainActivity.onCreate(MainActivity.java:48) 
W/System.err:  at android.app.Activity.performCreate(Activity.java:6237) 
W/System.err:  at android.app.Instrumentation.callActivityOnCreate(Instrumentation. 
W/System.err:  at android.app.ActivityThread.performLaunchActivity(ActivityThread. 
W/System.err:  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476 
W/System.err:  at android.app.ActivityThread.-wrap11(ActivityThread.java) 
W/System.err:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:102) 
W/System.err:  at android.os.Looper.loop(Looper.java:148) 
W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:5417) 
W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit. 
W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission 
W/System.err:  at libcore.io.Posix.open(Native Method) 
W/System.err:  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 
W/System.err:  at java.io.File.createNewFile(File.java:932) 
W/System.err: ... 15 more 
+0

Danke .. Für diese Funktion von Eibisch Hinweis auf .. Ich weiß nicht, wie habe ich es vergessen? Wie auch immer .. Danke .. Ich versuche, die Runtime-Erlaubnis zu geben und werde die Frage bald aktualisieren. –

+0

Alter, du verdammtes gerettet mein Schwanz. Vielen Dank. Du bist ein Gentleman und ein Schuft.;) – LukeWaggoner

+0

Laut den Richtlinien können Sie auch vermeiden, zu viele Berechtigungen zu verlangen, indem Sie Absichten verwenden, um andere Apps wie die Kamera für die Arbeit zu nutzen. Dies bedeutet, dass die Kamera-App über die erforderlichen Berechtigungen zur Aufnahme des Bildes verfügen und ein Ergebnis zurückgeben muss. Recht? Wenn das der Fall ist, warum öffnet dann seine Kamera nicht? Ich frage, weil ich ein Problem mit meiner App habe, bei dem der Ergebniscode nicht RESULT_OK lautet. Ich denke, es hat mit dieser Änderung der Berechtigungen zu tun. –