web-dev-qa-db-fra.com

Image de Galerie dans Android 6(Marshmallow)

Dans mon application, j'essaie de sélectionner une image dans la cuisine afin de la transmettre au serveur.

Le code fonctionne bien sur Android 5 et les versions antérieures, mais pour Android 6 sur Nexus 5, je ne parviens pas à obtenir les informations sur l'image.Journal trace que j'ai obtenu

Remarque : Le code fonctionne correctement sous Android 5 et versions antérieures

11-06 12:27:43.736: W/System.err(31678): Java.lang.SecurityException: Permission Denial: reading com.google.Android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.Android.apps.photos.contentprovider/0/1/content%3A//media/external/images/media/19138/ACTUAL/94710853 from pid=31678, uid=10111 requires the provider be exported, or grantUriPermission()
11-06 12:27:43.757: W/System.err(31678): 
at Android.os.Parcel.readException(Parcel.Java:1599)
11-06 12:27:43.757: W/System.err(31678): 
at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:183)
11-06 12:27:43.757: W/System.err(31678): 
at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:135)
11-06 12:27:43.757: W/System.err(31678): 
at Android.content.ContentProviderProxy.query(ContentProviderNative.Java:421)
11-06 12:27:43.757: W/System.err(31678): 
at Android.content.ContentResolver.query(ContentResolver.Java:491)
11-06 12:27:43.757: W/System.err(31678): 
at Android.content.ContentResolver.query(ContentResolver.Java:434)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.ContentFilesystem.openCursorForURL(ContentFilesystem.Java:258)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.ContentFilesystem.getFileMetadataForLocalURL(ContentFilesystem.Java:169)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.FileUtils.getFileMetadata(FileUtils.Java:822)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.FileUtils.access$500(FileUtils.Java:52)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.FileUtils$15.run(FileUtils.Java:394)
11-06 12:27:43.758: W/System.err(31678): 
at org.Apache.cordova.file.FileUtils$25.run(FileUtils.Java:551)
11-06 12:27:43.758: W/System.err(31678): 
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1113)
11-06 12:27:43.758: W/System.err(31678): 
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:588)
11-06 12:27:43.758: W/System.err(31678): 
at Java.lang.Thread.run(Thread.Java:818)
10
Harsh

FAITES-le de cette façon…. Sur le bouton Cliquez sur Vérifier la version du SDK 

 if (Build.VERSION.SDK_INT >= 23){
    // Here, thisActivity is the current activity
                        if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.READ_EXTERNAL_STORAGE)
                                != PackageManager.PERMISSION_GRANTED) {

                            // Should we show an explanation?
                            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                    Manifest.permission.READ_EXTERNAL_STORAGE)) {

                                // Show an expanation to the user *asynchronously* -- don't block
                                // this thread waiting for the user's response! After the user
                                // sees the explanation, try again to request the permission.

                            } else {

                                // No explanation needed, we can request the permission.

                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                        MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

                                // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
                                // app-defined int constant. The callback method gets the
                                // result of the request.
                            }
                        }else{
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                        }
                    }else {

                        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                        photoPickerIntent.setType("image/*");
                        startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                    }

après cela, dans la méthode Override, onRequestPermissionsResult écrit ce code:

 case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                    photoPickerIntent.setType("image/*");
                    startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

Après ça

