2015-10-10 8 views
18

Tak, mam poniżej kod, który otworzyć aparat, uchwycić obraz i zapisać go na karcie SD.android: kamera nie otwiera się w 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() + ""); 
      } 
     } 
    } 
} 

Wszystko działa idealnie zgodnie z oczekiwaniami poniżej systemu Android 6.0. Ale nie działa na Androidzie 6.0 Marshmallow. Właściwie to nawet nie otwiera aparatu :(

Nie wiem, czy muszę zrobić coś specjalnego na piankę, nie dostaję żadnego błędu, że mogę to opublikować tutaj. mi się

Dzięki

Odpowiedz

34

Więc, Wykonałem moje zadanie jak poniżej:

Dla sprawdzenia uprawnień utworzyłem osobną klasę jak poniżej:

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

Następnie, dla uzyskania

... 
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

Miałem aplikację działającą na urządzeniu z Lollipop, a następnie nie działa na dwóch urządzeniach z Marshmallow. Podczas uruchamiania pojawiła się wiadomość - Wygląda na to, że Twoje urządzenie nie obsługuje kamery (lub jest ona zablokowana). Śledziłem błąd przez Camera.open() aż do Camera.cameraInitVersion(), gdzie powracał błąd braku możliwości dostępu do usługi Camera. Nie zdawałem sobie sprawy, że potrzebne są zmiany w kodowaniu, na razie teraz model zgody na Marshmallow. – medloh

+0

@ChintanSoni czy to tylko jedna prośba w aplikacji? – RushDroid

+1

co to jest plik multimedialny? czy to jest plik? dzięki za przykład! –

7

Cytowanie developers.android.com..

Począwszy od Androida 6.0 (API poziom 23), użytkownicy przyznają uprawnienia do aplikacji podczas gdy aplikacja jest uruchomiona, nie przy instalacji aplikacji Podejście to usprawnia o tysiąc dziewięćset osiemdziesiąt stopni Proces instalacji aplikacji, ponieważ użytkownik nie musi udzielać uprawnień podczas instalowania lub aktualizowania aplikacji. To także daje użytkownikowi większą kontrolę nad funkcjonalnością aplikacji; na przykład: użytkownik może zdecydować o przyznaniu dostępu do kamery aparatem, ale nie do lokalizacji urządzenia w lokalizacji . Użytkownik może odwołać uprawnienia w dowolnym momencie na , przechodząc do ekranu Ustawienia aplikacji.

uprawnienia systemowe są podzielone na dwie kategorie, normalny i niebezpieczne:

  • Normalne uprawnienia bezpośrednio nie ryzykują prywatność użytkownika. Jeśli Twoja aplikacja wyświetla w manifeście normalne uprawnienia, system automatycznie przyznaje uprawnienie .

  • Niebezpieczne uprawnienia mogą nadać aplikacji dostęp do poufnych danych użytkownika. Jeśli w swoim manifeście aplikacja wyświetla normalne uprawnienie w wersji , automatycznie przyznaje uprawnienie . Jeśli podasz niebezpieczne pozwolenie, użytkownik musi jednoznacznie zatwierdzić swoją aplikację pod numerem .

WRITE_EXTERNAL_STORAGE znajduje się w kategorii niebezpiecznych, z tego powodu trzeba wystąpić o pozwolenie do użytkownika przed wywołaniem mediaStorageDir.mkdirs() lub File.createTempFile inaczej zaprogramować awarii z tego wyjątku:

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

.. Dziękuję za wskazanie tej cechy Marshmallow .. Nie wiem jak ja zapomniałem? W każdym razie .. Dzięki .. Próbuję dać pozwolenie środowiska wykonawczego i wkrótce zaktualizuję pytanie. –

+0

Stary, zbzikujesz, uratowałeś mi ogon. Dzięki wielkie. Jesteś dżentelmenem i łajdakiem.;) – LukeWaggoner

+0

Zgodnie z wytycznymi oznacza to również, że można uniknąć pytania o zbyt wiele uprawnień za pomocą intencji, aby wykorzystać inne aplikacje, takie jak kamera do wykonywania pracy. Oznacza to, że aplikacja do aparatu musiałaby mieć niezbędne uprawnienia do wykonania zdjęcia i powinna zwrócić wynik. Dobrze? Jeśli tak, to dlaczego jego aparat się nie otwiera? Pytam, ponieważ mam problem z moją aplikacją, w której kodem wyniku nie jest RESULT_OK. Myślę, że ma to związek z tą zmianą uprawnień. –