在项目的兼容适配上碰到了一个问题,就是之前写好的上传头像功能在华为nexus6p原生机上不能使用了。
经过一番研究发现是以下两个问题导致的:
1、url的路径产生了变化,导致获取bitmap的方法跟着要变。
在华为nexus6p上是:
Bitmap photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));
在小米4(同为6.0系统,但是小米的修改系统造成了一定影响)或者其他低于6.0版本手机上是:
Bitmap photo = data.getParcelableExtra("data");
解决方式参考so:http://stackoverflow.com/questions/32564041/java-lang-nullpointerexception-attempt-to-invoke-virtual-method-java-lang-stri
最后判断版本进行不同的获取操作:
Bitmap photo = null;
try {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && data.getData() != null) {
photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));
} else {
// in android version lower than M your method must work
photo = data.getParcelableExtra("data");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
private void uploadImage(Bitmap photo) {
if (photo == null) {
LogUtils.d("裁剪后的photo为空");
return;
}
//存到本地
FileOutputStream b = null;
File file = new File(Config.LOCAL_PORTRAIT_CUT_PATH);
if (!file.exists()) {
file.mkdirs();// 创建文件夹
} else {
//删除文件夹下所有文件
CommonUtils.deleteFile(file);
}
localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
String fileName = Config.LOCAL_PORTRAIT_CUT_PATH + localTempImgFileName;
try {
b = new FileOutputStream(fileName);
photo.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
b.flush();
b.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后是改功能Aty完整代码:
EditUserInfoActivity.java:
/**
* Created by jiangzn on 16/10/3.
*/
public class EditUserInfoActivity extends BaseActivity implements View.OnClickListener {
@Bind(R.id.view_curtain_edituserinfo)
View view_curtain_edituserinfo; //幕布
@Bind(R.id.btn_editportrait_eidtuserinfo)
Button btn_editportrait_eidtuserinfo; //头像选择按钮
@Bind(R.id.btn_editsex_eidtuserinfo)
Button btn_editsex_eidtuserinfo; //性别选择按钮
@Bind(R.id.btn_editnickname_eidtuserinfo)
Button btn_editnickname_eidtuserinfo; //修改昵称
@Bind(R.id.btn_editsign_eidtuserinfo)
Button btn_editsign_eidtuserinfo; //修改签名
@Bind(R.id.btn_bindphonenumber_eidtuserinfo)
Button btn_bindphonenumber_eidtuserinfo; //绑定手机号
@Bind(R.id.layout_choose_edituserinfo)
LinearLayout layout_choose_edituserinfo; //选择布局
@Bind(R.id.tv_choosetv1_edituserinfo)
TextView tv_choosetv1_edituserinfo;
@Bind(R.id.tv_choosetv2_edituserinfo)
TextView tv_choosetv2_edituserinfo;
@Bind(R.id.btn_choosebtn1_edituserinfo)
Button btn_choosebtn1_edituserinfo;
@Bind(R.id.btn_choosebtn2_edituserinfo)
Button btn_choosebtn2_edituserinfo;
@Bind(R.id.btn_chooseclose_edituserinfo)
Button btn_chooseclose_edituserinfo;
@Bind(R.id.civ_userhead_edituserinfo)
NGNormalCircleImageView civ_userhead_edituserinfo;
@Bind(R.id.btn_back_edituserinfo)
ImageButton btn_back_edituserinfo;
@Bind(R.id.tv_username_edituserinfo)
TextView tv_username_edituserinfo;
@Bind(R.id.tv_usergender_edituserinfo)
TextView tv_usergender_edituserinfo;
@Bind(R.id.tv_sign_edituserinfo)
TextView tv_sign_edituserinfo;
private String localTempImgFileName = "";
private Boolean isupdate = false; //数据是否更新
private static final int REQUEST_CAMERA = 1;
private static final int REQUEST_READ_WIRTE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected int getContentViewLayoutID() {
return R.layout.activity_edituserinfo;
}
@Bind(R.id.targetview_edituserinfo)
View targetview_edituserinfo;
@Override
protected View getLoadingTargetView() {
return null;
}
private void initData() {
UserInfo tempUserInfo = UserInfoManager.getInstance(EditUserInfoActivity.this).getUserInfo();
if (!CommonUtils.isNull(tempUserInfo)) {
//头像
Glide.with(EditUserInfoActivity.this).load(tempUserInfo.getHeadUrl()).into(civ_userhead_edituserinfo);
//昵称
tv_username_edituserinfo.setText(CommonUtils.notNull(tempUserInfo.getNickName()));
//性别
if (tempUserInfo.getGender() == null) {
tv_usergender_edituserinfo.setText("未设置");
} else if (tempUserInfo.getGender() == 1) {
tv_usergender_edituserinfo.setText("男");
} else {
tv_usergender_edituserinfo.setText("女");
}
//签名
tv_sign_edituserinfo.setText(CommonUtils.notNull(tempUserInfo.getSign()));
}
}
private void initView() {
layout_choose_edituserinfo.setVisibility(View.VISIBLE);
layout_choose_edituserinfo.setY(mScreenHeight + getViewHeight(layout_choose_edituserinfo));
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA:
onRequestCamera(grantResults);
break;
case REQUEST_READ_WIRTE:
onRequestWriteAndRead(grantResults);
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
@OnClick({R.id.btn_editportrait_eidtuserinfo, R.id.btn_editnickname_eidtuserinfo,
R.id.view_curtain_edituserinfo, R.id.btn_editsex_eidtuserinfo,
R.id.btn_editsign_eidtuserinfo, R.id.btn_chooseclose_edituserinfo,
R.id.btn_bindphonenumber_eidtuserinfo, R.id.btn_back_edituserinfo
})
@Override
public void onClick(View view) {
Intent i;
switch (view.getId()) {
case R.id.btn_editportrait_eidtuserinfo:
//更改Choose框文字
tv_choosetv1_edituserinfo.setText("拍照");
tv_choosetv2_edituserinfo.setText("从相册选择");
btn_choosebtn1_edituserinfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO 拍照
getPortraitByCamera();
}
});
btn_choosebtn2_edituserinfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO 从相册选择
getPortraitByAlbum();
}
});
ifShowChooseLayout(true);
break;
case R.id.btn_editsex_eidtuserinfo:
//更改Choose框文字
tv_choosetv1_edituserinfo.setText("男");
tv_choosetv2_edituserinfo.setText("女");
btn_choosebtn1_edituserinfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO 转菊花
//TODO 向服务器提交用户修改性别为男性
Map updateParams = new HashMap<>();
updateParams.put("gender", 1);
HttpU.getInstance().post(EditUserInfoActivity.this,
Config.UPDATE_USER,
updateParams,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
LogUtils.d("EditUserInfoActivity_updategender" + response);
HttpResult updateResult = JSON.parseObject(response, HttpResult.class);
if (updateResult.isSuc()) {
//TODO 菊花消失
//TODO 显示更改名字成功
//更新本地用户信息数据
HttpU.getInstance().post(mContext,
Config.QUERY_USER,
null,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
HttpResult queryResult = JSON.parseObject(response, HttpResult.class);
if (queryResult.isSuc()) {
//更新userinfo
UserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);
UserInfoManager.getInstance(mContext).saveUserInfo(userInfo);
//更新ui
tv_usergender_edituserinfo.setText("男");
ifShowChooseLayout(false);
}
}
}
);
} else {
//TODO 显示保存失败
}
//TODO 菊花消失
}
}
);
}
});
btn_choosebtn2_edituserinfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO 转菊花
//TODO 向服务器提交用户修改性别为女性
Map updateParams = new HashMap<>();
updateParams.put("gender", 2);
HttpU.getInstance().post(EditUserInfoActivity.this,
Config.UPDATE_USER,
updateParams,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
LogUtils.d("EditUserInfoActivity_updategender" + response);
HttpResult updateResult = JSON.parseObject(response, HttpResult.class);
if (updateResult.isSuc()) {
//TODO 菊花消失
//TODO 显示更改名字成功
//更新本地用户信息数据
HttpU.getInstance().post(mContext,
Config.QUERY_USER,
null,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
HttpResult queryResult = JSON.parseObject(response, HttpResult.class);
if (queryResult.isSuc()) {
//更新userinfo
UserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);
UserInfoManager.getInstance(mContext).saveUserInfo(userInfo);
//更新ui
tv_usergender_edituserinfo.setText("女");
ifShowChooseLayout(false);
}
}
}
);
} else {
//TODO 显示保存失败
}
//TODO 菊花消失
}
}
);
}
});
ifShowChooseLayout(true);
break;
case R.id.btn_editnickname_eidtuserinfo:
//修改昵称
i = new Intent(EditUserInfoActivity.this, EditNickNameActivity.class);
startActivityForResult(i, Config.EDITUSERINFO_EDIT_USERNAME);
break;
case R.id.btn_editsign_eidtuserinfo:
//修改签名
i = new Intent(EditUserInfoActivity.this, EditSignActivity.class);
startActivityForResult(i, Config.EDITUSERINFO_EDIT_SIGN);
break;
case R.id.btn_bindphonenumber_eidtuserinfo:
//绑定手机号
i = new Intent(EditUserInfoActivity.this, BindPhoneNumberActivity.class);
startActivity(i);
break;
case R.id.view_curtain_edituserinfo:
//点击幕布
ifShowChooseLayout(false);
break;
case R.id.btn_chooseclose_edituserinfo:
//点击取消
ifShowChooseLayout(false);
break;
case R.id.btn_back_edituserinfo:
//点击返回
onBackPressed();
break;
}
}
@Override
protected void initViewsAndEvents() {
if ((ContextCompat.checkSelfPermission(EditUserInfoActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|| (ContextCompat.checkSelfPermission(EditUserInfoActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
{
ActivityCompat.requestPermissions
(EditUserInfoActivity.this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_READ_WIRTE);
} else {
initView();
initData();
}
}
private static boolean ifshowchooselayout = false;
private void ifShowChooseLayout(boolean isshow) {
ifshowchooselayout = isshow;
if (isshow) {
//选择头像,幕布淡入,头像选择布局淡入上滑
showCurtain(true);
showPortraitChoose(true);
} else {
//点击幕布选择框消失
showCurtain(false);
showPortraitChoose(false);
layout_choose_edituserinfo.setY(mScreenHeight + getViewHeight(layout_choose_edituserinfo));
}
}
/**
* 控制选择头像布局显示
*
* @param isShow
*/
private void showPortraitChoose(boolean isShow) {
if (isShow) {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 0f,
1f);
PropertyValuesHolder trsX = PropertyValuesHolder.ofFloat("translationY",
-1);
ObjectAnimator.ofPropertyValuesHolder(layout_choose_edituserinfo, pvhX, trsX).setDuration(400).start();
} else {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
0f);
ObjectAnimator.ofPropertyValuesHolder(layout_choose_edituserinfo, pvhX).setDuration(400).start();
}
}
/**
* 控制幕布显示
*
* @param isShow
*/
private void showCurtain(boolean isShow) {
ObjectAnimator animator;
if (isShow) {
view_curtain_edituserinfo.setVisibility(View.VISIBLE);
animator = ObjectAnimator.ofFloat(view_curtain_edituserinfo, "alpha", 0f, 1f);
animator.setDuration(400);
animator.start();
} else {
animator = ObjectAnimator.ofFloat(view_curtain_edituserinfo, "alpha", 1f, 0f);
animator.setDuration(400);
animator.start();
view_curtain_edituserinfo.setVisibility(View.GONE);
}
}
/**
* 通过手机拍照,选取照片
*/
public void getPortraitByCamera() {
if (!AndroidCompatUtils.checkSelfPermission(this, Manifest.permission.CAMERA, REQUEST_CAMERA)) {
return;
}
localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
//先验证手机是否有sdcard
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {
try {
File dir = new File(Environment.getExternalStorageDirectory() + "/" + Config.LOCAL_PORTRAIT_PATH);
if (!dir.exists()) {
dir.mkdirs();
} else {
//删除所有其他照片
CommonUtils.deleteFile(dir);
}
File f = new File(dir, localTempImgFileName);
/**
* 如果该文件夹已经存在,则删除它,否则创建一个
*/
try {
if (f.exists()) {
f.delete();
}
f.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(f);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, Config.GET_IMAGE_VIA_CAMERA);
} catch (ActivityNotFoundException e) {
// TODO Auto-generated catch block
Toast.makeText(EditUserInfoActivity.this, "没有找到储存目录", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(EditUserInfoActivity.this, "没有储存卡", Toast.LENGTH_LONG).show();
}
}
//照片URL
private Uri imageUri;
/**
* 从相册得到图片
*/
public void getPortraitByAlbum() {
// 激活系统图库,选择一张图片
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, Config.GET_IMAGE_VIA_GALLERY);
}
public Bitmap getImageBitmap(Context context, Intent intent) {
Bitmap bitmap = null;
if (intent.getExtras() != null) {
bitmap = (Bitmap) intent.getExtras().get("data");
} else {
Uri uri = intent.getData();
try {
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
return bitmap;
}
Uri tempuri;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case Config.GET_IMAGE_VIA_CAMERA:
//u就是拍摄获得的原始图片的uri,下面调用选取框进行裁剪
cropImage(imageUri, 300, 300, Config.PHOTO_REQUEST_CUT);
break;
case Config.GET_IMAGE_VIA_GALLERY:
//从相册选取头像
Bitmap bitmapfromgallery = getImageBitmap(EditUserInfoActivity.this, data);
cropImage(Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmapfromgallery, null, null)),
300, 300, Config.PHOTO_REQUEST_CUT
);
break;
case Config.EDITUSERINFO_EDIT_USERNAME:
//修改昵称回调
if (data.getBooleanExtra("isupdate", false)) {
tv_username_edituserinfo.setText(CommonUtils.notNull(UserInfoManager.
getInstance(EditUserInfoActivity.this).getUserInfo().getNickName()));
}
isupdate = true;
break;
case Config.EDITUSERINFO_EDIT_SIGN:
//修改签名回调
if (data.getBooleanExtra("isupdate", false)) {
tv_sign_edituserinfo.setText(CommonUtils.notNull(UserInfoManager.
getInstance(EditUserInfoActivity.this).getUserInfo().getSign()));
}
isupdate = true;
break;
case Config.PHOTO_REQUEST_CUT:
Bitmap photo = null;
try {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && data.getData() != null) {
photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));
} else {
// in android version lower than M your method must work
photo = data.getParcelableExtra("data");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
uploadImage(photo);
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void uploadImage(Bitmap photo) {
if (photo == null) {
LogUtils.d("裁剪后的photo为空");
return;
}
//存到本地
FileOutputStream b = null;
File file = new File(Config.LOCAL_PORTRAIT_CUT_PATH);
if (!file.exists()) {
file.mkdirs();// 创建文件夹
} else {
//删除文件夹下所有文件
CommonUtils.deleteFile(file);
}
localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
String fileName = Config.LOCAL_PORTRAIT_CUT_PATH + localTempImgFileName;
try {
b = new FileOutputStream(fileName);
photo.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
b.flush();
b.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 上传photo到服务器,再通过更新用户信息接口上传成用户头像,再保存到本地
Map params = new HashMap<>();
params.put("imgType", "live_image");
params.put("oss", true);
HttpU.getInstance().uploadImages(EditUserInfoActivity.this,
Config.UPLOAD_IMG,
params,
new File(fileName).getAbsolutePath(),
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
LogUtils.d("EditUserInfoActivity_upload_portroit:" + response);
try {
HttpResult result = JSON.parseObject(response, HttpResult.class);
if (result != null && result.isSuc()) {
String rs = result.getRs();
//调用接口更新用户数据
Map updateParams = new HashMap<>();
updateParams.put("headUrl", rs);
HttpU.getInstance().post(EditUserInfoActivity.this,
Config.UPDATE_USER,
updateParams,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
LogUtils.d("EditUserInfoActivity_updateuserinfo_portroit" + response);
HttpResult updateResult = JSON.parseObject(response, HttpResult.class);
if (updateResult != null && updateResult.isSuc()) {
//更新用户数据成功,此时刷新用户数据
HttpU.getInstance().post(EditUserInfoActivity.this,
Config.QUERY_USER,
null,
null,
new HttpCallback() {
@Override
public void onResponse(String response) {
LogUtils.d("EditUserInfoActivity_queryuserinfo_portroit" + response);
HttpResult queryResult = JSON.parseObject(response, HttpResult.class);
if (queryResult != null && queryResult.isSuc()) {
//更新userinfo
//放到本地的图片地址是补全的
UserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);
String portroit = Config.IMGHEADER + userInfo.getHeadUrl();
userInfo.setHeadUrl(portroit);
UserInfoManager.getInstance(EditUserInfoActivity.this).saveUserInfo(userInfo);
//更新头像
Glide.with(EditUserInfoActivity.this).load(userInfo.getHeadUrl())
.into(civ_userhead_edituserinfo);
//设置数据已经更新标志
isupdate = true;
//关闭幕布和弹框
ifShowChooseLayout(false);
}
}
}
);
}
}
}
);
}
} catch (Exception e) {
e.printStackTrace();
LogUtils.d("recommend-d:" + e);
}
}
}
);
}
//截取图片
public void cropImage(Uri uri, int outputX, int outputY, int requestCode) {
//裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
//裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//裁剪后输出图片的尺寸大小
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
//图片格式
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);
startActivityForResult(intent, requestCode);
}
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
}
@Override
public void onBackPressed() {
if (ifshowchooselayout) {
ifShowChooseLayout(false);
} else {
Intent intent = new Intent();
intent.putExtra("isupdate", isupdate);
EditUserInfoActivity.this.setResult(RESULT_OK, intent);
EditUserInfoActivity.this.finish();
super.onBackPressed();
}
}
private void onRequestCamera(int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//启动照相机
getPortraitByCamera();
} else {
//提示用户权限没有获取
ToastUtils.showToastTop(EditUserInfoActivity.this, "无法获取相机权限,请允许使用相机!");
}
}
private void onRequestWriteAndRead(int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initView();
initData();
} else {
//提示用户权限没有获取
ToastUtils.showToastTop(EditUserInfoActivity.this, "无法获取读写本地相册权限,请允许使用!");
}
}
}