简体   繁体   中英

How to get actual path of image from Uri in Android Q?

I'm taking picture using camera and selecting from gallery. After that doing compression to reduce file size. I was using getRealPathFromURI() method to get actual image path, but in Android Q MediaStore.Images.Media.DATA is deprecated.

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)
}

As per documentation I tried openFileDescriptor() to gain access:

private fun getBitmapFromUri(context: Context, uri: Uri): Bitmap {
    val parcelFileDescriptor = context.contentResolver.openFileDescriptor(uri, "rw")
    val fileDescriptor = parcelFileDescriptor?.fileDescriptor
    val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
    parcelFileDescriptor?.close()
    return image
}

also tried this

Due to Scoped Storage, we can't write the image directly to the desired folder and then update the MediaStore . Instead, Android Q introduces a new field MediaStore.Images.Media.RELATIVE_PATH in which we can specify the path of the image (for example, "Pictures/Screenshots/" ).

Please refer "Saving a photo to the gallery" section of this blog for more information.

for loading image from gallery you can use it and you have the create provide in manifest

<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>

create your @xml/provide_paths like this

<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>

code:

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);

    }

and for capture image in on Activity use

 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);
            }
        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM