58 votes

L'extraction d'une image de Gallery à partir des dossiers synchronisés de Picasa/Google + ne fonctionne pas.

J'essaie d'obtenir une image de l'application Galerie à partir de l'un des dossiers des photos synchronisées de Google+. Après avoir sélectionné l'image, l'Uri est renvoyé correctement. Mais lorsque j'essaie d'obtenir le chemin d'accès réel de cette image sur le périphérique de stockage, afin de pouvoir l'utiliser, l'application se bloque. Le problème semble être spécifiquement lié à l'option fournisseur de contenu picasa .

Testé sur Nexus S et Nexus 7, ainsi que sur d'autres appareils.

E/AndroidRuntime(14572): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.google.android.gallery3d.provider/picasa/item/5427003652908228690 }}

Ici, le champ dat semble transmettre correctement l'Uri, mais lorsque j'essaie de récupérer l'emplacement de l'image, le système se bloque avec l'erreur suivante.

W/GalleryProvider(14381): unsupported column: \_data

Il semble que le fournisseur de contenu pour les albums Picasa ne dispose pas d'un champ _data.

Le code pour obtenir l'emplacement est :

// imageUri is the Uri from above.
String\[\] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(imageUri, proj,null, null, null);
int column\_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();

String filePath = cursor.getString(column\_index);
cursor.close();

Les seules colonnes qui semblent être supportées pour cette image sont : [user_account, picasa_id, _display_name, _size, mime_type, datetaken, latitude, longitude, orientation].

Comment obtenir l'emplacement réel de cette image. Et si nous ne sommes pas censés travailler avec cette image, ces images ne devraient pas être montrées à l'utilisateur en premier lieu.

L'intention de lancer l'application de la galerie est :

Intent intent = new Intent();
intent.setType("image/\*");
intent.setAction(Intent.ACTION\_GET\_CONTENT);

15voto

drindt Points 69

J'ai perdu beaucoup d'heures et maintenant j'ai trouvé une solution qui fonctionne dans tous les cas sans téléchargement magique dans des fils spéciaux ou autre. La méthode suivante renvoie un flux du contenu que l'utilisateur a sélectionné et cela fonctionne avec tout ce qui est dans la nature.

FileInputStream getSourceStream(Uri u) throws FileNotFoundException {
    FileInputStream out = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        ParcelFileDescriptor parcelFileDescriptor =
                mContext.getContentResolver().openFileDescriptor(u, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        out = new FileInputStream(fileDescriptor);
    } else {
        out = (FileInputStream) mContext.getContentResolver().openInputStream(u);
    }
    return out;
}

7voto

Kumar Bibek Points 5768

Après de nombreuses recherches, j'ai estimé qu'il y avait trop de solutions de contournement pour faire quelque chose qui semble être très simple. J'ai donc écrit une petite bibliothèque qui gère tous les "si" complexes et qui fonctionne pour tous les scénarios possibles auxquels je peux penser. Essayez-la et voyez si elle vous aide.

http://techdroid.kbeanie.com/2013/03/easy-image-chooser-library-for-Android.html

Il s'agit d'une mise en œuvre initiale. Bien qu'elle gère presque toutes les situations, il pourrait y avoir quelques bogues. Si vous utilisez cette bibliothèque, merci de me faire part de vos réactions et de me dire si elle peut encore être améliorée.

5voto

Leonidos Points 6450

J'ai rencontré le même problème il y a environ un an Je vous montre ma solution (le code est assez désordonné, merci de le refactoriser). Donc, vous avez l'image URI qui a été retournée par la galerie :

    ImageInfo getImage(URI imageUri) {

        ImageInfo result = null;

        final String[] cursorColumns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION};

        // some devices (OS versions return an URI of com.android instead of com.google.android
        if (imageUri.toString().startsWith("content://com.android.gallery3d.provider"))  {
            // use the com.google provider, not the com.android provider.
            imageUri = Uri.parse(imageUri.toString().replace("com.android.gallery3d","com.google.android.gallery3d"));
        }

        Cursor cursor = App.getContext().getContentResolver().query(imageUri, cursorColumns, null, null, null);
        if (cursor != null) {

            int dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            int orientationColumnIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION);

            cursor.moveToFirst();

            // if it is a picasa image on newer devices with OS 3.0 and up
            if (imageUri.toString().startsWith("content://com.google.android.gallery3d")) {

                result = new ImageInfo(downloadImage(imageUri), "0");                       

            } else { // it is a regular local image file

                result = new ImageInfo(cursor.getString(dataColumnIndex), cursor.getString(orientationColumnIndex));

            }

            cursor.close();

        } else {
            result = new ImageInfo(downloadImage(imageUri), "0");
        }

        return result;                      
}

Et maintenant nous avons besoin d'une fonction pour télécharger l'image :

private String downloadImage(URI imageUri) {

    File cacheDir;
    // if the device has an SD card
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
        cacheDir = new File(android.os.Environment.getExternalStorageDirectory(),".OCFL311");
    } else {
        // it does not have an SD card
        cacheDir = App.getContext().getCacheDir();
    }

    if(!cacheDir.exists()) cacheDir.mkdirs();
    File f = new File(cacheDir, PUT_HERE_FILE_NAME_TO_STORE_IMAGE);

    try {

        InputStream is = null;
        if (imageUri.toString().startsWith("content://com.google.android.gallery3d")) {
            is = App.getContext().getContentResolver().openInputStream(imageUri);
        } else {
            is = new URL(imageUri.toString()).openStream();
        }

        OutputStream os = new FileOutputStream(f);
        Utils.InputToOutputStream(is, os);

        return f.getAbsolutePath();
    } catch (Exception ex) {
        Log.d(this.getClass().getName(), "Exception: " + ex.getMessage());
        // something went wrong
        ex.printStackTrace();
        return null;
    }
}

ImageInfo est ma classe pour stocker le chemin vers l'image et son orientation.

public static class ImageInfo {
    public final String filePath;
    public final String imageOrientation;

    public ImageInfo(String filePath, String imageOrientation) {
        this.filePath = filePath;

        if (imageOrientation == null) imageOrientation = "0";
        this.imageOrientation = imageOrientation;           
    }
}

0voto

naveed ahmad Points 1005

J'ai utilisé cette approche, qui fonctionne bien pour moi, J'espère que cela vous aidera ....

ACTIVITYRESULT_CHOOSEPICTURE est l'int que vous utilisez lorsque vous appelez startActivity(intent, requestCode) ;

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if(requestCode == ACTIVITYRESULT_CHOOSEPICTURE) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    final InputStream ist = ontext.getContentResolver().openInputStream(intent.getData());
    final Bitmap bitmap = BitmapFactory.decodeStream(ist, null, options);
    ist.close();
  }
}

Si le code ci-dessus ne fonctionne pas, référez-vous à ce lien... il vous montrera certainement la voie à suivre.

http://dimitar.me/how-to-get-picasa-images-using-the-image-picker-on-Android-devices-running-any-os-version/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X