Выбор фотографии с помощью нового приложения Google Фото не работает

Мое приложение имеет возможность выбрать фотографию из библиотеки. Именно я хочу путь к файлу из этого выбора.

Это код для создания цели выбора фотографии:

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

Это код, который получает путь к файлу из 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;

До вчерашнего обновления приложения Google Photos все работало отлично. Сейчас path является нулевым после анализа URI.

URI похож на это: content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209/ACTUAL

Я также пытался создать намерение с помощью действия Intent.ACTION_GET_CONTENT - не повезло.

2 ответа

Решение

Ниже код работает для меня, чтобы получить URI контента на последних Google Фото. То, что я пробовал, - это запись во временный файл и возврат URI временного изображения, если он имеет права доступа к URI содержимого.

Вы можете попробовать то же самое:

public 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 {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return null;
}

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

Это, безусловно, обходной путь, но вы можете извлечь реальный URI контента, который по какой-то причине стал встроенным: content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209

Я смог создать новый URI с authority=media and path=external/images/media/xxxи преобразователь содержимого вернул реальный URL.

Пример кода:

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

Я знаю, что этот вопрос немного устарел, но я сделал следующее, чтобы получить изображение из галереи и использовать его. Ниже приведена функция расширения для того же самого.

fun Uri.toBitmap(context: Context?): Bitmap {
    return MediaStore.Images.Media.getBitmap(context?.contentResolver, this)
}

Требуется контекст в качестве параметра для получения contentResolver и Uri, полученных от onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?).

Чтобы использовать, просто сделайте следующее:

intent?.data.toBitmap(context)

где intent?.data это Uri, полученный от onActivityResult().

Другие вопросы по тегам