错误:没有找到可处理Intent act=android.media.action.IMAGE_CAPTURE的活动

5
我有一段代码是从API 23之前遗留下来的,我需要将其升级以适用于最新的API,并使用FileProvider解决因为暴露文件安全问题而必须使用的问题。然而,现在相机不再工作了(这并不一定是由于FileProvider导致的,只是在需要使用FileProvider的同时停止工作了,因为更新了API)。在调用MediaStore.ACTION_IMAGE_CAPTURE意图的创建时,代码出错了:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE dat=content://com.company.appname/external_files/temp.jpg flg=0x1 }
我已经进行了大量的搜索,但是每个人(尤其是StackOverflow)都认为添加检查相机是否存在的代码可以解决这个问题,但实际上并不行。这只是一个检查,如果没有检测到相机,则不运行代码。我测试用的所有设备都有相机。我在Android模拟器上进行了调试(并通过使用默认相机应用程序拍摄我的照片来验证了连接到我的笔记本电脑相机的模拟相机),还在我的手机上进行了调试,该手机具有前置和后置相机,均可正常工作。所以,请不要提供绕过问题的答案。我知道我有相机,不需要检查它们。我需要帮助确定为什么我的代码找不到MediaStore.ACTION_IMAGE_CAPTURE的意图。
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

并且

<provider
    android:name=".Providers.GenericFileProvider"
    android:authorities="com.company.myapp"
    android:exported="false"
    android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

MainActivity.java

File f = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
Uri uri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, f);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CAMERA);

当启动活动时,代码在最后一行抛出异常。由于这是继承的代码,我倾向于放弃他们为相机捕获所编写的代码,并重新开始,但在 > API 23 升级之前,该代码曾经运行。

仅供参考,在升级之前的调用如下:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));

但是这种方法已不再适用(由于文件URI的暴露而被API阻止)

有人发现如何使其正常工作了吗?

风格说明

我为简化代码进行了编辑,生产环境中有异常处理。

1个回答

9

提醒一下,在升级前的调用如下:

该代码使用了EXTRA_OUTPUT,这是传递ACTION_IMAGE_CAPTURE中的Uri的正确方法。它的问题是Uri.fromFile()部分,在您的targetSdkVersion升至24或更高版本后,将无法在Android 7.0+上运行,正如您所指出的那样。

正确的代码是这两个代码的组合:

File f = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(MainActivity.this, AUTHORITY, f));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CAMERA);

请查看此示例应用程序,了解完整的使用ACTION_IMAGE_CAPTUREFileProvider的示例。


你真是个天才!谢谢。 - iolympian
等一下,但 Android 8.0 的级别号是26,而不是27。 - RedSIght
谢谢,这对我有用!我只是添加了 intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri) 就可以了。 - user1300214

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接