Android: получение растрового изображения из стороннего приложения (например, WhatsApp) через content://URI

Я пытаюсь получить изображение из стороннего приложения (например, WhatsApp) в свое приложение (тестируется на Marshmallow). Когда я «делюсь изображением» из WhatsApp и делюсь им со своим приложением, я получаю URI примерно такого вида:

content://com.whatsapp.provider.media/item/61025

Но в моем приложении, когда я вызываю getContentResolver().openInputStream(uri) или getContentResolver().openFileDescriptor(uri, "r") с указанным выше URI, происходит сбой с исключением:

java.lang.SecurityException: Отказ в разрешении: открытие провайдера com.whatsapp.MediaProvider из ProcessRecord{a4b804a 30321:com.myapp/u0a145} (pid=30321, uid=10145), который не экспортируется из uid 10083

Что я уже пробовал

Я искал это исключение на SO и нашел похожий вопрос, но для импорта изображений из Google Фото и получил, что нужно добавить разрешение нравится:

<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>

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

В некоторых других ответах было предложено немедленно прочитать/скопировать данные от поставщика контента. Но не знаю как. Потому что я получаю исключение в самом openInputStream.

Я также должен упомянуть, что изображение WhatsApp может быть успешно передано другим приложениям (например, Google Диску), поэтому должен быть какой-то способ сделать это.

Пожалуйста, кто-нибудь может дать подсказки или рабочее решение по этому поводу?


comment
Есть ли у вас разрешение на чтение из внешнего хранилища и проверка во время выполнения?   -  person Nabin Bhandari    schedule 05.10.2017
comment
этот провайдер не экспортируется, только некоторые ограниченные пакеты могут получить к нему доступ (например, Google Drive), но вашему приложению это не разрешено.   -  person pskink    schedule 05.10.2017
comment
@ Набин да, у меня есть разрешение   -  person Atul    schedule 05.10.2017
comment
@pskink Если это так, то каковы будут критерии. Потому что я пробовал с некоторыми другими приложениями, отличными от Google (например, приложение для редактирования изображений InShot, передача файлов Xender), и оно работает с ними. В любом случае, это задокументировано где-нибудь, пожалуйста, поделитесь ссылкой. Спасибо.   -  person Atul    schedule 05.10.2017
comment
Опубликуйте код, который вы пробовали, включая manifest. Возникает ли эта проблема при обмене данными только из WhatsApp или из других приложений? А из галереи?   -  person Nabin Bhandari    schedule 05.10.2017
comment
@Nabin Я заметил, что это происходит, когда мое приложение получает совместно используемое изображение через uri контента (content://), а не когда оно получает uri файла (file://). Поскольку галерея и другие приложения, которые я пробовал, делились своими изображениями, используя файл uri, поэтому я не получил исключения. Но WhatsApp дает мне контент URI своих изображений.   -  person Atul    schedule 05.10.2017
comment
@Nabin: код приложения слишком велик, чтобы делиться им. Но нет ничего особенного, пока речь идет об этом крахе. Я просто передаю входной URI в getContentResolver().openInputStream(uri), и он тут же падает, особенно когда uri является содержимым uri из WhatsApp.   -  person Atul    schedule 05.10.2017


Ответы (1)


В порядке. Я нашел, где была проблема. В начальной активности моего приложения я сохранял URI контента (который я получил от стороннего приложения, такого как WhatsApp или Chrome и т. д., например, для content://com.whatsapp.provider.media/item/61025) в массиве и обращался к нему из другая деятельность.

Это было неправильно. Я получил подсказку из этого ответа, и я вызвал getContentResolver().openInputStream(uri) прямо из активности запуска приложения сразу после получения общего содержимого. И это сработало, никаких исключений не было.

person Atul    schedule 06.10.2017
comment
можете ли вы предоставить пример кода для получения пути fromcontent://com.whatsapp.provider.media/item/45856 - person Rafiq Ahmad; 31.10.2017
comment
не пытайтесь получить путь из URI. Это неправильный способ работы с URI. Вместо этого используйте getContentResolver().openInputStream(uri) - person Atul; 31.10.2017
comment
getContentResolver().openInputStream(uri), что он возвращает?? я в полном замешательстве - person Rafiq Ahmad; 03.11.2017
comment
getContentResolver().openInputStream возвращает InputStream, который вам нужно прочитать для общих данных. Например, если это данные изображения, вы можете вызвать BitmapFactory.decodeStream. Пожалуйста, Google, как читать данные из InputStream. - person Atul; 03.11.2017
comment
Спасибо за объяснение, я решил это. Он возвращал растровое изображение из BitmapFactory.decodeStream, и оттуда я получил путь. Потребовалось 2 дня, эй! +1 за вашу помощь. - person Rafiq Ahmad; 03.11.2017