最近的项目,后续会独立出一个demo,下面贴出代码,有一些代码是弹出popupwindow等业务的大家忽略,有时间会精简一下,可以直接从
takePhoto()和selectPhoto()看起,要注意的地方主要是SDK4.4不一样的文件URI读取方法和URI相关权限获取部分
package com.gsww.unify.ui.personalcenter; import android.annotation.TargetApi; import android.content.ContentUris; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.v4.content.FileProvider; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Button; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; import com.gsww.unify.R; import com.gsww.unify.ui.BaseActivity; import com.gsww.unify.utils.Cache; import com.gsww.unify.utils.Constants; import com.gsww.unify.utils.JSONUtil; import com.gsww.unify.utils.Logger; import com.gsww.unify.utils.NetworkHelper; import com.gsww.unify.utils.StringHelper; import com.gsww.unify.view.CustomProgressDialog; import com.gsww.unify.view.RoundImageView; import net.tsz.afinal.FinalHttp; import net.tsz.afinal.http.AjaxCallBack; import net.tsz.afinal.http.AjaxParams; import org.apache.commons.lang.StringUtils; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import static com.gsww.unify.view.ImageViewUtil.getBitmapsize; public class SettingActivity extends BaseActivity { @BindView(R.id.head_picture_iv) RoundImageView headPictureIv; @BindView(R.id.user_name_tv) TextView userNameTv; Uri imageUri;//拍照照片Uri Uri imageUriCrop;//裁剪照片Uri public static final int TAKE_PHOTO = 1;//拍照 public static final int SELECT_PHOTO = 2;//从相册选取 public static final int PHOTO_CROP = 102011;//裁剪相片 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); ButterKnife.bind(this); init(); } void init() { initTopPanel(R.id.topPanel, R.string.setting, Constants.RIGHT_TYPE_HIDDEN, Constants.LEFT_TYPE_BACK); String headUrl = ""; if (StringHelper.isNotBlank(Cache.HEAD_URL)) { headUrl = Cache.HEAD_URL + "_press"; } headPictureIv.setTag(headUrl); loadImage(headPictureIv); } @Override protected void onResume() { super.onResume(); userNameTv.setText(Cache.USER_NAME); } @OnClick({R.id.head_picture_ll, R.id.user_name_ll, R.id.personaldata_ll, R.id.identity_authentication_ll, R.id.change_psw_ll, R.id.exit_login_bt}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.head_picture_ll: initPopupWindow(); break; case R.id.user_name_ll: break; case R.id.personaldata_ll: startActivity(new Intent(this, PersonalDataActivity.class)); break; case R.id.identity_authentication_ll: startActivity(new Intent(this, VerificationIdentityActivity.class)); break; case R.id.change_psw_ll: startActivity(new Intent(this, ChangePasswordActivity.class)); break; case R.id.exit_login_bt: logoff(); finish(); break; } } /** * 拍照获取图片 **/ public void take_photo() { //创建File对象,用于存储拍照后的图片 File outputImage = new File(this.getExternalCacheDir(), "output_image.jpg"); File outputImageCrop = new File(this.getExternalCacheDir(), "output_image_crop.jpg"); try { if (outputImage.exists()) { outputImage.delete(); } outputImage.createNewFile(); if (outputImageCrop.exists()) { outputImageCrop.delete(); } outputImageCrop.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (Build.VERSION.SDK_INT >= 24) { imageUri = FileProvider.getUriForFile(this, "com.gsww.unify", outputImage); imageUriCrop = FileProvider.getUriForFile(this, "com.gsww.unify", outputImageCrop); } else { imageUri = Uri.fromFile(outputImage); imageUriCrop = Uri.fromFile(outputImageCrop); } //启动相机程序 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, TAKE_PHOTO); } /** * 从相册中获取图片 */ public void select_photo() { //创建File对象,用于存储拍照后的图片 File outputImageCrop = new File(this.getExternalCacheDir(), "output_image_crop.jpg"); try { if (outputImageCrop.exists()) { outputImageCrop.delete(); } outputImageCrop.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (Build.VERSION.SDK_INT >= 24) { imageUriCrop = FileProvider.getUriForFile(this, "com.gsww.unify", outputImageCrop); } else { imageUriCrop = Uri.fromFile(outputImageCrop); } openAlbum(); // } } /** * 打开相册的方法 */ private void openAlbum() { Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent, SELECT_PHOTO); } /** * 添加新笔记时弹出的popWin关闭的事件,主要是为了将背景透明度改回来 */ class popupDismissListener implements PopupWindow.OnDismissListener { @Override public void onDismiss() { backgroundAlpha(1f); } } PopupWindow popupWindow; protected void initPopupWindow() { View popupWindowView = LayoutInflater.from(this).inflate( R.layout.view_photo_picture_chose, null); //内容,高度,宽度 popupWindow = new PopupWindow(popupWindowView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); //动画效果 popupWindow.setAnimationStyle(R.style.AnimationBottomFade); //菜单背景色 ColorDrawable dw = new ColorDrawable(0xffffffff); popupWindow.setBackgroundDrawable(dw); //显示位置getWindow().getDecorView()获取最上层VIEW popupWindow.showAtLocation(getWindow().getDecorView(), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); //设置背景半透明 backgroundAlpha(0.5f); //关闭事件 popupWindow.setOnDismissListener(new popupDismissListener()); popupWindowView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { /*if( popupWindow!=null && popupWindow.isShowing()){ popupWindow.dismiss(); popupWindow=null; }*/ // 这里如果返回true的话,touch事件将被拦截 // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss return false; } }); Button take_photo = (Button) popupWindowView.findViewById(R.id.take_photo); final Button select_photo = (Button) popupWindowView.findViewById(R.id.select_photo); Button cancel = (Button) popupWindowView.findViewById(R.id.cancel); take_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { take_photo(); popupWindow.dismiss(); } }); select_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { select_photo(); popupWindow.dismiss(); } }); cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { popupWindow.dismiss(); } }); } /** * 设置添加屏幕的背景透明度 * * @param bgAlpha */ public void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = SettingActivity.this.getWindow().getAttributes(); lp.alpha = bgAlpha; //0.0-1.0 SettingActivity.this.getWindow().setAttributes(lp); } /** * 4.4以下系统处理图片的方法 */ private void handleImageBeforeKitKat(Intent data) { Uri uri = data.getData(); String imagePath = getImagePath(uri, null); displayImage(imagePath); } /** * 4.4及以上系统处理图片的方法 */ @TargetApi(Build.VERSION_CODES.KITKAT) private void handleImgeOnKitKat(Intent data) { String imagePath = null; Uri uri = data.getData(); if (DocumentsContract.isDocumentUri(SettingActivity.this, uri)) { //如果是document类型的uri,则通过document id处理 String docId = DocumentsContract.getDocumentId(uri); if ("com.android.providers.media.documents".equals(uri.getAuthority())) { //解析出数字格式的id String id = docId.split(":")[1]; String selection = MediaStore.Images.Media._ID + "=" + id; imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection); } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId)); imagePath = getImagePath(contentUri, null); } else if ("content".equalsIgnoreCase(uri.getScheme())) { //如果是content类型的uri,则使用普通方式处理 imagePath = getImagePath(uri, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) { //如果是file类型的uri,直接获取图片路径即可 imagePath = uri.getPath(); } //根据图片路径显示图片 displayImage(imagePath); } } /** * 根据图片路径显示图片的方法 */ private void displayImage(String imagePath) { if (imagePath != null) { photoCrop(Uri.parse("file://" + Uri.parse(imagePath))); } else { Toast.makeText(SettingActivity.this, "failed to get image", Toast.LENGTH_LONG).show(); } } /** * 通过uri和selection来获取真实的图片路径 */ private String getImagePath(Uri uri, String selection) { String path = null; Cursor cursor = SettingActivity.this.getContentResolver().query(uri, null, selection, null, null); if (cursor != null) { if (cursor.moveToFirst()) { path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; } /** * 上传 */ public void upLoad(Bitmap image) { List<Bitmap> list = new ArrayList<>(); list.add(image); List<File> fileList; fileList = saveBitmapFile(list);//压缩储存 try { final File file = fileList.get(0); if (NetworkHelper.isConnected(SettingActivity.this)) { progressDialog = CustomProgressDialog.show(SettingActivity.this, "", "图像上传中,请稍候...", true); AjaxParams params = new AjaxParams(); if (StringUtils.isBlank(Cache.USER_ID)) { loadCache(); } params.put("userId", Cache.USER_ID); params.put("bizId", Cache.USER_ID); params.put("bizCode", "81"); params.put("orgId", Cache.USER_ORG_ID); try { params.put("uploads", file); params.put("uploadsFileName", file.getName()); FinalHttp fh = new FinalHttp(); String url = com.gsww.unify.utils.Configuration.getUploadUrl(); fh.configTimeout(60000); fh.post(url, params, new AjaxCallBack<String>() { @Override public void onLoading(long count, long current) { } @Override public void onSuccess(String t) { super.onSuccess(t); if (progressDialog != null) { progressDialog.dismiss(); } Map resMap = JSONUtil.readJsonMap(t); final String fileUrl = String.valueOf(resMap.get("fileUrl")); if (StringUtils.isNotBlank(fileUrl)) { showToast("图片上传成功~"); //更新缓存中fileURL Map<String, Object> userInfoMap = Cache.USER_INFO; userInfoMap.put("fileUrl", fileUrl); Cache.HEAD_URL = fileUrl; Map<String, Object> userBasicInfo = new HashMap<>(); userBasicInfo.put(Constants.USER_INFO, JSONUtil.writeMapJSON(userInfoMap)); savaInitParams(userInfoMap); headPictureIv.setTag(fileUrl + "_press"); loadImage(headPictureIv); } } @Override public void onFailure(Throwable t, int errorNo, String strMsg) { if (progressDialog != null) { progressDialog.dismiss(); } showToast("图片上传失败!" + strMsg); } }); } catch (Exception e) { Logger.info(e); } // 上传文件 } else { showToast("亲,您的网络未连接,请先连接网络!"); } } catch (Exception e) { e.printStackTrace(); } } public List<File> saveBitmapFile(List<Bitmap> list) { List<File> fileList = new ArrayList<File>(); try { for (Bitmap bitmap : list) { String fileName = String.valueOf(System.currentTimeMillis()); File rootFile = new File( Environment.getExternalStorageDirectory(), "/jzfp/images/"); if (!rootFile.exists()) { rootFile.mkdirs(); } File file = new File(Environment.getExternalStorageDirectory() + "/jzfp/images/" + fileName + ".jpg"); if (!file.exists()) { file.createNewFile(); } BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(file)); if (getBitmapsize(bitmap) / 1024 <= 200) { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); } else if (getBitmapsize(bitmap) / 1024 >= 200 && getBitmapsize(bitmap) / 1024 < 1024) { bitmap.compress(Bitmap.CompressFormat.JPEG, 60, bos); } else if (getBitmapsize(bitmap) / 1024 >= 1024 && getBitmapsize(bitmap) / 1024 < 2048) { bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bos); } else if (getBitmapsize(bitmap) / 1024 >= 2048 && getBitmapsize(bitmap) / 1024 < 4096) { bitmap.compress(Bitmap.CompressFormat.JPEG, 12, bos); } else { bitmap.compress(Bitmap.CompressFormat.JPEG, 10, bos); } bos.flush(); bos.close(); fileList.add(file); } return fileList; } catch (IOException e) { Logger.info(e); } return fileList; } /** * 裁剪图片方法实现 * * @param uri */ public void photoCrop(Uri uri) { 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("outputX", 700); intent.putExtra("outputY", 700); intent.putExtra("return-data", false); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //授予URI相关权限 List resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); Iterator resInfoIterator = resInfoList.iterator(); while (resInfoIterator.hasNext()) { ResolveInfo resolveInfo = (ResolveInfo) resInfoIterator.next(); String packageName = resolveInfo.activityInfo.packageName; grantUriPermission(packageName, imageUriCrop, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); grantUriPermission(packageName, imageUriCrop, Intent.FLAG_GRANT_READ_URI_PERMISSION); } intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUriCrop); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, PHOTO_CROP); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case TAKE_PHOTO: if (resultCode == RESULT_OK) { try { photoCrop(imageUri); } catch (Exception e) { e.printStackTrace(); } } break; case SELECT_PHOTO: if (resultCode == RESULT_OK) { //判断手机系统版本号 if (Build.VERSION.SDK_INT > 19) { //4.4及以上系统使用这个方法处理图片 handleImgeOnKitKat(data); } else { handleImageBeforeKitKat(data); } } break; case PHOTO_CROP: if (resultCode == RESULT_OK) { try { Bitmap bitmap = BitmapFactory.decodeStream(SettingActivity.this.getContentResolver().openInputStream(imageUriCrop)); upLoad(bitmap); } catch (Exception e) { e.printStackTrace(); } } break; default: break; } } }