我有以下代码要求用户从照片应用中挑选图片或通过相机应用捕获图片:
// Camera
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = fragment.getActivity().getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
fragment.startActivityForResult(chooserIntent, UPLOAD_IMAGE_ACTIVITY_REQUEST_CODE);
我的onActivityResult代码:
if(requestCode == UPLOAD_IMAGE_ACTIVITY_REQUEST_CODE)
{
final boolean isCamera;
if(data == null)
{
isCamera = true;
}
else
{
final String action = data.getAction(); // data is always empty here after capture image by default camera in 5.1.1!
if(action == null)
{
isCamera = false;
}
else
{
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
//do sth according to value of isCamera
}
这些代码在之前的Android版本中运行良好。但是,当我将我的nexus 5更新为Android 5.1.1 (同时将相机应用程序更新为最新版本)时,请求默认相机拍摄照片时,代码效果不佳。
根据调试器,当代码在默认相机应用程序捕获图像后达到final String action = data.getAction();
时,结果Intent data
始终为空Intent(尽管不为null),但不包含动作,演员,数据等。所以final String action = data.getAction();
总是返回null并且我的后续代码失败。
我猜在5.1.1中默认的相机应用程序有所改变,因此相机的意图行为是不同的。但后来我不知道如何让它发挥作用。
任何建议都会受到赞赏。谢谢!
答案 0 :(得分:3)
我又添加了一个条件。在5.1.1以及不同的API级别中,它似乎没有任何问题。
if(data == null){
isCamera = true;
}else if(data.getData() == null){
isCamera = true;
}
else{
//....
答案 1 :(得分:1)
你的猜测是正确的,Lollipop有一个变化:http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
public static final String ACTION_IMAGE_CAPTURE 在API级别3中添加
标准意图动作,可以发送给相机应用程序捕获图像并将其返回。
调用者可以传递额外的EXTRA_OUTPUT来控制该图像的写入位置。如果EXTRA_OUTPUT不存在,则在额外字段中返回小尺寸图像作为Bitmap对象。这对于只需要小图像的应用程序非常有用。如果存在EXTRA_OUTPUT,则将将全尺寸图像写入EXTRA_OUTPUT的Uri值。从LOLLIPOP开始,这个uri也可以通过setClipData(ClipData)提供。如果使用此方法,您仍然必须通过EXTRA_OUTPUT字段提供uri以与旧应用程序兼容。如果您没有设置ClipData,则在调用startActivity(Intent)时会为您复制它。
你需要在意图中设置ClipData,就是我这样做的方式
intent.setClipData(ClipData.newRawUri(null, Uri.fromFile(file)));
在你的情况下,我认为它是
intent.setClipData(ClipData.newRawUri(null, outputFileUri));
另外我没有设置MediaStore.EXTRA_OUTPUT,因为对我来说它返回空数据,我不知道你怎么没有得到空数据,设置MediaStore.EXTRA_OUTPUT,但那是另一回事:{{3} }
答案 2 :(得分:1)
我遇到了同样的问题而且我添加了
mFileTemp.getParentFile().mkdirs();
在将uri传递给意图并为我解决之前。
答案 3 :(得分:0)
经过一些研究和测试,我找到了解决方案。
解决方案是在创建临时文件时使文件或文件对象的路径成为静态文件。
private static String path;
private File createImageFile() throws IOException {
File storageDir = Environment.getExternalStorageDirectory();
File image = File.createTempFile(
"hoivia_image", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
path=image.getpath();
return image;
}
之所以会发生这种情况,是因为当前活动对象在onActivityResult()处为空。
希望它对您有帮助。