Android内部缓存目录中的“java.io.FileNotFoundException:权限被拒绝”

时间:2015-07-21 10:42:45

标签: android android-intent android-camera

我正在尝试拍照并将其保存到应用程序的内部缓存中,因为它一上传就会被删除。我使用以下代码来创建文件:

public static File createInternalCacheImageFile(Context context, String imageFileName) throws IOException {
        return File.createTempFile(
                imageFileName,
                context.getString(R.string.image_extension),
                context.getCacheDir()
        );
    }

使用具有root权限的文件管理器进行检查表明该文件已正确创建。然后我使用以下代码启动相机意图,通常会将图像保存到我创建的文件中:

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
activity.startActivityForResult(takePictureIntent, REQUEST_CODE_IMAGE_CAPTURE);

显示相机活动,在接受图片后,活动结果为0.查看logcat时会显示以下内容:

07-21 13:19:51.093  12889-12889/? E/CAM_StateSavePic﹕ exception while saving result to URI: Optional.of(file:///data/data/org.serengetitracker.androidapp/cache/image_random_205854910-2018234447.jpg)
    java.io.FileNotFoundException: Permission denied
            at android.os.Parcel.openFileDescriptor(Native Method)
            at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:253)
            at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:199)
            at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:916)
            at android.content.ContentResolver.openOutputStream(ContentResolver.java:686)
            at android.content.ContentResolver.openOutputStream(ContentResolver.java:662)
            at com.android.camera.captureintent.state.StateSavingPicture.onEnter(StateSavingPicture.java:84)
            at com.android.camera.captureintent.stateful.StateMachineImpl.jumpToState(StateMachineImpl.java:62)
            at com.android.camera.captureintent.stateful.StateMachineImpl.processEvent(StateMachineImpl.java:110)
            at com.android.camera.captureintent.state.StateOpeningCamera$9.onClick(StateOpeningCamera.java:307)
            at android.view.View.performClick(View.java:4780)
            at android.view.View$PerformClick.run(View.java:19866)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

为什么我不允许将图像写入应用程序的内部缓存目录?

注意:我的应用程序中有android.permission.WRITE_EXTERNAL_STORAGE权限,但这并不重要,因为我没有处理外部存储。

3 个答案:

答案 0 :(得分:5)

相机活动在另一个应用中运行,该应用无法访问您应用的内部缓存目录。您必须使用外部目录或让相机应用程序选择目录本身 - 然后查询该路径(另一个主题)以便能够将其复制到缓存目录。

答案 1 :(得分:1)

来自以下链接http://developer.android.com/reference/android/content/Context.html#getCacheDir() getCacheDir()

edx

您的应用程序可以完全访问此路径,但是您在这里通过意图传递到缓存目录中的URI到Camera应用程序,它正在尝试访问应用程序的cacheDir以存储它已捕获的图像,但它无法访问它。

一种解决方案是使用外部目录上的文件夹。

答案 2 :(得分: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的引用并从那里检索它。