在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?
答案 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
,但只是准备好优雅地失败。