【问题标题】:Image path from Android camera intent来自 Android 相机意图的图像路径
【发布时间】:2015-12-18 22:33:02
【问题描述】:

我正在尝试找出拍照后从相机获取文件路径的正确方法:

启动相机意图。因为我告诉相机写入内部存储,所以给它 uri 和读取权限:

File file = new File(context.getFilesDir(), "picture.jpg");
Uri uri = FileProvider.getUriForFile(getApplicationContext(), "my.app.package.fileprovider", file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, ACTION_IMAGE_CAPTURE_REQUEST_CODE);

监听相机意图结果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }
    switch (requestCode) {
    case ACTION_IMAGE_CAPTURE_REQUEST_CODE:
        // How do I get the local path to the file here?
        break;
    }
}

在相机意图返回时获取文件路径的最佳方法是什么。当然我可以在启动意图之前将文件路径保存到成员变量,但这似乎很糟糕,似乎我应该从 onActivityResult 获取路径。

我已经试过了(Get Image path from camera intent):

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();

String imagePath = cursor.getString(column_index_data);

唯一的区别是我正在使用 INTERNAL_CONTENT_URI 因为我试图在内部存储图片。如果我这样做,我会得到一个例外:

获取数据列时出错
java.lang.IllegalArgumentException:列“_data”不存在

我是不是搞错了。我想拍一张照片并将这张照片存储在内部存储器中。

编辑:

再想一想。我应该在内部存储照片吗?我是对的,不是因为新的 android M 权限。我已经必须向用户询问相机权限,如果我将图片存储到外部存储,我必须询问用户是否允许写入外部。最后,如果我将图像存储在外部,则设备上所有可以从外部存储读取的应用程序都可以读取它。这可能是我的应用程序的隐私问题。

【问题讨论】:

    标签: android android-camera uri android-camera-intent


    【解决方案1】:

    在相机意图返回时获取文件路径的最佳方法是什么

    您在EXTRA_OUTPUT 中指定了文件路径。相机要么把照片放在那里,要么没有。如果是这样,那么您已经知道文件路径:new File(context.getFilesDir(), "picture.jpg")。绝大多数时候都应该是这种情况。

    一些相机应用程序有问题,会忽略EXTRA_OUTPUT。在这些情况下:

    • 您可以查看相机应用程序是否在传递给onActivityResult()Intent 中返回了Uri,然后使用ContentResolveropenInputStream() 开始将图像复制到所需位置的过程, 或

    • 您可以查看"data" extra 是否存在,在这种情况下,您可以将其保存到所需位置的Bitmap 缩略图。

    在所有这些情况下,文件路径都是您指定的;这只是您是否需要额外的工作才能获得图像的问题。

    当然我可以在启动意图之前将文件路径保存到成员变量,但这似乎很糟糕

    我不知道你为什么会这么想。

    看来我应该从 onActivityResult 获取路径

    欢迎你相信任何你想要的。相机应用程序开发人员希望阅读the documentation for ACTION_IMAGE_CAPTURE。该文档没有说明如果您提供 EXTRA_OUTPUT,相机应用程序必须返回任何内容。因此,许多相机应用程序不会返回任何内容。


    更新基于编辑:

    我应该在内部存储图片吗?

    嗯,你已经是了。

    如果我将图片存储到外部存储,我必须请求用户允许写入外部

    这取决于你在哪里写作。 getExternalFilesDir()getExternalCacheDir() 和来自 Context 的亲属不需要 Android 4.4+ 的权限。您为外部存储位置(例如,getExternalStoragePublicDirectory())调用 Environment 的方法确实需要 WRITE_EXTERNAL_STORAGE,这是一个 dangerous 权限,需要在运行时请求。

    【讨论】:

    • '该文档没有说明如果您提供 EXTRA_OUTPUT,相机应用程序必须返回任何内容'。这意味着您必须始终存储您要求相机意图写入的文件的路径,因为这是在 onActivityResult 中获取该路径的唯一可靠方法,对吗?
    • @lostintranslation:正确。虽然通过“商店”,onSaveInstanceState() 就足够了。顺便说一句,我刚刚注意到您的编辑并更新了我的答案。
    • 啊废话! getExternalFilesDir() 是一个仅对我的应用程序可读的外部存储位置。允许我的应用程序私有的外部存储媒体。谢谢!
    • @lostintranslation:“getExternalFilesDir() 是一个外部存储位置,只有我的应用程序才能读取”——不。任何带有READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE 的应用程序都可以读取它。它对您的应用来说是独一无二的。它不是您的应用的私有
    • 是的,很抱歉赶上了文档。所以基本上,如果我希望我的媒体可以被我的应用程序读取,那么我的选择就是内部存储。由于我正在吃可能有限的存储空间。至少根据android docs/recommendation:developer.android.com/intl/es/guide/topics/media/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多