android 拍照本本地选择图片上传

好久没有坐下来安安静静的写博客了 ,上一篇写的是自定义相机 ,以前项目中用过一些第三方的库 ,万物归终今天找个时间总结一下 ,做开发几年了 。随着android studio的运用,开源资源越来越多,越来越好用 ,但是使用第三方的开源代码,越来越不爽 ,很多库渐渐的丢下了 ,比如说EventBus ,刚开始的时候觉得好像神奇 ,用多了 。感觉代码不是很直观 ,就慢慢不用了 ,还是觉得自己写的回调接口好用。

  好了,不说废话了 ,一直以来开发平台都是RK芯片 5.0系统的,有时候也做一些APK ,上次出现的androdi7.0的问题,今天整理下 。拍照,选中本地图片,切割,老生常谈,无论使用开源,还是自定义 ,现在发现还是android系统提供的好用,毕竟androi d都8.0了,越来越好用 。

 android7.0 ,拍照,选择图片,不能和以前一样使用了 ,增加了权限的管理 ,直接看代码 。 相对以前的使用区别还是挺明显的

 0:先贴一个常量类,一会后边要使用

public class AppConstant {
    /***
     * 拍照返回图片的
     */
    public static final String cameralSavePath = ApInfo.IMAGE_URL + "/camera.jpg";
    public static final String CACHE_IMAGE = ApInfo.IMAGE_URL + "/cache.jpg";
    public static final String authorities = "com.mirrormobile.fileprovider";
    public static final int CAMERA_IMAGE_BACK = 5612;
    public static final int CUT_IMAGE_BACK = 23456;
    public static final int IMAGE_CUT_BACK = 5617;
    /***
     * 选择本地图库
     */
    public static final int LOCAL_FILE_BACK = 56452;
    public static final String TAG_LOCALFILE_BACK = "TAG_LOCALFILE_BACK";}

1:res中新建 xml 文件夹,在xml中新建file_paths.xml

    patH后边的路径是包名

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="files_root"
        path="Android/data/com.mirrormobile/" />
    <external-path
        name="external_storage_root"
        path="." />
</paths>


2:在清单文件中注册 :com.mirrormobile  是包名

      resource中是刚才新建的xml的路径

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.mirrormobile.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

3:新建工具类 :   ImageCutUtil,用来拍照,本地选择,切割图片

   android 6.0 以后使用隐私的权限,需要申请权限,这里我用的是HiPermission ,大家可以去github去看,使用还是挺方便的,这里就只贴代码了 ,Buid.gradle中引用一下

    

//hipermission
compile 'me.weyye.hipermission:library:1.0.7'

    去请求相机权限 ,通过后去调用系统

/***
 * 检查相机权限
 */
public void checkCameraPermission() {
    List<PermissionItem> permissions = new ArrayList<PermissionItem>();
    permissions.add(
            new PermissionItem(Manifest.permission.CAMERA, "SD卡读取权限", R.drawable.permission_ic_phone));
    HiPermission.create(context).title(context.getString(R.string.permission_cus_title)).permissions(
            permissions).msg(context.getString(R.string.permission_cus_msg)).animStyle(R.style.PermissionAnimModal).style(
            R.style.PermissionDefaultBlueStyle).checkMutiPermission(new PermissionCallback() {
        @Override
        public void onClose() {
            Log.e("main", "====onClose====");
        }

        @Override
        public void onFinish() {
            try {
                takeCameraPhoto();
            } catch (Exception e) {
                MyToastView.getInstance().Toast(context, e.toString());
                Log.e("main", "====打开相机异常====" + e.toString());
            }
        }

        @Override
        public void onDeny(String permission, int position) {
            Log.e("main", "====打开相机异常====");
            MyToastView.getInstance().Toast(context, "您拒绝了" + permission + "权限,请手动打开");
        }

        @Override
        public void onGuarantee(String permission, int position) {
            Log.e("main", "====onGuarantee====");
        }
    });
}

