可靠的方法来执行ACTION_IMAGE_CAPTURE意图?

时间:2016-06-28 16:08:08

标签: android android-intent

在Android上执行ACTION_IMAGE_CATPURE意图的最可靠方法是什么?我尝试过多次在网上找到的东西,但没有一种能在每台设备上运行。我的测试设备是Nexus 6(Android 6.0.1)和联想手机(4.4.2)。

我已尝试过以下操作(删除冗余代码,例如权限 - 这些代码显然正常运行):

选项A(仅适用于Nexus 6)

final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = "img_" + System.currentTimeMillis() + ".jpg";
outputFileUri = Uri.fromFile(new File(root, fname));

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, outputFileUri);

try {
     startActivityForResult(takePhotoIntent, 1);
} catch (SecurityException e) { }

// ....

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    System.out.println(new File(outputFileUri.toString()).exists()));
    // This prints false on Kitkat, but true on 6.0

选项B(两者都不起作用,但似乎它应该适用于两者)

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
outputFileUri = takePhotoIntent.getData();
// start intent

// .....

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    System.out.println(new File(outputFileUri.toString()).exists()));
    // This prints false on everything

似乎应该是在Android版本中实现这一目标的可靠方式,但过去一小时我一直处于堆栈溢出状态,并且我有10多个解决方案。已经尝试过,但没有一个能够在旧版本的Android上运行。

如何从ACTION_IMAGE_CAPTURE意图中可靠地获取Uri?

1 个答案:

答案 0 :(得分:2)

  

//这在Kitkat上打印为false,但在6.0

时为true

在所有版本的Android上都应该失败。 outputFileUri.toString()类似于"file:///..."(对于...的某些值),并且它不是有效的文件系统路径。也许谷歌更新了File来处理剥离计划。

更好的解决方案是保留new File(root, fname),这是正确的File对象。请记住,当摄像头应用程序位于前台时,您的进程可能会终止,因此请在保存的实例状态Bundle中保留此进程。

另请注意,一旦targetSdkVersion为24或更高,file Uri values are banned,您的方法将无法在API级别24+上运行。

  

但似乎它应该同时适用于

The documentation并未声明ACTION_IMAGE_CAPTURE将返回任何,更不用说Uri了。我同意这在逻辑上应该是答案,但Android中有很多东西违背了逻辑。

  

似乎应该有一种可靠的方法在Android版本中执行此操作

嗯,期待ACTION_IMAGE_CAPTURE的可靠结果是愚蠢的。您正在委托第三方应用。有数以千计的Android设备型号,以及数百个相机应用程序。 Play商店和其他地方还有数百种。许多相机应用程序开发人员都没有很好地测试ACTION_IMAGE_CAPTURE,并且有许多相机应用程序存在错误,例如完全忽略EXTRA_OUTPUT

上述file Uri禁令会导致更多人被绊倒,因为他们可能不会期待content Uri。哎呀, Google 甚至没有在他们自己的相机应用上测试ACTION_IMAGE_CAPTURE ,只要他们不处理content { {1}}值和will not do so for some time

随意使用Uri,但只是准备好优雅地失败。