MVP模式的Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题

来源:互联网 发布:江苏省软件测试中心 编辑:程序博客网 时间:2024/04/29 22:12

Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题

直接上代码

首先添加拍照需要的权限

<uses-permission android:name="android.permission.CAMERA" />//相机权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//写SD<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//读SD<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTE" />

使用的常量

public static final int MY_PERMISSIONS_REQUEST_CAMERA = 100;//拍照权限public static final int MY_PERMISSIONS_REQUEST_READ_SD= 101;//读SD卡权限public static final int MY_PERMISSIONS_REQUEST_WRITE_SK = 102;//写SD卡权限public static final int MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM= 103;//写SD卡权限public static final int MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM = 104;//写SD卡权限public static final int CAPTURE_IMAGE_REQUEST = 104;//拍照后的返回值public static final int LOAD_IMAGE_REQUEST = 105;//相册的返回值public static final int CLIP_IMAGE_REQUEST = 106;//剪裁图片的返回值public static final String IMAGE_TYPE = "image/*";public  static File mOutFile;//图片uri路径public  static File mImageFile=null;//图片file路径public  static Integer mBuildVersion=android.os.Build.VERSION.SDK_INT;//当前SDK版本

定义需要用到的接口

public interface UserCenterModel {    /**     * 拍照     * @param context     */    void getFileByPhotograph(Context context);    /**     * 相册     * @param context     */    void getFileByPhotoAlbum(Context context);    /**     * 创建img文件     * @return     */    File getImagefile();    /**     * 开始拍照     * @param context     */    void startPhotograph(Context context);    /**     * 调用相册     * @param context     */    void startPhotoAlbum(Context context);    /**     * 剪裁图片     * @param activity     */    void startClip(Activity activity, File file);    /**     * API24 以上调用     * @param context     * @param imageFile     * @return     */    Uri getImageContentUri(Context context, File imageFile);}

接口实现类

public class UserCenterRealize implements UserCenterModel {    @Override    public void getFileByPhotograph(Context context) {        Activity activity = (Activity) context;        if (AppConsts.mBuildVersion >= 23) {            if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {                //申请相机权限                ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, AppConsts.MY_PERMISSIONS_REQUEST_CAMERA);            } else {                if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                    //申请读SD权限                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_READ_SD);                } else {                    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                        //申请写SD权限                        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK);                    } else {                        startPhotograph(activity);                    }                }            }        } else {            //拍照            startPhotograph(activity);        }    }    @Override    public File getImagefile() {        File mediaStorageDir = null;        File mediaFile = null;        try {            mediaStorageDir = new File(Environment.getExternalStorageDirectory().toString() + "/IMAGE/");            Log.d("创建文件夹成功", mediaStorageDir.toString());        } catch (Exception e) {            e.printStackTrace();            Log.d("创建文件夹失败", mediaStorageDir.toString());        }        if (!mediaStorageDir.exists()) {            if (!mediaStorageDir.mkdirs()) {                Log.d("创建文件失败", "WRITE_EXTERNAL_STORAGE 权限");                return null;            }        }        // Create a media file name        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());        mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");        Log.d("创建文件成功",mediaFile.toString());        return mediaFile;    }    @Override    public void getFileByPhotoAlbum(Context context) {        Activity activity= (Activity) context;        if (AppConsts.mBuildVersion >= 23) {                if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                    //申请读SD权限                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM);                } else {                    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                        //申请写SD权限                        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM);                    } else {                        startPhotoAlbum(context);                    }                }        } else {            startPhotoAlbum(context);        }    }    @Override    public void startPhotoAlbum(Context context) {        if(!BitmapUtils.existSDCard()){            Toast.makeText(context, "未检测到SD卡", Toast.LENGTH_SHORT).show();            return;        }        Activity a= (Activity) context;        Intent getAlbum = new Intent(Intent.ACTION_GET_CONTENT);        getAlbum.setType(AppConsts.IMAGE_TYPE);        a.startActivityForResult(getAlbum, AppConsts.LOAD_IMAGE_REQUEST);    }    @Override    public void startPhotograph(Context context) {        if(!BitmapUtils.existSDCard()){            Toast.makeText(context, "未检测到SD卡", Toast.LENGTH_SHORT).show();            return;        }        Activity activity= (Activity) context;        if (AppConsts.mBuildVersion<24){            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);            mImageFile=getImagefile();            intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(mImageFile));            activity.startActivityForResult(intent, AppConsts.CAPTURE_IMAGE_REQUEST);        }else {            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);            ContentValues contentValues = new ContentValues(1);            mImageFile=getImagefile();            contentValues.put(MediaStore.Images.Media.DATA, mImageFile.getAbsolutePath());            Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);            activity.startActivityForResult(intent, AppConsts.CAPTURE_IMAGE_REQUEST);        }    }    @Override    public void startClip(Activity activity, File file) {        if(null == file){            return;        }        mOutFile=getImagefile();        Intent intent = new Intent("com.android.camera.action.CROP");        intent.setDataAndType(getImageContentUri(activity,file),AppConsts.IMAGE_TYPE);        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(mOutFile));        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());        intent.putExtra("noFaceDetection", true);        activity.startActivityForResult(intent, AppConsts.CLIP_IMAGE_REQUEST);    }    @Override    public Uri getImageContentUri(Context context, File imageFile) {        String filePath = imageFile.getAbsolutePath();        Uri uri=null;        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");            uri= Uri.withAppendedPath(baseUri, "" + id);        } else {            if (imageFile.exists()) {                ContentValues values = new ContentValues();                values.put(MediaStore.Images.Media.DATA, filePath);                uri= context.getContentResolver().insert(                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);            } else {                uri= null;            }        }        return uri;    }}

Actvity界面中的回调