/***
 * 拍照返回
 */
public void takeCameraPhoto() {
    try {
        FileUtils.creatFileNotExciet();
        File file = new File(AppConstant.cameralSavePath);
        if (file.exists()) {
            file.delete();
        }
        file.createNewFile();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  //7.0执行该方法
            Uri imageUri = FileProvider.getUriForFile(context, AppConstant.authorities, file);
            Intent intent = new Intent();
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
            context.startActivityForResult(intent, AppConstant.CAMERA_IMAGE_BACK);
        } else {  //7.0以下手机系统执行这个方法
            Intent getPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            Uri uri = Uri.fromFile(file);
            getPhoto.putExtra(MediaStore.EXTRA_OUTPUT, uri);//根据uri保存照片
            getPhoto.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//保存照片的质量
            context.startActivityForResult(getPhoto, AppConstant.CAMERA_IMAGE_BACK);//启动相机拍照
        }
    } catch (Exception e) {
        MyToastView.getInstance().Toast(context, e.toString());
    }
}
    拍照的时候,判断一下当前的系统版本,7.0以前使用的url .7.0以后是使用FileProvider来访问本地图片

    选择本地的图片 ,同理,需要分系统来操作

    接下来就是图片切割了 ,7.0的使用方法相比以前的要稍微复杂一点,但是系统的切割用着舒服 ,简单的调用,如果觉得界面不好看,那就智能自己去想办法了 ,去引用第三方 ,或者自己写  ,注释比较清楚,不解释了

      

/***
 * 裁切图片
 * @param inputUrl
 *     裁切图片的url
 * @param outputUrl
 * 保存的图片的url
 */
public void cutImage(String inputUrl, String outputUrl) {
    try {
        File file_out = new File(outputUrl);
        if (file_out.exists()) {
            file_out.delete();
        }
        file_out.createNewFile();
        cropPicture(inputUrl, outputUrl);
    } catch (Exception e) {
        Log.e(TAG, "====裁切图片异常=--" + e.toString());
        MyToastView.getInstance().Toast(context, e.toString());
    }
}

/**
 * 调用系统剪裁功能
 */
public void cropPicture(String inputUrl, String output) {
    File fileinput = new File(inputUrl);
    Uri imageUri;
    Uri outputUri;
    Intent intent = new Intent("com.android.camera.action.CROP");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        imageUri = FileProvider.getUriForFile(context, AppConstant.authorities, fileinput);
        outputUri = Uri.fromFile(new File(output));
    } else {
        imageUri = Uri.fromFile(fileinput);
        outputUri = Uri.fromFile(new File(output));
    }
    intent.setDataAndType(imageUri, "image/*");
    intent.putExtra("crop", "true");
    //设置宽高比例
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 2);
    //设置裁剪图片宽高
    // intent.putExtra("outputX", 300);
    // intent.putExtra("outputY", 300);
    intent.putExtra("scale", true);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    intent.putExtra("noFaceDetection", true);
    context.startActivityForResult(intent, AppConstant.IMAGE_CUT_BACK);
}

   界面调用初始化这个工具类 ,然后直接调用权限的方法就可以了,我们看一下OnActivityForResult()这个方法

  

