How to find Uri from Gallery on Android 7 nougat

Asked

Viewed 278 times

1

I’m making an application where I search an image in the Android Nougat gallery and send it to a server. However I am not able to recover Uri with the image address to send.

if(camera.equals("galeria")){
        startActivityForResult(getPickImageChooserIntentGaleria(), 150);
    }
    else{
        startActivityForResult(getPickImageChooserIntentGaleria(), 200);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Bitmap bitmap;
        if (requestCode == 200) {
            ImageView imageView = (ImageView) findViewById(R.id.iv_img_imagem);
            if (getPickImageResultUri(data) != null) {
                picUri = getPickImageResultUri(data);

                try {
                    myBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri);
                    myBitmap = rotateImageIfRequired(myBitmap, picUri);
                    myBitmap = getResizedBitmap(myBitmap, 500);
                    imageView.setImageBitmap(myBitmap);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                bitmap = (Bitmap) data.getExtras().get("data");
                myBitmap = bitmap;
                imageView.setImageBitmap(myBitmap);
            }
        }

        if (requestCode == 150) {
            Uri selectedImage = data.getData();

            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
            ImageView imageView = (ImageView) findViewById(R.id.iv_img_imagem);
            imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
            try {
                Uri originalUri = data.getData();
                String pathsegment[] = originalUri.getLastPathSegment().split(":");
                String id = pathsegment[0];
                final String[] imageColumns = { MediaStore.Images.Media.DATA };

                Uri uri = getUri();
                Cursor imageCursor = this.getContentResolver().query(uri, imageColumns, MediaStore.Images.Media._ID + "=" + id, null, null);

                if (imageCursor.moveToFirst()) {
                    String value = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                    picUri = Uri.parse(value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    private Uri getUri() {
        String state = Environment.getExternalStorageState();
        if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
            return MediaStore.Images.Media.INTERNAL_CONTENT_URI;
        return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    }

For requestCode == 150 I get the following error message:

E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-VINHOS.jpg: open failed: EACCES (Permission denied)

And for requestCode == 200 I get the following error message:

java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference

I’m using this project as a base: http://www.journaldev.com/13270/android-capture-image-camera-gallery#comment-39227

When the image capture is done by the camera it is possible to get the path of Uri correctly, but when it is by Gallery the value in Uri is like this:

picUri = content://media/external/images/media/5168
picUri.getPath() = /external/images/media/5168

I need to receive Uri in this format

/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-VINHOS.jpg

I would like some help to solve this problem.

  • Please see this link https://developer.android.com/training/permissions/requesting.html?hl=pt-br

  • Voce needs to request permission at runtime

3 answers

1

I was able to solve the problem as follows: In the code I used as a base, I added the permission: Permissions.add(READ_EXTERNAL_STORAGE);

thus remaining :

    permissions.add(CAMERA);
    permissions.add(READ_EXTERNAL_STORAGE);
    permissionsToRequest = findUnAskedPermissions(permissions);
    //get the permissions we have asked for before but are not granted..
    //we will store this in a global list to access later.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (permissionsToRequest.size() > 0)
            requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]), ALL_PERMISSIONS_RESULT);
    }

0

From the Android 6.0 (API level 23), users grant permissions to applications while they are running, not when they are installed.

This approach optimizes the application installation process as the user does not need to grant permissions when installing or updating the application.

It also gives the user more control over the application’s features.

For example, a user could choose to allow a camera app access to the camera, but not the location of the device. The user can revoke permissions at any time on the application’s Settings screen.

Add the following line into your AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Activity

  import android.content.pm.PackageManager;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.Toast;

    public class MessageView extends AppCompatActivity {

        private final int CODE_PERMISSION = 123;
        @Override
        protected void onResume() {
            super.onResume();
            checkPermission();
        }

        private void checkPermission() {
            // Verifica necessidade de verificacao de permissao
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                // Verifica necessidade de explicar necessidade da permissao
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_PERMISSION);
                } else {
                    // Solicita permissao
                    ActivityCompat.requestPermissions(this,
                            new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                            CODE_PERMISSION);
                }
            }
        }

        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            // Verifica resultado
            if (requestCode == CODE_PERMISSION) {
                if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "É necessário a permissão para continuar!", Toast.LENGTH_SHORT).show();
                }
            }
        }


    }
  • The project I am using as a base already has this permission, but also includes this code and I did not get the URI from the gallery. http://www.journaldev.com/13270/android-capture-image-camera-gallery#comment-39227

0

data.getData() Return to the Language Intent.ACTION_OPEN_DOCUMENT

  • The result of this suggestion was: data.getData() = content://com.android.providers.media.Documents/Document/image%3A5168

Browser other questions tagged

You are not signed in. Login or sign up in order to post.