如何从Android Q中的Uri获取图像的实际路径?

时间:2019-09-24 13:39:22

标签: android

我正在使用相机拍照并从画廊中选择。之后,进行压缩以减小文件大小。我当时使用public handleObjectWithMultipleFields = (ev) => { const target = ev.target; const {value, name} = target; this.setState({ [name]: value }) } 方法来获取实际的图像路径,但是在Android Q getRealPathFromURI()中已弃用。

MediaStore.Images.Media.DATA

根据文档,我尝试fun getRealPathFromURI(contentUri: Uri, activityContext: Activity): String { val proj = arrayOf(MediaStore.Images.Media.DATA) val cursor = activityContext.managedQuery(contentUri, proj, null, null, null) val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) cursor.moveToFirst() return cursor.getString(column_index) } 来获得访问权限:

openFileDescriptor()

还尝试了this

2 个答案:

答案 0 :(得分:1)

要从图库中加载图像,可以使用它,并且在清单中有创建提供

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

像这样创建您的@ xml / provide_paths

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" 
path="Android/data/package_name/files/Pictures" /> //pictures is the folder where your image will store
</paths>

代码:

if (resultCode == Activity.RESULT_OK) { //onActivity you will get the result like this way
                    if (data != null) {
                        Uri contentURI = data.getData();
                        String path = null;
                        try {
                            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),contentURI);
                            path = saveImage(bitmap);
                         //   decodeImage(path);
                            img.setImageBitmap(bitmap);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        mCurrentPhotoPath = path;
                    }
                }

public void activeGallery() {// for taking the picture from gallery
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        startActivityForResult(galleryIntent,RESULT_LOAD_IMAGE);

    }

并用于在活动中使用捕获图像

 Bundle bundle=data.getExtras();  // 
                        Bitmap bitmap= (Bitmap) bundle.get("data");
                        img.setImageBitmap(bitmap);
                        saveImage(bitmap);


 public String saveImage(Bitmap myBitmap) { //this method will compress your image
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        myBitmap.compress(JPEG, 90, bytes);
        File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() , ""+IMAGE_DIRECTORY);
        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {
            wallpaperDirectory.mkdirs();
        }

        try {
            File f = new File(wallpaperDirectory, Calendar.getInstance()
                    .getTimeInMillis() + ".jpg");
            f.createNewFile();
            FileOutputStream fo = new FileOutputStream(f);
      //      FileOutputStream fos = new FileOutputStream(f);
            myBitmap.compress(JPEG, 90, fo);
            fo.write(bytes.toByteArray());
            MediaScannerConnection.scanFile(this,
                    new String[]{f.getPath()},
                    new String[]{"image/jpeg"}, null);
            fo.close();
            Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());

            return f.getAbsolutePath();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return "";
    } 

 public void activeTakePhoto() {// it will go on camera intent
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getApplicationContext().getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File

            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
            }
        }

    }

答案 1 :(得分:0)

由于作用域存储,我们无法将图像直接写入所需的文件夹,然后更新MediaStore。取而代之的是,Android Q引入了一个新字段MediaStore.Images.Media.RELATIVE_PATH,我们可以在其中指定图像的路径(例如"Pictures/Screenshots/")。

有关更多信息,请参阅this博客的“将照片保存到图库”部分。