在开发过程中,头像上传是非常常见的,一般选择方式分为两种,拍照和从图库选取,既然今天的主要内容是从图库读取图片,那我就仔仔细细说一下其中遇到的问题,因为我本身也是小白,所以就是记录下自己遇到的问题,各位大神,别打脸......
先说说事情的经过,我的测试机是小米,跟随了我两年多了,有的时候我就想,如果所有人用的都是这种类型的手机,那么开发人员得多轻松啊,但是也或许是android手机型号多,也才应证了android之所以是Android,ios是ios吧.最主要说的就是,我在小米上面开发的时候完全没有遇到问题,但是到了华为上,却出现了崩溃,当然这不是手机厂商的问题,还是开发中自己的疏忽,不多废话了,开始上代码.
//从列表中选择某项并返回所选数据Intent intent = new Intent(Intent.ACTION_PICK);
//让用户选择数据,并返回所选数据
//Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, QuantityUtils.ALBUM);
建议大家采用第一种方式,因为我之所以出现问题就是第二种方式导致的
上面的含义就是打开系统准备好的选取资源方式
接收时,就是用了百度上搜出来的前篇一律的代码
if (QuantityUtils.ALBUM == requestCode) {//不为空说明获取成功
if (data != null) {
Uri uri = data.getData();
if (uri == null) {
return;
}
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().managedQuery(uri, proj, null, null, null);
Uri uri1 = null;
//部分手机返回为null(这里百度上搜索的没有,具体为什么会有null我不清楚,主要是因为华为采用ACTION_GET_CONTENT,会返回null)
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
//部分手机返回为null(还是华为上,上面返回了数据,可是这里又继续报null)
if (path != null) {
File file = new File(path);
uri1 = Uri.fromFile(file);
}
}
if (uri1 == null) {//由于android版本不同,uri有两种开头方式,所以为了万无一失,都要进行一下转换,当然是建立在uri为null的基础上uri1 = BitmapHelper.ConvertUri(getActivity(), uri, "camera.jpeg", PathUtils.Path_Mine);
}
if (uri1 != null) {//这个就是去切图了
startImageZoom(uri);
}
}
}
这里是转换uri的代码,主要就是把图片存到一个位置,再取出来(里面做了打薄操作,防止图片过大,使时间过长)
public static Uri ConvertUri(Context mContext, Uri uri, String imageName, String path) {
InputStream is = null;
try {
is = mContext.getContentResolver().openInputStream(uri);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
Bitmap bitmap = BitmapFactory.decodeStream(is, null, opt);
return SDHelper.setBitmapToUri(mContext, bitmap, imageName, path);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
其中有用到存储的部分,如下:
public static Uri setBitmapToUri(Context mContext, Bitmap bitmap, String imageName, String path) {
File file = setBitmapToFile(mContext, bitmap, imageName, path, false);
if (file == null) {
return null;
}
return Uri.fromFile(file);
}
public static File setBitmapToFile(Context mContext, Bitmap bitmap, String imageName, String path) {
return setBitmapToFile(mContext, bitmap, imageName, path, true);
}
public static File setBitmapToFile(Context mContext, Bitmap bitmap, String imageName, String path, boolean isCompress) {
//如果mContext为null,则return
if (mContext == null) {
return null;
}
//如果bitmap为null,则return
if (bitmap == null) {
return null;
}
//如果imageName为null或"",则return
if (imageName == null || "".equals(imageName)) {
return null;
}
//如果path为null或"",则return
if (path == null || "".equals(path)) {
return null;
}
String real_path = getRealPath(mContext, path);
File file = new File(real_path, imageName);
//判断文件是否存在,不存在则创建其所在文件夹
if (!file.exists()) {
File dir = new File(real_path, File.separator);
dir.mkdirs();
}
try {
file.createNewFile();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 80;
// //根据图片名称的后缀名决定文件的存储格式
if (imageName.contains(".png") || imageName.contains(".PNG")) {
bitmap.compress(Bitmap.CompressFormat.PNG, options, baos);
} else {
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
while (isCompress && baos.toByteArray().length / 1024 > 100) {
baos.reset();
options -= 10;
if (imageName.contains(".png") || imageName.contains(".PNG")) {
bitmap.compress(Bitmap.CompressFormat.PNG, options, baos);
} else {
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
return file;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
上面的使用在很多时候就可以避免问题了,
如果有使用拍照的,拍照的时候往往会出现模糊的现象,
//拍照好的照片存放在该文件中
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(filePhoto));//把拍出来的图片存储起来会节省很多问题,也避免了图片模糊,系统返回的bitmap是压缩后,所以模糊比较大
startActivityForResult(intent, QuantityUtils.TAKE_PHOTO);
裁剪处也一样,注意:裁剪图片的uri和裁剪过后的uri不能相同,在很多手机上虽然能正常使用,进行替换,但也有部分手机不能使用,导致裁剪出来的图片损坏
//裁剪完图片存的位置
File file = new File(PathUtils.getPath_Crop(getActivity()));
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("output", Uri.fromFile(file));
intent.putExtra("return-data", false);//设置不返回数据,将其存储起来
startActivityForResult(intent, QuantityUtils.CROP);
基本上就遇到这些问题了,别的具体还没有深究-.-