Moto X设备调用MediaStore.ACTION_IMAGE_CAPTURE无法打开相机求助
Moto X上MediaStore.ACTION_IMAGE_CAPTURE无法打开相机的排查方案
我来帮你梳理下Moto X设备上调用相机失败的可能原因,结合你的代码片段,咱们一步步来解决:
1. 确认相机权限已正确申请
Android 6.0(API 23)及以上版本需要动态申请相机权限,哪怕你已经在Manifest里声明了<uses-permission android:name="android.permission.CAMERA"/>,也要在代码里主动请求用户授权:
// 检查相机权限状态 if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); return; }
只有等用户授权通过后,再执行启动相机的逻辑。
2. 确保cameraUri使用FileProvider生成(Android 7.0+)
如果你的Moto X运行的是Android 7.0(API 24)及以上版本,直接用file://格式的URI会触发FileUriExposedException,必须通过FileProvider生成content://类型的安全URI:
步骤1:在Manifest中注册FileProvider
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
步骤2:创建res/xml/file_paths.xml文件
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="camera_photos" path="Pictures" /> </paths>
步骤3:生成合法的cameraUri
// 生成临时图片文件 File imageFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "temp_capture.jpg"); // 通过FileProvider转换为content URI Uri cameraUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", imageFile);
3. 完善URI权限授予逻辑
只添加FLAG_GRANT_WRITE_URI_PERMISSION可能不够,建议同时授予读写权限,并且明确指定给相机应用:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 获取所有能处理相机Intent的应用包名,精准授予权限 List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resolveInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, cameraUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri); // 这里无需再addFlags,因为已经通过grantUriPermission完成了权限授予
4. 排查启动逻辑的潜在问题
- 先测试去掉
Intent.createChooser的情况,直接调用context.startActivityForResult(intent, REQUEST_CODE),看是否能打开相机,排除选择器的干扰。 - 暂时注释掉
TelloApplication.getInstance().setInBackgroundWithSafeMode(true)这行代码,测试是否是应用后台安全模式限制了相机启动。
5. 检查设备特定问题
Moto X部分机型有定制化的系统相机应用,你可以尝试安装第三方相机(比如Google相机),然后用你的代码测试是否能启动,以此判断是系统相机兼容性问题还是代码逻辑问题。
内容的提问来源于stack exchange,提问作者Sohail Ahmad Khan
相关产品推荐
相关产品推荐

