此文章只为记录本人在开发中遇到的坑以及学到的知识,里面可能还是存在问题,如果有问题希望大家能指出来,谢谢!
1.拍照
拍照需要适配7.0和7.0以下的手机,然后还需要申请相机和SD卡的读写权限。这次没有用到裁剪的功能,所以该文章中没有裁剪代码。
7.0及以上的手机需要用到provider。
第一步 在application中定义provider
<provider android:name="android.support.v4.content.FileProvider"//固定值 android:authorities="com.weconex.maanshancitizencard.fileprovider"//包名加上.fileprovider android:exported="false"//是否支持其他应用调用当前组件,要求为false android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS"//固定值 android:resource="@xml/filepaths" />//在res目录下创建一个xml文件夹,创建xml文件,名字可以自定义 </provider>第二步 xml文件定义
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--相机相册裁剪-->
<root-path name="camera_no_sdcard" path=""/>//这里我是放在SD卡的根目录下,所以这里用root-path
</paths>
第三步 调用代码
1.初始化对象
mCameraFile = new File(Environment.getExternalStorageDirectory(), "cameraFile");//照相机的File对象 mGalleryFile = new File(Environment.getExternalStorageDirectory(), "imageGallery");//相册的File对象2.调用相机
Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//7.0及以上 Uri uriForFile = FileProvider.getUriForFile(context, "com.weconex.maanshancitizencard.fileprovider", file); intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, uriForFile); intentFromCapture.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intentFromCapture.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } else { intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); } fragment.startActivityForResult(intentFromCapture, code);3.处理拍照后的回调
通过mCameraFile.getPath()方法可以得到拍照后得到的图片地址。这里需要对图片进行压缩处理,否则会报异常。
2.从相册中获取图片
1.调用相册
这里需要对7.0及以上、7.0以下4.4及以上和4.4以下进行适配。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//如果大于等于7.0使用FileProvider Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); Uri uriForFile = FileProvider.getUriForFile(context, "com.weconex.maanshancitizencard.fileprovider", mGalleryFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, uriForFile); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); fragment.startActivityForResult(intent, code7); } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//7.0以下,4.4以上 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); fragment.startActivityForResult(intent, code); }else{//4.4以下 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); fragment.startActivityForResult(intent, code); }2.处理相册的回调
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//4.4以上 return ImageUtils.zoomImage(getPath(context,data.getData()));//这里要解决分水岭问题,在getPath()方法中实现了 }else{//4.4以下 Uri selectedImage = data.getData(); //获取系统返回的照片的Uri String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor =context.getContentResolver().query(selectedImage, filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片 cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); //获取照片路径 cursor.close(); return ImageUtils.zoomImage(picturePath); }4.4及以上的手机获取的图片面临这分水岭问题,可以通过以下代码来解决
@TargetApi(Build.VERSION_CODES.KITKAT) private String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, 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(context, 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(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, 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 context The context. * @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(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); 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()); }完成。