web-dev-qa-db-fra.com

Le choix de la photo à l'aide de la nouvelle application Google Photos est rompu

Mon application a la possibilité de sélectionner une photo dans la bibliothèque. Exactement, je veux le chemin du fichier de cette sélection.

Voici le code pour créer l'intention de sélectionner une photo:

    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    photoPickerIntent.setType("image/*");
    startActivityForResult(photoPickerIntent, INTENT_REQUEST_CODE_SELECT_PHOTO);

Voici le code qui obtient le chemin du fichier depuis l'URI:

    Cursor cursor = null;
    String path = null;
    try {
        String[] projection = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
        int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
        cursor.moveToFirst();
        path = cursor.getString(columnIndex);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return path;

Avant la mise à jour d'hier de l'application Google Photos, tout fonctionnait parfaitement bien. Maintenant, path est nul après l'analyse de l'URI.

L'URI est similaire à ceci: content://com.google.Android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209/ACTUAL

J'ai également essayé de créer une intention avec l'action Intent.ACTION_GET_CONTENT - pas de chance.

46
Den Rimus

Le code ci-dessous me permet également d'obtenir l'URI du contenu sur les dernières photos Google. Ce que j'ai essayé, c'est d'écrire dans un fichier temporaire et de renvoyer l'URI de l'image temporaire, s'il a autorité sur l'URI de contenu.

Vous pouvez essayer la même chose:

private static String getImageUrlWithAuthority(Context context, Uri uri)
{
    InputStream is = null;

    if (uri.getAuthority() != null)
    {
        try
        {
            is = context.getContentResolver().openInputStream(uri);
            Bitmap bmp = BitmapFactory.decodeStream(is);
            return writeToTempImageAndGetPathUri(context, bmp).toString();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (is != null)
                {
                    is.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    return null;
}

private static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage)
{
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}
47
Akhil

Il s'agit très certainement d'une solution de contournement, mais vous pouvez extraire l'URI de contenu réel qui a apparemment été intégré pour une raison quelconque: content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209

J'ai pu créer un nouvel URI avec authority=media and path=external/images/media/xxx, et le résolveur de contenu a renvoyé une véritable URL.

Exemple de code:

String unusablePath = contentUri.getPath();
int startIndex = unusablePath.indexOf("external/");
int endIndex = unusablePath.indexOf("/ACTUAL");
String embeddedPath = unusablePath.substring(startIndex, endIndex);

Uri.Builder builder = contentUri.buildUpon();
builder.path(embeddedPath);
builder.authority("media");
Uri newUri = builder.build();
6
Jon Rogstad