2015-10-10 59 views
18

因此,我有下面的代码打开相机,捕获图像并将其保存在SDCard上。android:相机不打开棉花糖

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

一切工作完美,预计低于Android 6.0。但它不适用于Android 6.0棉花糖。事实上,它甚至不打开相机:(

我不知道我是否必须做一些特别的棉花糖,我没有得到任何形式的错误,我可以在这里发布。我出去

感谢

回答

34

,我完成了我的任务,如下所示:

对于检查许可我创建了一个单独的类,如下所示:

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

然后,让

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

我曾经在有棒棒糖的设备上工作,然后在运行棉花糖的两台设备上失败。我在启动时收到一条消息 - 看起来您的设备不支持摄像头(或已锁定)。我通过Camera.open()追踪到Camera.cameraInitVersion()的错误,它返回了无法访问Camera服务的错误。目前尚未意识到对棉花糖现在的许可模式需要进行编码更改。 – medloh

+0

@ChintanSoni是它显示一个请求只有一次在应用程序? – RushDroid

+1

什么是mediaFile?它是一个文件?感谢这个例子! –

7

引用developers.android.com:。

中的Android 6.0开始(API等级23),用户权限授予 应用程序的应用程序运行时,而不是当他们安装的应用程序这 方法简化了e应用程序安装过程,因为用户在安装或更新应用程序时不需要授予权限 。它也 给用户更多的控制应用程序的功能;例如, 用户可以选择给相机应用程序访问相机,但不是 到设备位置。用户可以在任何 时间通过转到应用的设置屏幕来撤销权限。

系统权限分为两类,普通和 危险:

  • 普通权限不直接风险用户的隐私。如果您的 应用在其清单中列出了正常权限,系统将自动授予 权限。

  • 危险的权限可以让应用程序 访问用户的机密数据。如果您的应用在其清单中列出正常的 权限,系统将自动授予 权限。如果您列出危险权限,用户必须明确地批准您的应用程序 。

WRITE_EXTERNAL_STORAGE处于危险类别,为此你需要,否则你的程序与此异常崩溃,请求允许用户呼叫mediaStorageDir.mkdirs()File.createTempFile前:所以

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

谢谢。您指出棉花糖的这一特点。我不知道我怎么会忘记呢?无论如何..谢谢..我想给运行时权限,并会尽快更新问题。 –

+0

伙计,你吓坏了我的尾巴。非常感谢。你是一个绅士和流氓。;) – LukeWaggoner

+0

按照指导方针,它还表示您可以避免通过使用意图利用其他应用程序(如相机)执行此项工作来请​​求太多权限。这意味着相机应用程序需要拥有必要的权限才能拍摄照片并返回结果。对?如果是这样的话那为什么他的相机不能打开?我问,因为我的应用程序在结果代码不是RESULT_OK时遇到问题。我认为这与权限更改有关。 –