在实习期遇到的问题,小组长叫找头像上传的bug,偶然了解了一下,在这里记录一下,当然代码不是我写的,只是记一下,日后遇到可以看一下。
功能描述:
1.调用相机拍照,选好拍照的照片进行裁剪,将头像进行上传
2.从图库里选择所要上传的照片,裁剪,将头像上传
步骤:(针对Android4.4以上的版本)
1.先获取拍照权限,读取SD卡权限
2.创建一个文件夹用于保存图片
3.调用系统的相机或者图片,获取图片的URI
4.根据URI获取图片
功能描述:
1.调用相机拍照,选好拍照的照片进行裁剪,将头像进行上传
2.从图库里选择所要上传的照片,裁剪,将头像上传
步骤:(针对Android4.4以上的版本)
1.先获取拍照权限,读取SD卡权限
2.创建一个文件夹用于保存图片
3.调用系统的相机或者图片,获取图片的URI
4.根据URI获取图片
5.采用系统的裁剪方法,裁剪图片
获取相关权限
/** * 检查相机权限 * @return */ protected boolean checkCameraPermission(){ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){ checkPermission(REQUEST_CODE_CAMERA, Manifest.permission.CAMERA); return false; } return true; } /** * 检查SDCard权限 * @return */ protected boolean checkSDCardPermission(){ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ checkPermission(REQUEST_CODE_SD_CARD, Manifest.permission.WRITE_EXTERNAL_STORAGE); return false; } return true; }
/** * 请求权限 * * @param permission */ public final boolean checkPermission(int requestCode, String permission) { if (ActivityCompat.checkSelfPermission(getBaseContext(), permission) == PackageManager.PERMISSION_GRANTED) return true; ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode); return false; }权限获取成功在onRequestPermissionsResult方法里处理,可以直接重写
权限在被用户拒绝获取该权限时,并同时选中不再提醒此类消息的复选框下,二次申请权限时,重写shouldShowRequestPermissionRationale
方法,设置Intent动作Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); startActivity(intent);跳转到系统的权限设置页进行设置权限。
创建保存图片的文件夹
/** * 创建保存图片的文件夹 */ private void createPhotoFolder(){ if (!new File(Constant.DIR_PHOTO).exists()){ new File(Constant.DIR_PHOTO).mkdirs(); } }打开相机/** * 拍照 */ public void openCamera() { if (!checkSDCardPermission()) return; if (!checkCameraPermission()) return; createPhotoFolder(); Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 指定调用相机拍照后照片的储存路径 mTempFile = new File(Constant.DIR_PHOTO, getPhotoFileName()); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile)); //指定清晰度 cameraIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); startActivityForResult(cameraIntent, REQUEST_CODE_TAKE_PHOTO); }设置拍照后的照片文件名,根据时间生成唯一文件名public String getPhotoFileName() { Date date = new Date(System.currentTimeMillis()); SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss"); return dateFormat.format(date) + ".jpg"; }/** * 手机相册 */ @TargetApi(Build.VERSION_CODES.KITKAT) public void openAlbum() { if (!checkSDCardPermission()) return; createPhotoFolder();Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, REQUEST_CODE_PIC_PHOTO); }裁剪图片private void startPhotoZoom(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // crop为true是设置在开启的intent中设置显示的view可以剪裁 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX,outputY 是剪裁图片的宽高 intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); intent.putExtra("return-data", true); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, REQUEST_CODE_PHOTO_CROP); }Android4.4以上的图片的URI处理比较麻烦,具体以下下面的给出解析地址,两位大神已经写得很好了点击打开链接点击打开链接/** * 获取Uri的path路径 * @param uri * @return */ private String getUriPath(Uri uri) { // DocumentProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(this, uri)){ // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ private String getDataColumn(Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String[] projection = { MediaStore.MediaColumns.DATA }; try { cursor = getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ private boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ private boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ private boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ private boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } /** * 得到裁剪后的图片 * @param imagePath 图片的sd卡路径 * @param fileName */ public void doBackgroundImage(String imagePath, String fileName, Bitmap bitmap){ }在onActivityResult对各种消息进行处理
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) return; switch (requestCode){ case REQUEST_CODE_PIC_PHOTO://手机相册 Uri uri = data.getData(); // String path = PhotoUtil.getAblumPicPath(this, data); String path = getUriPath(uri); if (!TextUtils.isEmpty(path)){ mTempFile = new File(path); // startPhotoZoom(uri); startPhotoZoom(Uri.fromFile(mTempFile)); } else { showToast("获取手机相册图片失败。"); } break; case REQUEST_CODE_TAKE_PHOTO://拍照 startPhotoZoom(Uri.fromFile(mTempFile)); break; case REQUEST_CODE_PHOTO_CROP://裁剪 if (data == null) return; Bundle bundle = data.getExtras(); if (bundle == null) return; Bitmap bmp = bundle.getParcelable("data"); if (bmp == null) return; String imagePath = Constant.DIR_PHOTO + mTempFile.getName(); FileUtil.SavePicInSdcard(bmp, imagePath, true); String fileName = mTempFile.getName(); doBackgroundImage(imagePath, fileName, bmp); break; } }