            userCenterRealize.getFileByPhotoAlbum(this);//拍照外部调用            userCenterRealize.getFileByPhotograph(this);//相册外部调用
@Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == AppConsts.MY_PERMISSIONS_REQUEST_CAMERA)        {            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                userCenterRealize.getFileByPhotograph(this);            } else {                Toast.makeText(this, "请授予相机权限", Toast.LENGTH_SHORT).show();            }        }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_READ_SD){            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                userCenterRealize.getFileByPhotograph(this);            } else {                Toast.makeText(this, "请授予读SD卡权限", Toast.LENGTH_SHORT).show();            }        }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK){            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                userCenterRealize.getFileByPhotograph(this);            } else {                Toast.makeText(this, "请授予写SD卡权限", Toast.LENGTH_SHORT).show();            }        }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM) {            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                userCenterRealize.startPhotoAlbum(this);            } else {                Toast.makeText(this, "请授予读SD卡权限", Toast.LENGTH_SHORT).show();            }        }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM) {            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                userCenterRealize.startPhotoAlbum(this);            } else {                Toast.makeText(this, "请授予写SD卡权限", Toast.LENGTH_SHORT).show();            }        }    }@Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // 拍照        if (AppConsts.CAPTURE_IMAGE_REQUEST == requestCode) {            if (RESULT_OK == resultCode) {                Log.d("拍照得到图片", AppConsts.mImageFile.toString());                int mDegree=BitmapUtils.getBitmapDegree(AppConsts.mImageFile.getAbsolutePath());                Log.d("拍照得到图片的角度:", String.valueOf(mDegree));                if(mDegree==90||mDegree==180||mDegree==270){                    try {                        Bitmap mBitmap= BitmapUtils.getFileBitmap(AppConsts.mImageFile);                        Bitmap bitmap=BitmapUtils.rotateBitmapByDegree(mBitmap,mDegree);                        if(BitmapUtils.saveBitmapFile(bitmap,AppConsts.mImageFile)){                            userCenterRealize.startClip(this, AppConsts.mImageFile);                        }else {                            Toast.makeText(this, "保存图片失败", Toast.LENGTH_SHORT).show();                        }                    } catch (Exception e) {                        e.printStackTrace();                        Toast.makeText(this, "读取图片失败", Toast.LENGTH_SHORT).show();                    }                }else {                    userCenterRealize.startClip(this, AppConsts.mImageFile);                }            }            //相册        } else if (AppConsts.LOAD_IMAGE_REQUEST == requestCode) {            if (data != null) {                Uri uri = data.getData();                String filepath=FileUtils.getImageAbsolutePath(this, uri);                Log.d("相册获取到的文件路径",filepath);                File file = new File(filepath);                userCenterRealize.startClip(this, file);            }            //剪裁        } else if (AppConsts.CLIP_IMAGE_REQUEST == requestCode) {            Log.d("剪裁得到图片", AppConsts.mOutFile.toString());            Bitmap bitmap = BitmapUtils.getFileBitmap(AppConsts.mOutFile);            imgAvatar.setImageBitmap(bitmap);            BitmapUtils.deleteFile(AppConsts.mImageFile);        }    }

工程中使用到的工具类

