详细的android通过相册和相机获取图片和路径的方法

本文详细介绍了如何在Android应用中通过相册和相机获取图片及其路径。针对选择相册时可能出现的问题,建议使用Intent.ACTION_PICK与MediaStore.Images.Media.EXTERNAL_CONTENT_URI。在Android 7.0及以上版本,相机返回的URI必须为content类型,并提供了文件URI转content URI的方法。同时,文章还强调了在用户拍照后,应对图片进行压缩处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.权限

<uses-permission android:name="android.permission.CAMERA"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

分别代表调用相机的权限和内存读写的权限



二.点击事件

public void AddPic(View view) {
        CharSequence[] items = {"相册", "相机"};
        new AlertDialog.Builder(this)
                .setTitle("选择图片来源")
                .setItems(items, new DialogInterface.OnClickListener() {
                    public static final int SELECT_CAMER = 1;
                    public static final int SELECT_PICTURE = 0;

                    public void onClick(DialogInterface dialog, int which) {
                        if (Utils.getAndroidSDKVersion() < 19) {
                                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                                intent.setType("image/*");
                                startActivityForResult(intent, SELECT_PICTURE);
                            } else {
                                Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                                startActivityForResult(Intent.createChooser(intent, "选择图片"), SELECT_PICTURE);
                            }
                        } else {
                            try {
                                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                //path为保存图片的路径,执行完拍照以后能保存到指定的路径下
                                File file;
                                private String picpath = "/storage/emulated/0/DCIM/Camera/", picfilename = "IMG_picpath1.jpg";
                                file = new File(picpath, picfilename);
                                if (Utils.getAndroidSDKVersion()<24){//安卓7.0以后版本,只接受content uri 不能再传file uri
                                    Uri imageUri = Uri.fromFile(file);
                                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                                    startActivityForResult(intent, SELECT_CAMER);
                                }else {
                                    Uri imageUri = Utils.getImageContentUri(HouseActivity.this,file);
                                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                                    startActivityForResult(intent, SELECT_CAMER);
                                }
                            } catch (RuntimeException e) {//用来捕获6.0后调用系统相机给了权限但是还是会崩的问题

                                Toast.makeText(HouseActivity.this, "请打开手机中该软件的调用系统相机的权限", Toast.LENGTH_SHORT).show();

                                //跳转提示用户打开该软件调用相机的权限

                                Intent intent2 = new Intent();

                                intent2.setAction("Android.intent.action.MAIN");

                                intent2.setClassName("com.android.settings", "com.android.settings.ManageApplications");

                                startActivity(intent2);

                            }
                        }
                    }
                })
                .create().show();
    }



           此处弹出一个对话框,选择相机或相册,选择相册时当版本小于19时,使用Intent.GET_CONTENT可以直接得到图片路径;而大于19时,弹出的界面为选择图片类型。

          选择相册时可以成功获得路径,而选择“最近,图片”等标签时,无法获得正确途径,此时可以使用Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI作为参数的intent。

              注意:安卓7.0版本调用相机传uri时只能传content uri而不能传file uri 文章最后附上file uri转content uri的方法,此方法只能转换多媒体类型的uri不能转换其他uri


获得SDK版本的方法

public static int getAndroidSDKVersion() {
        int version = 0;
        try {
            version = Integer.valueOf(android.os.Build.VERSION.SDK);
        } catch (NumberFormatException e) {
            Log.e("TAG",e.getLocalizedMessage());
        }
        return version;
    }

当选择相机时,若想最后能得到照片存储的路径,需要先提前设定好图片保存的路径即代码中的picpath和picfilename。然后调用系统相机。(当版本为6.0或以上的安卓系统时,需要手动授权给应用,若用户没有授权,则跳转至授权界面)。



三.onActivityResult


 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            ContentResolver cr = this.getContentResolver();
            //选择图片
            if (data != null) {
                uri = data.getData();
                String[] filePathColumns = {MediaStore.Images.Media.DATA};
                Cursor c = this.getContentResolver().query(uri, filePathColumns, null, null, null);
                c.moveToFirst();
                int columnIndex = c.getColumnIndex(filePathColumns[0]);
                picturePath = c.getString(columnIndex);
                c.close();
                PicDispose.compressImage(picturePath, picturePath, 30);
                bm = BitmapFactory.decodeFile(picturePath);
                imageview.setImageBitmap(bm);
                imageview.setVisibility(View.VISIBLE);
            } else {
            picturePath = picpath + picfilename;
            PicDispose.compressImage(picturePath, picturePath, 30);
            bm = BitmapFactory.decodeFile(picturePath);
            imageview.setImageBitmap(bm);
            imageview.setVisibility(View.VISIBLE);
            }
        } else {
            Toast.makeText(HouseActivity.this, "请重新选择图片", Toast.LENGTH_SHORT).show();
        }
    }

            当用户选择的是图片时,根据URI从系统的表中查询出对应的图片路径(若不要图片路径可以直接通过uri得到图片并显示出来)

           当用户选择的是拍照时就可以直接根据预设好的路径获得图片了

             注意:图片取得后应该压缩再显示,此处提供一个从网上找的压缩图片的类




public class PicDispose {

    public static String compressImage(String filePath, String targetPath, int quality)  {
        Bitmap bm = getSmallBitmap(filePath);//获取一定尺寸的图片
        int degree = readPictureDegree(filePath);//获取相片拍摄角度
        if(degree!=0){//旋转照片角度,防止图片横着显示
            bm=rotateBitmap(bm,degree);
        }
        File outputFile=new File(targetPath);
        try {
            if (!outputFile.exists()) {
                outputFile.getParentFile().mkdirs();
                //outputFile.createNewFile();
            }else{
                outputFile.delete();
            }
            FileOutputStream out = new FileOutputStream(outputFile);
            bm.compress(Bitmap.CompressFormat.JPEG, quality, out);
        }catch (Exception e){}
        Log.d("bmp","targetPath========>"+targetPath+"==========outputFile.getPath()"+outputFile.getPath());
        return outputFile.getPath();
    }

    /**
     * 根据路径获得图片信息并按比例压缩,返回bitmap
     */
    public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高
        BitmapFactory.decodeFile(filePath, options);
        // 计算缩放比
        options.inSampleSize = calculateInSampleSize(options, 480, 800);
        // 完整解析图片返回bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }


    /**
     * 获取照片角度
     * @param path
     * @return
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            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 bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }
    public static int calculateInSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }





}


                        
file uri转content uri的方法,此方法只能转换多媒体类型的uri不能转换其他uri

//将File Uri更换为Content Uri()
    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;
            }
        }
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值