使用Android 6.0未经许可捕获图像

时间:2015-09-08 16:21:18

标签: android android-intent permissions camera android-6.0-marshmallow

我需要让用户使用Android 6.0拍照(来自图库或相机应用)。

因为我不需要控制相机,所以我想使用这里描述的意图:

  

但是,如果您不需要此类控件,则可以使用ACTION_IMAGE_CAPTURE意图来请求图像。当您启动意图时,系统会提示用户选择相机应用程序(如果还没有默认的相机应用程序),该应用程序将拍摄照片。相机应用程序将图片返回到您应用的onActivityResult()方法。

https://developer.android.com/preview/features/runtime-permissions.html

但是对于 ACTION_IMAGE_CAPTURE ,您需要将额外的“MediaStore.EXTRA_OUTPUT”填充为临时文件的Uri(没有此参数我将只有一个缩略图)。此临时文件必须位于外部存储中(可由相机应用程序访问)。您需要权限 WRITE_EXTERNAL_STORAGE 才能在外部存储上创建文件。

因此,如果没有权限android.permission.CAMERA android.permission.WRITE_EXTERNAL_STORAGE ,则无法通过原生对话框/应用捕获图像。这是对的吗?

由于

5 个答案:

答案 0 :(得分:10)

试试这个:

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getActivity().getApplicationContext().getExternalFilesDir(android.os.Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "yourPicture.jpg");
Uri uri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, url);

这使您可以访问"外部"在这种情况下,相机应用程序的存储可写,但文件只能从您的应用程序中看到。 要了解有关android中存储空间的更多信息,请参阅https://www.youtube.com/watch?v=C28pvd2plBA

希望它可以帮到你!

答案 1 :(得分:6)

如果您在android 4.4+上,可以将MediaStore.EXTRA_OUTPUT指定为特定于包的文件 目录

  

从Android 4.4开始,文件的所有者,组和模式   外部存储设备现在基于目录合成   结构体。这使应用程序可以管理其特定于程序包   目录在外部存储上,而不需要他们持有广泛的   WRITE_EXTERNAL_STORAGE权限。 例如,包含应用的应用   名称com.example.foo现在可以自由访问   Android / data / com.example.foo /在外部存储设备上没有   权限。这些合成权限由   将原始存储设备包装在FUSE守护程序中。

https://source.android.com/devices/storage/

答案 2 :(得分:2)

Since the camera app cannot access to the private dirs of your app, It's your applications duty to write the photo file to that directory. I'm not really sure about this but this works for me:

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
            .format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
}

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
    // Create the File where the photo should go
    File photoFile = null;
    try {
        photoFile = createImageFile();
        takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
    } catch (IOException ex) {
        // Error occurred while creating the File
        Log.e(TAG, "Unable to create Image File", ex);
    }

    // Continue only if the File was successfully created
    if (photoFile != null) {
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photoFile));
    } else {
        takePictureIntent = null;
    }
}

But you still need WRITE_EXTERNAL_STORAGE permission before KITKAT:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />

答案 3 :(得分:1)

如果没有CAMERAWRITE_EXTERNAL_STORAGE权限,则可以这样做。

您可以在应用的缓存目录中创建临时,并让其他应用访问它。这使得该文件可由相机应用程序写入:

File tempFile = File.createTempFile("photo", ".jpg", context.getCacheDir());
tempFile.setWritable(true, false);

现在您只需将此文件作为摄像头意图的输出文件传递:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));  // pass temp file
startActivityForResult(intent, REQUEST_CODE_CAMERA);

注意:文件Uri不会在Activity结果中传递给你,你必须保留对tempFile的引用并从那里检索它。

答案 4 :(得分:0)

我按照here的说明,将content://FileProvider.getUriForFile()一起使用,并按ACTION_IMAGE_CAPTURE的意图使用了外部相机应用程序,该应用程序不需要任何许可。

但是,似乎如果该应用的清单使用了android.permission.CAMERA权限,则打开外部相机应用确实需要相机许可。参见herehere