调用系统拍照 -- 踩过的坑

   本文提供一些参考,由于项目要使用拍照功能并且截图功能,本来说是在网上找一找用用,但是还是发现有很多问题,算上这一个拍照和选择图片的话算上写了第四种不同风格方案了(有多选,单选,系统拍照截图,系统选择图片截图),有两种方法是被需求pass,还剩两套拍照和选择图片在项目中用,在此过程中踩了些坑.

1,系统拍照原API版本问题,4.4以上的版本问题

这个也是头痛的问题,Android4.4以下使用拍照截图 ,会出现奔溃

解决办法



/**
* 截图并回调onActivityResult方法
* @param activity
* @param reqCode 请求�?
*/
public static void cropForReslt(final Activity activity, Uri uri, final int reqCode,CropParams cropParams){
setImgUri(uri);
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(imgUri, "image/*");

//在拍照之前先判断要跳转的页面是否存在
List<ResolveInfo> list = activity.getApplicationContext().getPackageManager().queryIntentActivities(
intent, 0);
int size = list.size();
 if (size == 0) {
Toast.makeText(activity, "can't find crop app", Toast.LENGTH_SHORT)
.show();
return;
} else {
intent.putExtra("outputX", cropParams.outputX);
intent.putExtra("outputY", cropParams.outputY);
intent.putExtra("aspectX", cropParams.aspectX);
intent.putExtra("aspectY", cropParams.aspectY);
intent.putExtra("scale", cropParams.scale);
intent.putExtra("return-data", true);


// only one
if (size == 1) {//存在的话进行跳转
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent(new ComponentName(res.activityInfo.packageName,
res.activityInfo.name));
activity.startActivityForResult(i, reqCode);
} else {//多个的话提示用户进行选择设备
// many crop app
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = activity.getPackageManager().getApplicationLabel(
res.activityInfo.applicationInfo);
co.icon = activity.getPackageManager().getApplicationIcon(
res.activityInfo.applicationInfo);
co.appIntent = new Intent(intent);
co.appIntent
.setComponent(new ComponentName(
res.activityInfo.packageName,
res.activityInfo.name));
cropOptions.add(co);
}


CropOptionAdapter adapter = new CropOptionAdapter(
activity.getApplicationContext(), cropOptions);


AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("choose a app");
builder.setAdapter(adapter,
new DialogInterface.OnClickListener() {


public void onClick(DialogInterface dialog, int item) {
activity.startActivityForResult(
cropOptions.get(item).appIntent,
reqCode);
}
});


builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {


if (imgUri != null) {
activity.getContentResolver().delete(imgUri, null, null);
imgUri = null;
}
}
});


AlertDialog alert = builder.create();
alert.show();
}
}

}

在拍照之前先判断要跳转的页面是否存在,存在的话在再系统清单进行查询


2,各大厂商的系统定制问题导致一些API不能正常使用

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imgUri = CropFileUtils.generateUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
activity.startActivityForResult(intent, reqCode);

这是开启系统拍照,就不多说了.

接下来是截图的代码重点

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setData(imgUri);

intent.setType("image/*");

intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY"aspectY);
intent.putExtra("scale", scale);
intent.putExtra("return-data", true);

测试了其他的手机(小米2s,Oppo,华为,魅族)都是完全OK.

测试了有些手机系统不能识别,比如:联想柠檬3s部分手机

拍完照之后就直接奔溃,DEBUG看了,

List<ResolveInfo> list = activity.getApplicationContext().getPackageManager().queryIntentActivities(
intent, 0);

这个方法没有查到要跳转的Activity,size为0,抛出未找到该Intent所跳转到的Activity

然后经过调试把上面标红的可以换成

intent.setDataAndType(imgUri, "image/*");

算是解决了


还有startActivityForResult(intent, reqCode)这个方法的话Fragment也是可以直接使用的,使用时返回的额resultcode要大于0才能生效官方文档有说明


Demo地址 https://github.com/chengzichen/CropDemo


猜你喜欢

转载自blog.csdn.net/chengzichen_/article/details/52135372