android 系统自带图片选择器和截图

1.图片路径处理类

public class UriUtil {

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static 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];
                }
                // TODO handle non-primary volumes
            }
            // 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);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isGooglePhotosUri(uri)) {
                return uri.getLastPathSegment();
            }
            return getDataColumn(context, uri, null, null);
        } 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.
     */
    public static 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.
     */
    public static 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.
     */
    public static 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.
     */
    public static 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.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
}

2.图片选择和裁剪工具类

/**
 * 调用android原生图片选择器(包括系统裁剪)
 * @author gyq
 */
public class PhotoSelectUtil {
    public static final int SELECT_PHOTO = 1;
    public static final int CROP_PHOTO = 2;


    private Activity activity;

    private Uri resultUri = null;
    private File cropImageFile = null;


    public PhotoSelectUtil(Activity activity) {
        this.activity = activity;
    }

    /***
     * 从相册中选取图片
     */
    public void pickPhoto() {
        try {
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("image/*");
                activity.startActivityForResult(intent, SELECT_PHOTO);
            } else {
                //Intent.ACTION_GET_CONTENT 好像没啥区别
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/*");
                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                activity.startActivityForResult(intent, SELECT_PHOTO);
            }
        } catch (Exception e) {
            activity.finish();
        }
    }

    /**
     * 在Activity的onActivityResult中调用,此方法后面调用super.onActivityResult(requestCode, resultCode, data);
     * @param requestCode
     * @param resultCode
     * @param intent
     * @param cropAspectX 宽高比
     * @param cropAspectY
     * @param cropOutputX 截图的宽高
     * @param cropOutputY
     */
    public void handleActivityResult(int requestCode, int resultCode, Intent intent,int cropAspectX,int cropAspectY,int cropOutputX,int cropOutputY) {
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case SELECT_PHOTO:
                    Uri photoUri = intent.getData();
                    startPhotoZoom(photoUri, cropAspectX, cropAspectY, cropOutputX, cropOutputY);
                    break;
                case CROP_PHOTO:
                    refreshSystemAlbum(cropImageFile);
                    // TODO: 2018/7/19 截图保存在cropImageFile中,可对截图做相应的操作
                    if (activity instanceof PhotoSelectTestActivity && cropImageFile != null) {
                        Bitmap bitmap = BitmapFactory.decodeFile(cropImageFile.getAbsolutePath());
                        if (bitmap != null) {
                            ((PhotoSelectTestActivity) activity).setCropImage(bitmap);
                        }
                    }
                    break;

                default:
                    break;

            }
        }
    }

    /**
     * 插入到系统相册,通知图库更新
     * @param cropImageFile
     */
    private void refreshSystemAlbum(File cropImageFile) {
        try {
            MediaStore.Images.Media.insertImage(activity.getContentResolver(),
                    cropImageFile.getAbsolutePath(), "CropImage.jpeg", null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(cropImageFile)));
    }

    /**
     * 选择图片后,获取图片的路径
     */
    private String getPicturePath(Uri photoUri) {
        String flag = "file";
        if (!photoUri.toString().contains(flag)) {
            return UriUtil.getPath(activity, photoUri);
        } else {
            return photoUri.getPath();
        }
    }


    /**
     * 调用系统自带截图
     * @param photoUri 选择图片后返回的uri
     * @param aspectX  裁剪图片的宽高比
     * @param aspectY
     * @param outputX  裁剪图片的宽高
     * @param outputY
     */
    private void startPhotoZoom(Uri photoUri, int aspectX, int aspectY, int outputX, int outputY) {
        final int VERSION_M = 24;
        String picPath = getPicturePath(photoUri);
        photoUri = Uri.parse(picPath);
        prepareResultUri();

        Intent intent = new Intent("com.android.camera.action.CROP");
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            try {
                Uri tempUri = null;
                //适配android 7.0以上版本
                if (Build.VERSION.SDK_INT >= VERSION_M) {
                    tempUri = FileProvider.getUriForFile(activity, "com.anke.app.activity.fileprovider", new File(picPath));
                    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    tempUri = Uri.fromFile(new File(picPath));
                }
                intent.setDataAndType(tempUri, "image/*");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            intent.setDataAndType(photoUri, "image/*");
        }

        intent.putExtra("crop", "true");
        // 图片的输出格式
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        //这里有个坑,如果截的是大图,那么截完后不会执行onActivityResult方法
        //intent.putExtra("return-data", true);
        // 设置剪切的图片保存位置,注意 resultUri 是由fromFile创建的
        intent.putExtra(MediaStore.EXTRA_OUTPUT, resultUri);
        activity.startActivityForResult(intent, CROP_PHOTO);

    }

    /**
     * 创建保存截图后的文件路径  resultUri 必须由Uri.fromFile创建,不然会提示无法保存经过裁剪的图片
     */
    private void prepareResultUri() {
        cropImageFile = new File(DataConstant.CROP_PICTURE_PATH);
        if (!cropImageFile.exists()) {
            cropImageFile.mkdirs();
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA);
        String filename = "IMG_" + dateFormat.format(new Date(System.currentTimeMillis())) + ".png";
        cropImageFile = new File(cropImageFile, filename);
        resultUri = Uri.fromFile(cropImageFile);
    }


}

3.用例

android 系统自带图片选择器和截图_第1张图片
在Activity中的简单调用

4.适配android 7.0

android 系统自带图片选择器和截图_第2张图片
在androidManifest中声明,注意声明的FileProvider不能和其他应用声明的一样
android 系统自带图片选择器和截图_第3张图片
在src/mian/res目录下,注意文件名字跟声明时一致

5.注意需要的权限声明

 

你可能感兴趣的:(android 系统自带图片选择器和截图)