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

直接上代码

首先添加拍照需要的权限

//相机权限//写SD//读SD

使用的常量

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(遇到问题或者有更好的建议请联系我额)

更多相关文章

  1. 居中显示并旋转 android Button 里的属性drawableLeft
  2. android ListView中自定义SimpleAdapter动态添加ratingBar及图片
  3. Android(安卓)TextView加载HTMl图文之添加点击事件和查看图片
  4. Android之Bitmap 高效加载
  5. 【翻译】Android安全之Linux内核篇
  6. QuickSand图片点击后分裂成几份消失效果
  7. 检索Android的图片库,并显示
  8. android附件上传下载(图片,语音,视频)
  9. Android注册设备管理器(获取超级管理员权限)

随机推荐

  1. Android解析xml的Demo
  2. Android SDK 2.0 安装
  3. 2013年上半年CSDN精华0分下载资源
  4. Android之back键拦截处理
  5. android studio 中添加 Volley module
  6. Qt for Android 程序禁止屏幕旋转
  7. android ksoap调用天气预报
  8. android视频播放
  9. Android性能优化之管理应用的内存
  10. Android开发学习之设置Android壁纸的功能