4

开始一个意图:

  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  CurrentFile = new File(getTempFileString());
  CurrentUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", CurrentFile);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, CurrentUri);
  intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
  startActivityForResult(intent, IMAGE_CAPTURE);

曾经工作。它不再这样做了。我在意图之后开始的方法是:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
}

resultCode以前是,RESULT_OK现在是RESULT_CANCELED

如果我停止检查 resultCode 并跳过它,我会发现照片不存在。

根据 CommonsWare 的评论,我提取了日志。在此操作期间生成的 654 行中,有 4 行似乎相关。

2020-10-12 11:03:04.301 1471-1763/? E/MediaProvider: Creating a non-default top level directory or deleting an existing one is not allowed!
2020-10-12 11:03:04.310 477-2112/? I/AppsFilter: interaction: PackageSetting{240e1c6 com.[my app package]/10151} -> PackageSetting{193734c com.android.camera2/10124} BLOCKED
2020-10-12 11:03:04.553 390-9884/? W/ServiceManager: Permission failure: android.permission.SYSTEM_CAMERA from uid=10124 pid=11746
2020-10-12 11:03:14.097 11746-11746/? E/CAM_StateSavePic: exception while saving result to URI: Optional.of(content://[my app package].provider/external_files/[The SD card path I asked for]/1602518584301.jpg)

我要求将文件保存在这里:

new File(Environment.getExternalStorageDirectory(), getString(a.getApplicationInfo().labelRes))

这似乎是问题所在。

4

3 回答 3

10

真正的@CommonsWare 值得称赞。问题是getTempFileString()源代码中的调用。我试图将文件保存到临时路径,以便我可以在之后立即删除它。该文件只存在不久。谷歌阻止了对此的访问。Camera应用程序收到有关无法保存到此路径的错误,但它没有引发错误或显示消息。它只是将结果RESULT_CANCELED返回给我的应用程序。我通过更新用于本地缓存目录的路径getExternalCacheDir()并在其中使用子目录来解决此问题。

编辑:添加对我有用的代码。删除了应用程序特定的文本,以及错误处理以保持简短和简单。

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "My Application Directory");

if (!path.exists()) {
   path.mkdir();
}

File imageFile = File.createTempFile("Your file Name", ".jpg", path);

Context context = getActivity().getBaseContext();
Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", imageFile);

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
   String packageName = resolveInfo.activityInfo.packageName;
   context.grantUriPermission(packageName, CurrentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

startActivityForResult(intent, IMAGE_CAPTURE); // IMAGE_CAPTURE = 0
于 2020-10-12T17:06:26.263 回答
1

您不应该使用“getExternalStoragePublicDirectory()”,因为这是共享存储行为,并且从(可能)2021 年 7 月 5 日起,Play 商店中的所有应用程序必须以 android SDK 30 为目标并仅使用 Scoped Storage(因此您不能使用“requestLegacyStorage” , idk 关于“preserveLegacyStorage”)。

我建议您将目标路径更改为:

context.getExternalFilesDir(null).getPath();

有一个美好的一天和一个美好的编码:D

于 2021-06-23T13:10:47.323 回答
0

这是一种奇怪的行为,但如果您使用MediaStore.EXTRA_OUTPUT标志方法onActivityResult()将始终返回空数据,并且您应该在此处指出的位置查找数据:

CurrentUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", CurrentFile);

所以有两种不同的方式来处理你正在寻找的结果

于 2022-03-02T15:52:23.920 回答