public class BitmapUtils {    /**     * 获取网络图片资源     * @param url     * @return     */    public static Bitmap getHttpBitmap(String url){        URL myFileURL;        Bitmap bitmap=null;        try{            myFileURL = new URL(url);            //获得连接            HttpURLConnection conn=(HttpURLConnection)myFileURL.openConnection();            //设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制            conn.setConnectTimeout(6000);            //连接设置获得数据流            conn.setDoInput(true);            //不使用缓存            conn.setUseCaches(false);            //这句可有可无,没有影响            //conn.connect();            //得到数据流            InputStream is = conn.getInputStream();            //解析得到图片            bitmap = BitmapFactory.decodeStream(is);            //关闭数据流            is.close();        }catch(Exception e){            e.printStackTrace();        }        return bitmap;    }    /**     * 判断是否有SD卡     * @return     */    public   static  boolean existSDCard() {        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){           return true;        }else {            return false;        }    }    /**     * 从文件中读取图片     * @param file     * @return     */    public static Bitmap getFileBitmap(File file) {        FileInputStream fis = null;        Bitmap bitmap=null;        try {            //把图片转化为字节流            fis = new FileInputStream(file);            //把流转化图片             bitmap = BitmapFactory.decodeStream(fis);        } catch (FileNotFoundException e) {            e.printStackTrace();        } finally {            try {                fis.close();//关闭流            } catch (IOException e) {                e.printStackTrace();            }        }        return bitmap;    }    /**     * 读取图片的旋转的角度     *     * @param path     *            图片绝对路径     * @return 图片的旋转角度     */    public static int getBitmapDegree(String path) {        int degree = 0;        try {            // 从指定路径下读取图片,并获取其EXIF信息            ExifInterface exifInterface = new ExifInterface(path);            // 获取图片的旋转信息            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,                    ExifInterface.ORIENTATION_NORMAL);            switch (orientation) {                case ExifInterface.ORIENTATION_ROTATE_90:                    degree = 90;                    break;                case ExifInterface.ORIENTATION_ROTATE_180:                    degree = 180;                    break;                case ExifInterface.ORIENTATION_ROTATE_270:                    degree = 270;                    break;            }        } catch (IOException e) {            e.printStackTrace();        }        return degree;    }    /**     * 将图片按照某个角度进行旋转     *     * @param bm     *            需要旋转的图片     * @param degree     *            旋转角度     * @return 旋转后的图片     */    public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {        Bitmap returnBm = null;        // 根据旋转角度,生成旋转矩阵        Matrix matrix = new Matrix();        matrix.postRotate(degree);        try {            // 将原始图片按照旋转矩阵进行旋转,并得到新的图片            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);        } catch (OutOfMemoryError e) {        }        if (returnBm == null) {            returnBm = bm;        }        if (bm != returnBm) {            bm.recycle();        }        return returnBm;    }    /**     * 删除文档      * @param file     */    public static boolean  deleteFile(File file) {        try {                if(file!=null) {                    if(FileUtils.deleteFile(file.getAbsolutePath())){                        AppConsts.mImageFile=null;                        Log.d("删除文件","true");                        return true;                    }else {                        return false;                    }                }else {                    Log.d("删除文件路径为空","false");                    return false;                }            } catch (Exception e) {               e.printStackTrace();               Log.d("删除文件","false");               return false;            }    }        /**         * 保存图片         * @param bitmap         * @param file         */    public static boolean saveBitmapFile(Bitmap bitmap, File file){        try {            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);            bos.flush();            bos.close();            return true;        } catch (IOException e) {            e.printStackTrace();            return false;        }    }public class FileUtils {    /**     * 删除单个文件     * @param   filePath    被删除文件的文件名     * @return 文件删除成功返回true,否则返回false     */    public static boolean deleteFile(String filePath) {        File file = new File(filePath);        if (file.isFile() && file.exists()) {            return file.delete();        }        return false;    }    /**     * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换     * @param context     * @param imageUri     * @author yaoxing     * @date 2014-10-12     */    @TargetApi(19)    public static String getImageAbsolutePath(Activity context, Uri imageUri) {        if (context == null || imageUri == null)            return null;        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {            if (isExternalStorageDocument(imageUri)) {                String docId = DocumentsContract.getDocumentId(imageUri);                String[] split = docId.split(":");                String type = split[0];                if ("primary".equalsIgnoreCase(type)) {                    return Environment.getExternalStorageDirectory() + "/" + split[1];                }            } else if (isDownloadsDocument(imageUri)) {                String id = DocumentsContract.getDocumentId(imageUri);                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));                return getDataColumn(context, contentUri, null, null);            } else if (isMediaDocument(imageUri)) {                String docId = DocumentsContract.getDocumentId(imageUri);                String[] split = docId.split(":");                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;                }                String selection = MediaStore.Images.Media._ID + "=?";                String[] selectionArgs = new String[] { split[1] };                return getDataColumn(context, contentUri, selection, selectionArgs);            }        } // MediaStore (and general)        else if ("content".equalsIgnoreCase(imageUri.getScheme())) {            // Return the remote address            if (isGooglePhotosUri(imageUri))                return imageUri.getLastPathSegment();            return getDataColumn(context, imageUri, null, null);        }        // File        else if ("file".equalsIgnoreCase(imageUri.getScheme())) {            return imageUri.getPath();        }        return null;    }    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {        Cursor cursor = null;        String column = MediaStore.Images.Media.DATA;        String[] projection = { column };        try {            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);            if (cursor != null && cursor.moveToFirst()) {                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 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.     */    private 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.     */    private 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());    }}

The End

 QQ:3355168235(遇到问题或者有更好的建议请联系我额)
0 1
原创粉丝点击