Android:简单的拍照/相册截图功能

因为以前做一些项目偶尔会用到拍照截图或者相册截取图做头像的功能,在这里整理一下以免重复踩坑。

1.权限申请

首先我们需要获取相册以及读写内存权限。

AndroidManifest.xml声明

因为申请了WRITE_EXTERNAL_STORAGE就能进行读写操作,我就不再重复申请读取的权限了。

	<!-- 允许程序设置内置sd卡的写权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 运行程序使用相机权限-->
    <uses-permission android:name="android.permission.CAMERA" />

动态申请权限

权限并不是xml申请就完事,targetSdkVersion为23或者以上我们还需要在运行时请求这些所需的权限。

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED||
                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            //申请WRITE_EXTERNAL_STORAGE权限
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123);
        }else {
            have_permission = true;
        }

然后我们需要处理权限申请的回调

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode==123){
            boolean isAllGranted = true;
            for (int grant : grantResults) {
                if (grant != PackageManager.PERMISSION_GRANTED) {
                    isAllGranted = false;
                    have_permission = false;
                    break;
                }
            }
            if (isAllGranted) {
                have_permission = true;
            }
        }
    }

2.拍照截图

权限申请完毕之后下来的就是正戏。

确认存储路径是否存在

我这里是在系统相册的目录下新建一个独立文件夹做存储,比较不环保(程序卸载依旧保留文件),大家可以自行修改。

        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
        final File file = new File(path + "/plants");
        if (!file.exists()) {
            try {
                //按照指定的路径创建文件夹
                file.mkdirs();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }

拍照/相册截图操作

逻辑流程:

101
103
102
触发拍照
拍照结果回调
进行截图
截图回调
触发相册取图
选取图片回调

下面开始码代码:

	private Uri imageUri;
    private Uri imageCropUri;
    private File cropFile;
    private static final int RESULT_CAMERA_ONLY = 101;//拍照
    private static final int RESULT_ALBUM_ONLY_THROUGH_URI = 102;//相册
    private static final int CROP_PATH_RESULT = 103;//截图

触发系统拍照相关的代码:

       if(have_permission){ //判断是否拥有权限
           File file2 = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath()+ "/plants/temp"+"12345"+".jpg");//创建拍照图片文件
           imageUri = Uri.fromFile(file2);
           File cropFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/plants/temp"+"12345"+"_crop.jpg");//创建截图图片文件
           imageCropUri = Uri.fromFile(cropFile);
           takeCameraOnly();
       }else {
           Log.e("MainActivity","permission:"+have_permission);
       }

    void takeCameraOnly() {
        Intent intent = null;
        intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//action is capture
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, RESULT_CAMERA_ONLY);
    }

触发相册取图的代码:

     if(have_permission){
          gotoAlbum();
      }else {
          Log.e("MainActivity","permission:"+have_permission);
      }
 	void gotoAlbum(){
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setType("image/*");
        startActivityForResult(intent, RESULT_ALBUM_ONLY_THROUGH_URI);
    }

重写回调函数onActivityResult():

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.i("onActivityResult","requestCode:"+requestCode+"resultCode:"+resultCode);
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        switch (requestCode) {
            case RESULT_CAMERA_ONLY: {
                File file2 = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath()+ "/plants/temp"+ "12345"+".jpg");// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
                imageUri = Uri.fromFile(file2);
                cropFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/plants/temp"+ "12345"+"_crop.jpg");
                imageCropUri = Uri.fromFile(cropFile);
                cropImg(imageUri);
            }
            break;
            case RESULT_ALBUM_ONLY_THROUGH_URI:{
                String picPath = parsePicturePath(MainActivity.this,data.getData());
                File file = new File(picPath);
                Uri uri= Uri.fromFile(file);
                cropFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/plants/temp"+ "12345"+"_crop.jpg");
                imageCropUri = Uri.fromFile(cropFile);
                cropImg(uri);
            }
            break;
            case CROP_PATH_RESULT: {
                if (getTempFile() != null) {
                    try {
                        imageCropUri = Uri.fromFile(cropFile);
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageCropUri));
                        if (bitmap != null) {
                            Bitmap smallBmp = setScaleBitmap(bitmap, 2);
                            riv_flower.setImageBitmap(smallBmp);
                        }
                        if(!TextUtils.isEmpty(imageUri.toString())){//对拍照原图进行删除操作,可视情况考虑是否保留
                            File file =  new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath()+ "/plants/temp"+ "12345"+".jpg");
                            file.delete();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else{
                    Log.e("CROP_PATH_RESULT","getTempFile=null");
                }
            }
            break;
        }
    }

触发截图操作:

public void cropImg(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 700);
        intent.putExtra("outputY", 700);
        intent.putExtra("return-data", false);
//        Log.i("TAG","imageCropUri;"+imageCropUri.toString());
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, CROP_PATH_RESULT);
    }

图片压缩相关代码:

	private Bitmap setScaleBitmap(Bitmap photo,int SCALE) {
        if (photo != null) {
            //为防止原始图片过大导致内存溢出,这里先缩小原图显示,然后释放原始Bitmap占用的内存
            //这里缩小了1/2,但图片过大时仍然会出现加载不了,但系统中一个BITMAP最大是在10M左右,我们可以根据BITMAP的大小
            //根据当前的比例缩小,即如果当前是15M,那如果定缩小后是6M,那么SCALE= 15/6
            Bitmap smallBitmap = zoomBitmap(photo, photo.getWidth() / SCALE, photo.getHeight() / SCALE);
            //释放原始图片占用的内存,防止out of memory异常发生
            photo.recycle();
            return smallBitmap;
        }
        return null;
    }
    public Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) width / w);
        float scaleHeight = ((float) height / h);
        matrix.postScale(scaleWidth, scaleHeight);// 利用矩阵进行缩放不会造成内存溢出
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
        return newbmp;
    }

获取相册路径核心代码:

	public static String parsePicturePath(Context context, Uri uri) {

        if (null == context || uri == null)
            return null;

        boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentUri
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageDocumentsUri
            if (isExternalStorageDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                String[] splits = docId.split(":");
                String type = splits[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + File.separator + splits[1];
                }
            }
            // DownloadsDocumentsUri
            else if (isDownloadsDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaDocumentsUri
            else if (isMediaDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                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 = "_id=?";
                String[] selectionArgs = new String[] {split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isGooglePhotosContentUri(uri))
                return uri.getLastPathSegment();
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;

    }
    private static boolean isExternalStorageDocumentsUri(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    private static boolean isDownloadsDocumentsUri(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    private static boolean isMediaDocumentsUri(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    private static boolean isGooglePhotosContentUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = "_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 {
            try {
                if (cursor != null)
                    cursor.close();
            } catch (Exception e) {
                Log.e("harvic",e.getMessage());
            }
        }
        return null;

    }

完整代码下载:https://github.com/elongpaoxiao/InterceptPictures/tree/master/app/src/main/java/com/test/interceptpictures

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值