String updatePath = "";

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == AppConstant.CAMERA_IMAGE_BACK) { //拍照返回的数据
        imageCutUtil.cutImage(AppConstant.cameralSavePath, AppConstant.CACHE_IMAGE);
    } else if (requestCode == AppConstant.LOCAL_FILE_BACK) {
        String filePath = data.getStringExtra(AppConstant.TAG_LOCALFILE_BACK);
        imageCutUtil.cutImage(filePath, AppConstant.CACHE_IMAGE);
    } else if (requestCode == AppConstant.IMAGE_CUT_BACK) {  //切割之后返回的数据
        Bitmap bitmap = BitmapFactory.decodeFile(AppConstant.CACHE_IMAGE);
        iv_show_image.setImageBitmap(bitmap);
        updatePath = AppConstant.CACHE_IMAGE;
    }
}

    选择本地也就简单了,结合上边的代码 ,处理起来比较简单,检查权限,打开本地图库

     

 public void checkSdImagePermiss() {
        List<PermissionItem> permissions = new ArrayList<PermissionItem>();
        permissions.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "SD卡读取权限", R.drawable.permission_ic_phone));
        permissions.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "SD卡读取权限", R.drawable.permission_ic_phone));

        HiPermission.create(context).title(context.getString(R.string.permission_cus_title)).permissions(
                permissions).msg(context.getString(R.string.permission_cus_msg)).animStyle(R.style.PermissionAnimModal).style(
                R.style.PermissionDefaultBlueStyle).checkMutiPermission(new PermissionCallback() {
            @Override
            public void onClose() {
                Log.i(TAG, "用户拒绝我们的权限");
            }

            @Override
            public void onFinish() {
                try {
                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*");
                    context.startActivityForResult(intent, AppConstant.LOCAL_FILE_BACK);
//                    Intent intent = new Intent(context, LoImgChooiceActivity.class);
//                    context.startActivityForResult(intent, AppConstant.LOCAL_FILE_BACK);
                } catch (Exception e) {
                    Log.e("main", "====打开相机异常====" + e.toString());
                }
            }

      界面的onActivityForResult(),接受到数据,直接吧数据丢给Util去处理

      

    String updatePath = "";

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == AppConstant.CAMERA_IMAGE_BACK) { //拍照返回的数据
            imageCutUtil.cutImage(AppConstant.cameralSavePath, AppConstant.CACHE_IMAGE);
        } else if (requestCode == AppConstant.LOCAL_FILE_BACK) {  //本地图片选择
            imageCutUtil.cutImageLocal(data);
//            String filePath = data.getStringExtra(AppConstant.TAG_LOCALFILE_BACK);
//            imageCutUtil.cutImage(filePath, AppConstant.CACHE_IMAGE);
        } else if (requestCode == AppConstant.IMAGE_CUT_BACK) {  //切割之后返回的数据
            Bitmap bitmap = BitmapFactory.decodeFile(AppConstant.CACHE_IMAGE);
            iv_show_image.setImageBitmap(bitmap);
            updatePath = AppConstant.CACHE_IMAGE;
        }
    }

/***
 * 本地图片选择器
 * @param data
 */
public void cutImageLocal(Intent data) {
    Uri imageUri = data.getData();
    String url_out = AppConstant.CACHE_IMAGE;
    File file_out = new File(AppConstant.CACHE_IMAGE);
    if (file_out.exists()) {
        file_out.delete();
    }
    Uri outputUri = Uri.fromFile(new File(url_out));
    cutImage(imageUri, outputUri);
}
   直接获取图片的URI ,然后直接去裁切 。下面贴上全部代码 ;

     

package com.mirror.mobile.util.image;


import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.util.Log;

import com.cdl.dialog.toast.MyToastView;
import com.mirror.mobile.test.LoImgChooiceActivity;
import com.mirror.mobile.util.FileUtils;
import com.mirror.mobile.util.updatepic.AppConstant;
import com.mirrormobile.R;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import me.weyye.hipermission.HiPermission;
import me.weyye.hipermission.PermissionCallback;
import me.weyye.hipermission.PermissionItem;

/***
 * 图片裁剪工具类
 */
public class ImageCutUtil {
    Activity context;
    private static final String TAG = "MAIN";

    public ImageCutUtil(Activity context) {
        this.context = context;
    }


    //===============================================================================================================================

    /***
     * 本地图片选择器
     * @param data
     */
    public void cutImageLocal(Intent data) {
        Uri imageUri = data.getData();
        String url_out = AppConstant.CACHE_IMAGE;
        File file_out = new File(AppConstant.CACHE_IMAGE);
        if (file_out.exists()) {
            file_out.delete();
        }
        Uri outputUri = Uri.fromFile(new File(url_out));
        cutImage(imageUri, outputUri);
    }