@Override
    protected void onActivityResult(int reqCode, int resultCode, Intent data) {
        super.onActivityResult(reqCode, resultCode, data);

        switch (reqCode) {
 case SELECT_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        final Uri imageUri = data.getData();
                        final InputStream imageStream = getContentResolver().openInputStream(imageUri);
                        final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                        contactimage.setImageBitmap(selectedImage);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }
21
Ashwani

Je crois que vous devrez demander les autorisations à l'utilisateur au moment de l'exécution (il s'agit de l'un des changements les plus remarquables d'api 22 à 23).

Vous pouvez essayer cet extrait, extrait de la page de permission de Android Developers .

if (Build.VERSION.SDK_INT >= 23){    
// Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
  }

Faites-moi savoir si cela vous a aidé.

5
mmark

J'ai eu le même problème. L'image affichée dans Imageview après avoir sélectionné l'image dans la galerie à l'aide de 

Intent galleryIntent = new Intent(Intent.ACTION_PICK, Android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, videoIdentifier);

et décodage de l'image bitmap à partir de l'URI

Mais enregistrer l'URI pour une utilisation future, rouvrir l'application et réutiliser l'URI enregistré n'a pas fonctionné. Impossible de décoder le bitmap de l'URI.

J'ai résolu le problème en extrayant le contenu d'origine uri du chemin d'URI

public String RemoveUnwantedString(String pathUri){
    //pathUri = "content://com.google.Android.apps.photos.contentprovider/-1/2/content://media/external/video/media/5213/ORIGINAL/NONE/2106970034"
    String[] d1 = pathUri.split("content://");
    for (String item1:d1) {
        if (item1.contains("media/")) {
            String[] d2 = item1.split("/ORIGINAL/");
            for (String item2:d2) {
                if (item2.contains("media/")) {
                    pathUri = "content://" + item2;
                    break;
                }
            }
            break;
        }
    }
    //pathUri = "content://media/external/video/media/5213"
    return pathUri;
}
2
Abi

Pour obtenir une image de la galerie dans Marshmallow, vous devez accorder le droit d'accès à READ_EXTERNAL_STORAGE lors de l'exécution. Android Version M a changé la manière dont les autorisations sont accordées aux applications.

Avant Marshmallow, toutes les autorisations requises sont accordées en même temps, c'est-à-dire au moment de l'installation. Mais dans Marshmallow, une autorisation est demandée à l'utilisateur uniquement si cette autorisation est requise, et l'utilisateur doit autoriser ou refuser cette autorisation.

Ci-dessous, deux liens vous aideront davantage. Link 1 est issu de la documentation officielle d'Android et Link 2 est un blog qui a expliqué ce problème à l'aide d'un exemple concret.

Link1: http://developer.Android.com/training/permissions/requesting.html

Link2: http://inthecheesefactory.com/blog/things-you-need-to-know-about-Android-m-permission-developer-edition/fr

2
Muhammad Ibrahim

Essaye ça

C'est la méthode simple que j'ai créée avec d'autres exemples

  1. appelez la méthode CHECKGALLERYPERMISSION () où vous voulez et collez le code dans la méthode

     private void CHECKGALLERYPERMISSION()
     {
        int MY_READ_PERMISSION_REQUEST_CODE =1 ;
        int PICK_IMAGE_REQUEST = 2;
        if (ContextCompat.checkSelfPermission(YourActivity.this, Android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED)
        {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
        }
        else
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            {
                requestPermissions(
                        new String[]{Android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        MY_READ_PERMISSION_REQUEST_CODE);
            }
            else
            {
            }
        }
      }
      @Override
      public void onRequestPermissionsResult(int requestCode, String[] 
      permissions, int[] grantResults) {
       if (requestCode == MY_READ_PERMISSION_REQUEST_CODE
            && grantResults[0] == PackageManager.PERMISSION_GRANTED)
       {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
    }
       }
      @Override
       public void onActivityResult(int requestCode, int resultCode, Intent data)
      {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null)
    {
        Uri uri = data.getData();
        try
        {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(YourActivity.this.getContentResolver(), uri);
            imageview.setImageBitmap(bitmap);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
      }
    

Remarque

  1. en mode fractionné, utilisez getactivity () au lieu de activity.this
  2. si Android.Manifest.permission.READ_EXTERNAL_STORAGE ne fonctionne pas, remplacez-le par Manifest.permission.READ_EXTERNAL_STORAGE partout
0
Sunil