在开发过程中遇到相机或者相册获取图片后截取图片时只有三星手机可以用其他手机全部没有效果。
原本使用的方法是:
public void scropPic(Uri uri) {
Intent intent = new Intent();
intent.setAction("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("return-data", true);
startActivityForResult(intent, 2);
}
据说是intent.putExtra("return-data", true); 不能用true。具体也不太了解。所以收集各位大神的方法后总结过来的。
接下来看详细代码。
先准备好这4个方法
1.
/**
* 进入相机拍照获取图片
* @param context
* @param REQUE_CODE_CAMERA
*/
private void getImageFromCamer(Context context,int REQUE_CODE_CAMERA) {
//判断sdcard是否存在
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {
try {
//qwe为相片保存的文件夹名
File dir = new File(Environment.getExternalStorageDirectory() + "/" + "qwe");
if (!dir.exists())
dir.mkdirs();
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//asd为保存的相片名
File f = new File(dir, "asd");// localTempImgDir和localTempImageFileName是自己定义的名字
Uri u = Uri.fromFile(f);
intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
intent.putExtra(MediaStore.EXTRA_OUTPUT, u);
((Activity) context).startActivityForResult(intent, REQUE_CODE_CROP);
} catch (ActivityNotFoundException e) {
// TODO Auto-generated catch block
Toast.makeText(context, "没有找到储存目录", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context, "没有储存卡", Toast.LENGTH_LONG).show();
}
}
2.
/**
* 进入相机获取图片
* @param context
* @param REQUE_CODE_PHOTO
*/
public static void getImageFromPhoto(Context context, int REQUE_CODE_PHOTO) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
((Activity) context).startActivityForResult(intent, REQUE_CODE_PHOTO);
}
3./**
* 进入图片截取页面
* @param context
* @param uri
* @param REQUE_CODE_CROP
*/
public static void startPhotoZoom(Context context, Uri uri, int REQUE_CODE_CROP) {
int dp = 500;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.putExtra("crop", "true");
intent.putExtra("scale", true);// 去黑边
intent.putExtra("scaleUpIfNeeded", true);// 去黑边
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);// 输出是X方向的比例
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高,切忌不要再改动下列数字,会卡死
intent.putExtra("outputX", dp);// 输出X方向的像素
intent.putExtra("outputY", dp);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra("return-data", false);// 设置为不返回数据
((Activity) context).startActivityForResult(intent, REQUE_CODE_CROP);
}
4.
/**
* 把图片的路径转换成bitmap格式的图片
* @param uri
* @param mContext
* @return
*/
public static Bitmap getBitmapFromUri(Uri uri, Context mContext) {
try {
// 读取uri所在的图片
Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
最关键的是在onActivityResult:@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
return;
}
switch (requestCode) {
//跳转相册返回后进入图片截取页面
case REQUE_CODE_PHOTO:
if (null != data) {// 为了取消选取不报空指针用的
uri = data.getData();
startPhotoZoom(this, uri, 2);
}
break;
//跳转图片截取页面返回后保存图片并设置图片
case REQUE_CODE_CROP:
if (uri == null) {
break;
}
cropBitmap = getBitmapFromUri(uri, this);
if (cropBitmap != null) {
try {
CunQuTuQian.saveImage(cropBitmap, etName.getText().toString().trim());
bitmap = CunQuTuQian.loadImage(etName.getText().toString().trim());
ivTu.setImageBitmap(bitmap);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
//跳转到相机返回后进入图片截取界面
case REQUE_CODE_CAMERA:
//获得相片地址
File f = new File(Environment.getExternalStorageDirectory() + "/" + "qwe" + "/" + "asd");
try {
uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(),
f.getAbsolutePath(), null, null));<pre name="code" class="java">public class CunQuTuQian {
private final static String ALBUM_PATH
= Environment.getExternalStorageDirectory() + "/download_test/";
//保存bitmap类型图片到 Environment.getExternalStorageDirectory() + "/download_test/";
@SuppressLint("NewApi")
public static void saveImage(Bitmap bm, String fileName) throws IOException {
File dirFile = new File(ALBUM_PATH);
if(!dirFile.exists()){
dirFile.mkdir();
}
File myCaptureFile = new File(ALBUM_PATH + fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
}
//从 Environment.getExternalStorageDirectory() + "/download_test/";读取bitmap类型图片
public static Bitmap loadImage(String fileName) throws FileNotFoundException{
FileInputStream is = new FileInputStream(ALBUM_PATH + fileName);
Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
}
}
// u就是拍摄获得的原始图片的uri,剩下的你想干神马坏事请便…… startPhotoZoom(this, uri, 2); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: break; } } 最后加上保存图片的工具类:
public class CunQuTuQian {
private final static String ALBUM_PATH
= Environment.getExternalStorageDirectory() + "/download_test/";
//保存bitmap类型图片到 Environment.getExternalStorageDirectory() + "/download_test/";
@SuppressLint("NewApi")
public static void saveImage(Bitmap bm, String fileName) throws IOException {
File dirFile = new File(ALBUM_PATH);
if(!dirFile.exists()){
dirFile.mkdir();
}
File myCaptureFile = new File(ALBUM_PATH + fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
}
//从 Environment.getExternalStorageDirectory() + "/download_test/";读取bitmap类型图片
public static Bitmap loadImage(String fileName) throws FileNotFoundException{
FileInputStream is = new FileInputStream(ALBUM_PATH + fileName);
Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
}
}
注意事项:
添加这两个权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Samsung的系统相机,版式是横板的,如果你的activity恰巧是竖版的,那么获取这个回调uri的时候,很可能为空!
原因在于,如果你没有设置版式改变的时候,activity不要调用onCreate方法!这就是要命的地方!
设置方法其实很简单:
1、在Manfest.xml中,给activity添加一个属性:android:configChanges="orientation|keyboardHidden"
2、在activity中添加:
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
}
原因在于,如果你没有设置版式改变的时候,activity不要调用onCreate方法!这就是要命的地方!
设置方法其实很简单:
1、在Manfest.xml中,给activity添加一个属性:android:configChanges="orientation|keyboardHidden"
2、在activity中添加:
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
}
另外还有一个蛋疼的错误容易犯:千万别给这个activity添加单例模式,即:android:launchMode="singleInstance"
在android4.0以后应该添加screenSize这样才能达到不重新加载的效果
android:configChanges="orientation|keyboardHidden|screenSize"