    //============================================================================================================================================

    public void cutImage(String inputUrl, String output) {
        try {
            File file_out = new File(output);
            if (file_out.exists()) {
                file_out.delete();
            }
            file_out.createNewFile();
            File fileinput = new File(inputUrl);
            Uri imageUri;
            Uri outputUri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                imageUri = FileProvider.getUriForFile(context, AppConstant.authorities, fileinput);
                outputUri = Uri.fromFile(new File(output));
            } else {
                imageUri = Uri.fromFile(fileinput);
                outputUri = Uri.fromFile(new File(output));
            }
            cutImage(imageUri, outputUri);
        } catch (Exception e) {
        }
    }

    public void cutImage(Uri imageUri, Uri outputUri) {
        try {
            Intent intent = new Intent("com.android.camera.action.CROP");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
            intent.setDataAndType(imageUri, "image/*");
            intent.putExtra("crop", "true");
            //设置宽高比例
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 2);
            intent.putExtra("scale", true);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
            intent.putExtra("noFaceDetection", true);
            context.startActivityForResult(intent, AppConstant.IMAGE_CUT_BACK);
        } catch (Exception e) {
        }
    }


//    public void cutImage(String inputUrl, String output) {
//        try {
//            File file_out = new File(output);
//            if (file_out.exists()) {
//                file_out.delete();
//            }
//            file_out.createNewFile();
//            File fileinput = new File(inputUrl);
//            Uri imageUri;
//            Uri outputUri;
//            Intent intent = new Intent("com.android.camera.action.CROP");
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//                imageUri = FileProvider.getUriForFile(context, AppConstant.authorities, fileinput);
//                outputUri = Uri.fromFile(new File(output));
//            } else {
//                imageUri = Uri.fromFile(fileinput);
//                outputUri = Uri.fromFile(new File(output));
//            }
//            intent.setDataAndType(imageUri, "image/*");
//            intent.putExtra("crop", "true");
//            //设置宽高比例
//            intent.putExtra("aspectX", 1);
//            intent.putExtra("aspectY", 2);
//            //设置裁剪图片宽高
//            // intent.putExtra("outputX", 300);
//            // intent.putExtra("outputY", 300);
//            intent.putExtra("scale", true);
//            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
//            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
//            intent.putExtra("noFaceDetection", true);
//            context.startActivityForResult(intent, AppConstant.IMAGE_CUT_BACK);
//        } catch (Exception e) {
//        }
//    }


    public void checkSdImagePermiss() {
        List<PermissionItem> permissions = new ArrayList<PermissionItem>();
        permissions.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "SD卡读取权限", R.drawable.permission_ic_phone));
        permissions.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "SD卡读取权限", R.drawable.permission_ic_phone));

        HiPermission.create(context).title(context.getString(R.string.permission_cus_title)).permissions(
                permissions).msg(context.getString(R.string.permission_cus_msg)).animStyle(R.style.PermissionAnimModal).style(
                R.style.PermissionDefaultBlueStyle).checkMutiPermission(new PermissionCallback() {
            @Override
            public void onClose() {
                Log.i(TAG, "用户拒绝我们的权限");
            }

            @Override
            public void onFinish() {
                try {
                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*");
                    context.startActivityForResult(intent, AppConstant.LOCAL_FILE_BACK);
//                    Intent intent = new Intent(context, LoImgChooiceActivity.class);
//                    context.startActivityForResult(intent, AppConstant.LOCAL_FILE_BACK);
                } catch (Exception e) {
                    Log.e("main", "====打开相机异常====" + e.toString());
                }
            }

            @Override
            public void onDeny(String permission, int position) {
                MyToastView.getInstance().Toast(context, "您拒绝了" + permission + "权限,请手动打开");
                Log.i(TAG, "用户禁止了权限" + permission);
            }

            @Override
            public void onGuarantee(String permission, int position) {
                Log.i(TAG, "onGuarantee");
            }
        });
    }

    /***
     * 检查相机权限
     */
    public void checkCameraPermission() {
        List<PermissionItem> permissions = new ArrayList<PermissionItem>();
        permissions.add(
                new PermissionItem(Manifest.permission.CAMERA, "SD卡读取权限", R.drawable.permission_ic_phone));
        HiPermission.create(context).title(context.getString(R.string.permission_cus_title)).permissions(
                permissions).msg(context.getString(R.string.permission_cus_msg)).animStyle(R.style.PermissionAnimModal).style(
                R.style.PermissionDefaultBlueStyle).checkMutiPermission(new PermissionCallback() {
            @Override
            public void onClose() {
                Log.e("main", "====onClose====");
            }

            @Override
            public void onFinish() {
                try {
                    takeCameraPhoto();
                } catch (Exception e) {
                    MyToastView.getInstance().Toast(context, e.toString());
                    Log.e("main", "====打开相机异常====" + e.toString());
                }
            }

            @Override
            public void onDeny(String permission, int position) {
                Log.e("main", "====打开相机异常====");
                MyToastView.getInstance().Toast(context, "您拒绝了" + permission + "权限,请手动打开");
            }

            @Override
            public void onGuarantee(String permission, int position) {
                Log.e("main", "====onGuarantee====");
            }
        });
    }

    /***
     * 拍照返回
     */
    public void takeCameraPhoto() {
        try {
            FileUtils.creatFileNotExciet();
            File file = new File(AppConstant.cameralSavePath);
            if (file.exists()) {
                file.delete();
            }
            file.createNewFile();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  //7.0执行该方法
                Uri imageUri = FileProvider.getUriForFile(context, AppConstant.authorities, file);
                Intent intent = new Intent();
                //添加这一句表示对目标应用临时授权该Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
                context.startActivityForResult(intent, AppConstant.CAMERA_IMAGE_BACK);
            } else {  //7.0以下手机系统执行这个方法
                Intent getPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                Uri uri = Uri.fromFile(file);
                getPhoto.putExtra(MediaStore.EXTRA_OUTPUT, uri);//根据uri保存照片
                getPhoto.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//保存照片的质量
                context.startActivityForResult(getPhoto, AppConstant.CAMERA_IMAGE_BACK);//启动相机拍照
            }
        } catch (Exception e) {
            MyToastView.getInstance().Toast(context, e.toString());
        }
    }

}

  界面拍照 ,获取图库代码

    

@Override
public void clickFirst() { //拍照
    imageCutUtil.checkCameraPermission();
}

@Override
public void clickSecond() {   //本地取图片
    imageCutUtil.checkSdImagePermiss();
}

    String updatePath = "";

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == AppConstant.CAMERA_IMAGE_BACK) { //拍照返回的数据
            imageCutUtil.cutImage(AppConstant.cameralSavePath, AppConstant.CACHE_IMAGE);
        } else if (requestCode == AppConstant.LOCAL_FILE_BACK) {  //本地图片选择
            imageCutUtil.cutImageLocal(data);
//            String filePath = data.getStringExtra(AppConstant.TAG_LOCALFILE_BACK);
//            imageCutUtil.cutImage(filePath, AppConstant.CACHE_IMAGE);
        } else if (requestCode == AppConstant.IMAGE_CUT_BACK) {  //切割之后返回的数据
            Bitmap bitmap = BitmapFactory.decodeFile(AppConstant.CACHE_IMAGE);
            iv_show_image.setImageBitmap(bitmap);
            updatePath = AppConstant.CACHE_IMAGE;
        }
    }


















    

猜你喜欢

转载自blog.csdn.net/fkgjdkblxckvbxbgb/article/details/79200248