Android 单选图片,一个dialog全部搞定

来源:互联网 发布:ab nginx压力测试 编辑:程序博客网 时间:2024/06/04 17:55

一:为什么写这个文章?

相信大家对图片选择已经不陌生了,大家基本一直都在用。但是假如你在选择图片的时候遇到,反应比较慢。Android 7.0选择图片时闪退的问题。你不妨花几分钟往下看下。

随着相机像素越来越高,手机拍照获取到的照片越来越大,这就需要我们在选择照片时处理好内存溢出的问题。于是出现了选择照片时保存图片的本地路径,上传时在转换为需要的格式。但是,安卓7.0在选择图片时获取到的路径不是在file文件夹下,而是在content下。好多人都获取不好正确的路径。于是网上就有了使用previder这样的方法获取图片的文章。本篇文章是在结合以上两点的情况下,把选择图片的所有逻辑全部封装在一个dialog中。让大家在使用的时候尽可能的方便。

二:开始正题


先给dialog


/** * 选择单张照片的dialog,是否裁剪可设置,裁剪尺寸目前没有做,可自己添加 */public class ChoseSingleImgDialog extends Dialog implements        View.OnClickListener {    private String title = "";    private Activity activity;    private int cameraRequestCode;    private int cutRequestCode;    private int selectRequestCode;    private boolean cut;    //动态获取权限监听    private static PermissionListener mListener;    private TextView tv_chose_single_img_title;    private TextView btn_chose_single_img_camera;    private TextView btn_chose_single_img_chose;    private Button btn_chose_single_img_cancel;    private Fragment fragment;    private String imageName;    private File cacheFile;//裁剪后的地址    private File cameraFile;//相机文件    private Uri imageUri;    private  String cachPath;    /**     * @param activity     * @param title             标题     * @param cameraRequestCode 相机图片请求码     * @param selectRequestCode 相册图片请求     * @param cutRequestCode    图片裁剪请求码     * @param imageName         图片名     * @param cut               是否剪切     */    public ChoseSingleImgDialog(Fragment fragment, Activity activity, String title, int cameraRequestCode, int selectRequestCode, int cutRequestCode, String imageName, boolean cut) {        super(activity, R.style.Dialog_boc);        this.activity = activity;        this.title = title;        this.cameraRequestCode = cameraRequestCode;        this.selectRequestCode = selectRequestCode;        this.cutRequestCode = cutRequestCode;        this.imageName = imageName;        this.fragment = fragment;        this.cut = cut;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //改变导航栏的颜色        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);        }        setContentView(R.layout.dialog_chose_single_img);        Window window = this.getWindow();        window.setGravity(Gravity.BOTTOM);        // window.setWindowAnimations(R.style.dialogAnimation);        initView();    }    private void initView() {        long time = Calendar.getInstance().getTime().getTime();        cachPath=getDiskCacheDir(activity)+ "/"+time+"crop_image.jpg";        cacheFile =getCacheFile(new File(getDiskCacheDir(activity)), time +"crop_image.jpg");        // TODO Auto-generated method stub        tv_chose_single_img_title = (TextView) findViewById(R.id.tv_chose_single_img_title);        btn_chose_single_img_camera = (TextView) findViewById(R.id.btn_chose_single_img_camera);        btn_chose_single_img_chose = (TextView) findViewById(R.id.btn_chose_single_img_chose);        btn_chose_single_img_cancel = (Button) findViewById(R.id.btn_chose_single_img_cancel);        tv_chose_single_img_title.setText(title);        btn_chose_single_img_camera.setOnClickListener(this);        btn_chose_single_img_chose.setOnClickListener(this);        btn_chose_single_img_cancel.setOnClickListener(this);    }    @Override    public void onClick(View v) {        // TODO Auto-generated method stub        switch (v.getId()) {            case R.id.btn_chose_single_img_camera://相机                getFromCamera();                break;            case R.id.btn_chose_single_img_chose://相册选择                getFromSelect();                break;            case R.id.btn_chose_single_img_cancel:                dismiss();                break;            default:                break;        }        dismiss();    }    /**     * 动态监听权限     */    private void getFromSelect() {        String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};        requestRuntimePermission(permissions, new PermissionListener() {            @Override            public void onGranted() {                openAlbum();            }            @Override            public void onDenied(List<String> deniedPermission) {                //没有获取到权限,什么也不执行,看你心情                OFBApplication.setToast("没有权限");            }        });    }    /**     * 打开相册,选择照片     */    private void openAlbum() {        Intent intent = new Intent("android.intent.action.GET_CONTENT");        intent.setType("image/*");        activity.startActivityForResult(intent, selectRequestCode); // 打开相册    }    /**     * 动态监听相机等权限     */    private void getFromCamera() {        //openCamera();        String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};        requestRuntimePermission(permissions, new PermissionListener() {            @Override            public void onGranted() {                openCamera();            }            @Override            public void onDenied(List<String> deniedPermission) {                //有权限被拒绝,什么也不做好了,看你心情                OFBApplication.setToast("您已经拒绝拍照权限");            }        });    }    /**     * 打开相机拍照     */    private void openCamera() {        cameraFile = getCacheFile(new File(getDiskCacheDir(activity)), imageName);        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        if (Build.VERSION.SDK_INT < 24) {//7.0以下,直接获取到Uri            imageUri = Uri.fromFile(cameraFile);        } else {//7.0使用fileprovider获取Uri            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);            imageUri = FileProvider.getUriForFile(activity, "com.xlk.onefootball.fileprovider", cameraFile);        }        // 启动相机程序        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);        activity.startActivityForResult(intent, cameraRequestCode);    }    /**     * 创建File对象,用于存储拍照后的图片     *     * @param parent     * @param child     * @return     */    private File getCacheFile(File parent, String child) {        // 创建File对象,用于存储拍照后的图片        File file = new File(parent, child);        if (file.exists()) {            file.delete();        }        try {            file.createNewFile();        } catch (IOException e) {            e.printStackTrace();        }        return file;    }    /**     * 获取图片路径     *     * @param context     * @return     */    public String getDiskCacheDir(Context context) {        String cachePath = null;        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())                || !Environment.isExternalStorageRemovable()) {            cachePath = context.getExternalCacheDir().getPath();        } else {            cachePath = context.getCacheDir().getPath();        }        return cachePath;    }    public String onActivityResult(int requestCode, int resultCode,                                Intent data, ImageView imageView) {        String uri = null;        // 从相册中去图片当resultcode == -1表示以选择0时没有选者        if (requestCode == selectRequestCode && resultCode == Activity.RESULT_OK) {//从相册选择            if (cut) {                // 判断手机系统版本号                if (Build.VERSION.SDK_INT >= 19) {                    // 4.4及以上系统使用这个方法处理图片                    OFBApplication.LogData("获取到4.4以上的图片",data.toString());                    handleImageOnKitKat(data);                } else {                    // 4.4以下系统使用这个方法处理图片                    OFBApplication.LogData("获取到4.4以下的图片",data.toString());                    handleImageBeforeKitKat(data);                }            } else {                if (Build.VERSION.SDK_INT >= 19) {                    // 4.4及以上系统使用这个方法处理图片                    Uri uri_temp = data.getData();                    String imagePath = uriToPath(uri_temp);                    File file_temp = new File(imagePath);                    uri = Uri.fromFile(file_temp)+"";                    OFBApplication.LogData("不裁剪相册",uri);                    GlideUtils.setImage(activity,uri,imageView);                } else {                    // 4.4以下系统使用这个方法处理图片                    Uri uri_temp = data.getData();                    String imagePath = getImagePath(uri_temp, null);                    File file_temp = new File(imagePath);                    uri = Uri.fromFile(file_temp)+"";                    OFBApplication.LogData("不裁剪相册",uri);                    GlideUtils.setImage(activity,uri,imageView);                }            }        }else if (requestCode == cameraRequestCode && resultCode == Activity.RESULT_OK) {//拍照            if (cut) {                try {                    // 将拍摄的照片显示出来                    OFBApplication.LogData("获取到相机文件",cameraFile.getAbsolutePath());                    startPhotoZoom(cameraFile, 350);                } catch (Exception e) {                    e.printStackTrace();                }            } else {                //uri = uriToPath(Uri.fromFile(cameraFile));                uri = Uri.fromFile(cameraFile)+"";                OFBApplication.LogData("不裁剪相机",uri);                GlideUtils.setImage(activity,uri,imageView);            }        }else if (requestCode == cutRequestCode && resultCode == Activity.RESULT_OK) {//裁剪            try {                uri = Uri.fromFile(new File(cachPath))+"";                GlideUtils.setImage(activity,cachPath,imageView);            } catch (Exception e) {                e.printStackTrace();            }        }        return uri;    }    /**     * 剪裁图片     */    private void startPhotoZoom(File file, int size) {        OFBApplication.LogData("TAG",getImageContentUri(activity,file)+"裁剪照片的真实地址");        try {            Intent intent = new Intent("com.android.camera.action.CROP");            intent.setDataAndType(getImageContentUri(activity,file), "image/*");//自己使用Content Uri替换File Uri            intent.putExtra("crop", "true");            intent.putExtra("aspectX", 1);            intent.putExtra("aspectY", 1);            intent.putExtra("outputX", 180);            intent.putExtra("outputY", 180);            intent.putExtra("scale", true);            intent.putExtra("return-data", false);            intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(cacheFile));//定义输出的File Uri            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());            intent.putExtra("noFaceDetection", true);            if (fragment != null) {                fragment.startActivityForResult(intent, cutRequestCode);            } else {                activity.startActivityForResult(intent, cutRequestCode);            }        } catch (ActivityNotFoundException e) {            String errorMessage = "Your device doesn't support the crop action!";            Toast.makeText(activity, errorMessage, Toast.LENGTH_LONG).show();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 4.4以上的图片     * @param data     */    @TargetApi(19)    private void handleImageOnKitKat(Intent data) {        Uri uri = data.getData();        OFBApplication.LogData("TAG", "handleImageOnKitKat: uri is " + uri);        String imagePath= uriToPath(uri);//        displayImage(imagePath); // 根据图片路径显示图片        OFBApplication.LogData("TAG","file://"+imagePath+"选择图片的URI"+uri);        startPhotoZoom(new File(imagePath),350);    }    /**     * 4.4以下图片处理     * @param data     */    private void handleImageBeforeKitKat(Intent data) {        Uri uri = data.getData();        String imagePath = getImagePath(uri, null);//        displayImage(imagePath);        OFBApplication.LogData("TAG","file://"+imagePath+"选择图片的URI"+uri);        startPhotoZoom(new File(imagePath),350);    }    /**     * Uri转Path     * @param uri     * @return     */    private String uriToPath(Uri uri) {        String path=null;        if (DocumentsContract.isDocumentUri(activity, uri)) {            // 如果是document类型的Uri,则通过document id处理            String docId = DocumentsContract.getDocumentId(uri);            if("com.android.providers.media.documents".equals(uri.getAuthority())) {                String id = docId.split(":")[1]; // 解析出数字格式的id                String selection = MediaStore.Images.Media._ID + "=" + id;                path = 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));                path = getImagePath(contentUri, null);            }        } else if ("content".equalsIgnoreCase(uri.getScheme())) {            // 如果是content类型的Uri,则使用普通方式处理            path = getImagePath(uri, null);        } else if ("file".equalsIgnoreCase(uri.getScheme())) {            // 如果是file类型的Uri,直接获取图片路径即可            path = uri.getPath();        }        return  path;    }    /**     * 获取图片路径     * @param uri     * @param selection     * @return     */    private String getImagePath(Uri uri, String selection) {        String path = null;        // 通过Uri和selection来获取真实的图片路径        Cursor cursor = activity.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;    }    /**     * 获取ContentUri  7.0特有     * @param context     * @param imageFile     * @return     */    public static Uri getImageContentUri(Context context, File imageFile) {        String filePath = imageFile.getAbsolutePath();        Cursor cursor = context.getContentResolver().query(                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,                new String[]{MediaStore.Images.Media._ID},                MediaStore.Images.Media.DATA + "=? ",                new String[]{filePath}, null);        if (cursor != null && cursor.moveToFirst()) {            int id = cursor.getInt(cursor                    .getColumnIndex(MediaStore.MediaColumns._ID));            Uri baseUri = Uri.parse("content://media/external/images/media");            return Uri.withAppendedPath(baseUri, "" + id);        } else {            if (imageFile.exists()) {                ContentValues values = new ContentValues();                values.put(MediaStore.Images.Media.DATA, filePath);                return context.getContentResolver().insert(                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);            } else {                return null;            }        }    }    //andrpoid 6.0 需要写运行时权限    public void requestRuntimePermission(String[] permissions, PermissionListener listener) {        mListener = listener;        List<String> permissionList = new ArrayList<>();        for (String permission : permissions) {            if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {                permissionList.add(permission);            }        }        if (!permissionList.isEmpty()) {            ActivityCompat.requestPermissions(activity, permissionList.toArray(new String[permissionList.size()]), 1);        } else {            mListener.onGranted();        }    }    public interface PermissionListener {        /**         * 成功获取权限         */        void onGranted();        /**         * 为获取权限         *         * @param deniedPermission         */        void onDenied(List<String> deniedPermission);    }}



用法:

public class MainActivity extends Activity {    ChoseSingleImgDialog choseSingleImgdialog;    ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        iv = (ImageView) findViewById(R.id.iv_main);        findViewById(R.id.btn_main_choseIMG).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                choseSingleImgdialog = new ChoseSingleImgDialog(null, MainActivity.this, "选择图片", 100, 101, 102, "head.jpg", true);                choseSingleImgdialog.show();            }        });    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (choseSingleImgdialog != null) {            //拿到图片路径,想干嘛随你            String url = choseSingleImgdialog.onActivityResult(requestCode, resultCode, data, iv);            OFBApplication.setToast("图片路径是"+url);            choseSingleImgdialog.dismiss();        }else{            OFBApplication.setToast("失败了");        }    }}


具体使用中要用到glide,和一个previder。感兴趣的可以去看Android 7.0选择图片,获取路径的博客。或者直接下载源码。

源码链接:https://github.com/MoJieBlog/choseSingleIMG

2 0
原创粉丝点击