Content com android providers media documents document image 599

Копировать изображение из фото-библиотеки android вызывает ошибку

Получить эту ошибку, когда я пытаюсь разрешить локальную файловую систему uri по телефонной запинке:

Я использую камеру для доступа к фотобиблиотеке и получаю этот файл_юри:

Затем я пытаюсь получить доступ к локальной файловой системе:

Вот где я получаю эту ошибку:

Btw: Я пробовал этот сценарий на iOS, и он работает без проблем.

Вот простое решение этой проблемы:

Если вы используете JavaScript, вы можете использовать этот код:

Этот метод заставляет uri пропускать «% 3A» так, как он есть, не меняя его на «:»,

Всякий раз, когда некоторый uri передается в он неявно декодируется из

Content: //com.android.providers.media.documents/document/image%3A9888 (1)

Content: //com.android.providers.media.documents/document/image: 9888 (2)

Однако после возвращения из Intent.ACTION_OPEN_DOCUMENT или Intent.ACTION_GET_CONTENT Android предоставляет вам разрешение на чтение для (1) , а не (2) . В этом случае WebView будет WebView ошибки журнала:

Java.lang.SecurityException: отказ в разрешении: чтение com.android.providers.media.MediaDocumentsProvider uri content: //com.android.providers.media.documents/document/image: 9888 из pid = 13163, uid = 10165 требует андроида. Разрешение.MANAGE_DOCUMENTS или grantUriPermission ()

Не удалось открыть URL-адрес контента

Фрагмент кода

Все, что вам нужно для решения проблемы

В вашем Java-коде перед передачей uri в HTML / JS, чтобы гарантировать, что (1) будет фактически загружен.

Я тестировал это на 4.4.2, 4.4.4 и 5.0. Самое забавное, что Android 4.4.2 дважды декодирует uri .

Источник

Uri изображения не отображает изображения в ImageView на некоторых устройствах android

у меня есть ImageView. Когда вы нажимаете на ImageView, он открывает галерею, и вы выбираете изображение и показываете его на ImageView. У меня есть условие, что когда я закрываю свое приложение, а затем открываю его, изображение сохранится там . Поэтому для этого я сохраняю Uri изображения на sharedprefrence. И при открытии приложения я получаю тот же Uri и пытается отобразить изображение на imageView.

однако в некоторых телефонах-изображение выглядит идеально, как Mi (Lollipop), Samsung (KitKat) но это не отображается в телефонах типа-Motorola (Marshmallow) ,One Plus One (Marshmallow). Есть идеи, почему это происходит ? Вот мой код

для сбора изображения, которое я использую

и на onActivityResult () код

и при извлечении из sharedprefrence я конвертирую строку в uri с помощью Uri.parse(profile_image)

однако, если я замечу, uri возвращается для разных телефонов android следующим образом

следовательно, когда содержимое uri is-content: / / media / external/images/ media / is отображение изображения на ImageView идеально, а в других случаях это не

11 ответов

попробуй такое

я разработал и tested и работает на

  1. Lenovo K3 Примечание (Зефир)
  2. Motorola (Леденец)
  3. Samsung (KitKat)

в своем MainActivity.java добавить

Теперь Ручка onActivityResult .

в своем Добавить permission

Примечание:

Assuming вы добавили код take permission на Marshmallow

результат Uri

lenovo K3 Примечание: content://com.android.externalstorage.documents/document/primary%3ADCIM%2FCamera%2FIMG_20160606_212815.jpg

samsung: content://com.android.providers.media.documents/document/image%3A2086

motorola: content://com.android.providers.media.documents/document/image%3A15828

Я думаю, что проблема с uri файла изображения, я использую класс для получения точного URI, и он протестирован и работает на всех версиях.

используйте getPath, чтобы найти точный путь к файлу. Это простой способ справиться с проблемой, как вы определили. Пожалуйста, попробуйте и дайте мне знать, если вам нужна дополнительная помощь 🙂

‘в предыдущих версиях Android, Если вы хотите, чтобы ваше приложение, чтобы получить определенный тип файла из другого приложения, он должен вызвать намерение с ACTION_GET_CONTENT действие. Это действие по-прежнему является подходящим способом запроса файла, который вы хотите импорт в вашем приложении. Тем не менее, Android 4.4 вводит ACTION_OPEN_DOCUMENT действие, которое позволяет пользователю выберите файл определенного типа и предоставьте вашему приложению долгосрочный доступ для чтения к этому файлу (возможно, с доступом на запись) без импорта файла в приложение.(подчеркнуто)

чтобы ваше приложение могло извлекать ранее выбранные изображения, просто измените действие с ACTION_GET_CONTENT to ACTION_OPEN_DOCUMENT (решение подтвердило работу на Nexus 7 2013).

передайте свой URI в этом методе, он вернет строку и преобразует ее в Bitmap

вам нужно запросить разрешение на чтение внешнего хранилища пользователю во время выполнения для Android 6+

надеюсь, что это помогает.

Читайте также:  Регистраторы автомобильные для андроид

возможно, вы можете справиться с этим, сначала преобразовав URI в реальный путь.

и ваш onActivityResult должен выглядеть так

мне удалось сделать это в прошлом. Вместо того, чтобы хранить его в SharePreferences, я сохраняю его в пакете, когда onSaveInstanceState(Bundle) вызывается: bundle.putParcelable (SOME_KEY, uri). Вы можете сделать это, потому что Uri реализует Parcelable. После этого проверьте этот uri в пакете, переданном в onCreate (). Код:

P/S: Я думаю, проблема хранения uri в SharePreference заключается в кодировании / декодировании Uri.

вы можете легко конвертировать URI в Bitmap:

а затем установите в Imageview: imgview.setImageBitmap(изображения);

надеюсь, это поможет вам.

может быть проблема с версиями Пикассо. Они исправили что-то с загрузкой больших изображений в версии 2.5.0 (2.4.0. ), который еще не доступен через репозитории.

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

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

вы можете использовать такие методы, как FileUtils.getPath (контекст, uri) или FileUtils.getFile (context, uri), чтобы получить файл. Тогда просто используйте его так:

надеюсь, что это помогает.

просто не на 100% уверен, если я получу вопрос. Если определенные изображения не могут быть показаны в imageView (даже до закрытия и перезапуска приложения), то проблема в том, что Picasso может обрабатывать содержимое от определенных поставщиков. Я не понимаю, что это так, но если это так, то вы можете рассмотреть возможность подачи ошибки/RFE для этой библиотеки. С другой стороны, если Picasso правильно показывает изображение для данного Uri, но не после Uri_org — > String — > Uri_regen преобразование тогда это означает, что Uri_org не то же самое, что Uri_regen. Вы можете (временно) добавить пару строк кода, чтобы преобразовать строку обратно в Uri и поставить точку останова сразу после и сравнить два Uri. Это должно дать вам ключ к тому, как все идет не так.

Если вы не нажмете точку останова, затем переместите точку останова обратно в Оператор » if » и визуально проверьте два Uri (которые почти наверняка будут одинаковыми, иначе у вас было бы нажмите точку останова,но это поможет проверить сам код отладки). Если URI такие же, то строки предпочтение не правильно сохранился почему-то. В этом случае запишите исходный Uri и добавьте точку останова в строке, которая преобразует строку обратно в Uri:

Если предыдущий эксперимент работал, он должен снова работать здесь, если profile_image не отличается. В любом случае вы должны получить указатели на то, где проблема есть.

Источник

access content://com.android.providers.media.documents/document/image%3A99 #351

Comments

EyalSi commented Sep 26, 2017

I’m getting a content uri in android while using react-native-document-picker or react-native-contacts (for the avatars).
URIs like:
‘content://com.android.providers.media.documents/document/image%3A99’
Trying to access this file fails with «File does not exist»

const urlDecoded = decodeURIComponent(url);
RNFS.stat(urlDecoded)
.then((file) => <
console.log(«RNFS URL SUCCESS», file);
>)
.catch((err) => <
console.log(«RNFS URL ERROR», err);
>);

Any idea how to access the file?
10x

The text was updated successfully, but these errors were encountered:

itinance commented Sep 28, 2017

Hi @EyalSi! The scheme «content://» is currently not supported.

PRs are very appreciated.

lukasbowen commented Oct 10, 2017

@itinance Does this still need to be resolved? I saw a PR request that could resolve it but I believe it was rejected?

nzhtrtlc commented Nov 23, 2017

I have the same error, any updates ?

lukasbowen commented Nov 27, 2017

I have a fix locally in my project; however, I am hesitant to create a PR request since there is one that does the same already pending.

itinance commented Nov 27, 2017

@LukBowen which one do you mean?

lukasbowen commented Nov 27, 2017

itinance commented Nov 27, 2017

Yes, i remember. I turned back to the contributor but he never answered. I will modify this PR manually to keep backward compatibility alive.

lukasbowen commented Nov 27, 2017

Sorry, I didn’t realize that was it was missing backwards compatibility. Other wise I would have just create my own PR.

itinance commented Nov 27, 2017

Submitting your own PR would be a good option! I would merge quickly (while CET-timezone 😉 )

lukasbowen commented Nov 27, 2017

I can still do it; however, it will have to be later today. Currently working on a separate project at work.

itinance commented Nov 27, 2017

Great and many thanks. No rush 🙂

krzysztof-miemiec commented Nov 29, 2017 •

Hey @itinance, I just added a PR based on @jrichardlai’s work. I hope we’ll finally be able to work with content URI’s on Android with no trouble! 🙂

Источник

Content provider (Контент-провайдер)

Что такое контент-провайдер

Контент-провайдер или «Поставщик содержимого» (Content Provider) — это оболочка (wrapper), в которую заключены данные. Если ваше приложение использует базу данных SQLite, то только ваше приложение имеет к ней доступ. Но бывают ситуации, когда данные желательно сделать общими. Простой пример — ваши контакты из телефонной книги тоже содержатся в базе данных, но вы хотите иметь доступ к данным, чтобы ваше приложение тоже могло выводить список контактов. Так как вы не имеете доступа к базе данных чужого приложения, был придуман специальный механизм, позволяющий делиться своими данными всем желающим.

Читайте также:  Автозаполнение от google android

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

В Android существует возможность выражения источников данных (или поставщиков данных) при помощи передачи состояния представления — REST, в виде абстракций, называемых поставщиками содержимого. Базу данных SQLite можно заключить в поставщик содержимого. Чтобы получить данные из поставщика содержимого или сохранить в нём новую информацию, нужно использовать набор REST-подобных идентификаторов URI. Например, если бы вам было нужно получить набор книг из поставщика содержимого, в котором заключена электронная библиотека, вам понадобился бы такой URI (по сути запрос к получению всех записей таблицы books):

Чтобы получить из библиотеки конкретную книгу (например, книгу №23), будет использоваться следующий URI (отдельный ряд таблицы):

Любая программа, работающая в устройстве, может использовать такие URI для доступа к данным и осуществления с ними определенных операций. Следовательно, поставщики содержимого играют важную роль при совместном использовании данных несколькими приложениями.

Встроенные поставщики

В Android используются встроенные поставщики содержимого (пакет android.provider). Вот неполный список поставщиков содержимого:

На верхних уровнях иерархии располагаются базы данных, на нижних — таблицы. Так, Browser, СаllLog, Contacts, MediaStore и Settings — это отдельные базы данных SQLite, инкапсулированные в форме поставщиков. Обычно такие базы данных SQLite имеют расширение DB и доступ к ним открыт только из специальных пакетов реализации (implerentation package). Любой доступ к базе данных из-за пределов этого пакета осуществляется через интерфейс поставщика содержимого.

Создание собственного контент-провайдера

Для создания собственного контент-провайдера нужно унаследоваться от абстрактного класса ContentProvider:

В классе необходимо реализовать абстрактные методы query(), insert(), update(), delete(), getType(), onCreate(). Прослеживается некоторое сходство с созданием обычной базы данных.

А также его следует зарегистрировать в манифесте с помощью тега provider с атрибутами name и authorities. Тег authorities служит для описания базового пути URI, по которому ContentResolver может найти базу данных для взаимодействия. Данный тег должен быть уникальным, поэтому рекомендуется использовать имя вашего пакета, чтобы не произошло путаницы с другими приложениями, например:

Источник поставщика содержимого аналогичен доменному имени сайта. Если источник уже зарегистрирован, эти поставщики содержимого будут представлены гиперссылками, начинающимися с соответствующего префикса источника:

Итак, поставщики содержимого, как и веб-сайты, имеют базовое доменное имя, действующее как стартовая URL-страница.

Необходимо отметить, что поставщики содержимого, используемые в Android, могут иметь неполное имя источника. Полное имя источника рекомендуется использовать только со сторонними поставщиками содержимого. Поэтому вам иногда могут встретиться поставщики содержимого, состоящие из одного слова, например contacts, в то время как полное имя такого поставщика содержимого — com.google.android.contacts.

В поставщиках содержимого также встречаются REST-подобные гиперссылки, предназначенные для поиска данных и работы с ними. В случае описанной выше регистрации унифицированный идентификатор ресурса, предназначенный для обозначения каталога или коллекции записей в базе данных NotePadProvider, будет иметь имя:

URI для идентификации отдельно взятой записи будет иметь вид:

Символ # соответствует конкретной записи (ряд таблицы). Ниже приведено еще несколько примеров URI, которые могут присутствовать в поставщиках содержимого:

Обратите внимание — здесь поставщики содержимого content://media и content://contacts имеют неполную структуру. Это обусловлено тем, что данные поставщики содержимого не являются сторонними и контролируются Android.

Структура унифицированных идентификаторов содержимого (Content URI)

Для получения данных из поставщика содержимого нужно просто активировать URI. Однако при работе с поставщиком содержимого найденные таким образом данные представлены как набор строк и столбцов и образуют объект Android cursor. Рассмотрим структуру URI, которую можно использовать для получения данных.

Унифицированные идентификаторы содержимого (Content URI) в Android напоминают HTTP URI, но начинаются с content и строятся по следующему образцу:

Вот пример URI, при помощи которого в базе данных идентифицируется запись, имеющая номер 23:

После content: в URI содержится унифицированный идентификатор источника, который используется для нахождения поставщика содержимого в соответствующем реестре. Часть URI ru.alexanderklimov.provider.notepad представляет собой источник.

/notes/23 — это раздел пути (path section), специфичный для каждого отдельного поставщика содержимого. Фрагменты notes и 23 раздела пути называются сегментами пути (path segments). Одной из функций поставщика содержимого является документирование и интерпретация раздела и сегментов пути, содержащихся в URI.

Читайте также:  Как работает андроид с виндовс

UriMatcher

Провайдер имеет специальный объект класса UriMatcher, который получает данные снаружи и на основе полученной информации создаёт нужный запрос к базе данных.

Вам нужно задать специальные константы, по которым провайдер будет понимать дальнейшие действия. Если используется одна таблица, то обычно применяют две константы — любые два целых числа, например, 100 для таблицы и 101 для отдельного ряда таблицы. Схематично можно изобразить так.

URI pattern Code Contant name
content://ru.alexanderklimov.provider.notepad/notes 100 NOTES
content://ru.alexanderklimov.provider.notepad/notes/# 101 NOTES_ID

В коде с помощью switch создаётся ветвление — хотим ли мы получить информацию о всей таблице (код 100) или к конкретному ряду (код 101).

Приложение может быть сложным и иметь несколько таблиц. Тогда и констант будет больше. Например, так.

URI pattern Code Contant name
content://com.android.contacts/contacts 1000 CONTACTS
content://com.android.contacts/contacts/# 1001 CONTACTS_ID
content://com.android.contacts/lookup/* 1002 CONTACTS_LOOKUP
content://com.android.contacts/lookup/*/# 1003 CONTACTS_LOOKUP_ID
. . .
content://com.android.contacts/data 3000 DATA
content://com.android.contacts/data/# 3001 DATA_ID
. . .

Символ решётки (#) отвечает за число, а символ звёздочки (*) за строку.

Метод query()

Метод query() является обязательным для класса ContentProvider. Если мы используем контент-провайдер для обращения к базе данных, то в нём вызывает одноимённый метод SQLiteDatabase. Состав метода практически идентичен.

Вам нужно программно получить необходимые данные для аргументов метода. Обратите внимание на метод ContentUris.parseId(uri), который возвращает последний сегмент адреса, в нашем случае число 3, для Selection Args.

Метод insert()

Метод insert() содержит два параметра — URI и ContenValues. Первый параметр работает аналогично, как в методе query(). Вторая вставляет данные в нужные колонки таблицы.

Для вставки используется вспомогательный метод insertGuest().

Структурирование МIМЕ-типов в Android

Как веб-сайт возвращает тип MIME для заданной гиперссылки (это позволяет браузеру активировать программу, предназначенную для просмотра того или иного типа контента), так и в поставщике содержимого предусмотрена возможность возвращения типа MIME для заданного URI. Благодаря этому достигается определенная гибкость при просмотре данных. Если мы знаем, данные какого именно типа получим, то можем выбрать одну или несколько программ, предназначенных для представления таких данных. Например, если на жестком диске компьютера есть текстовый файл, мы можем выбрать несколько редакторов, которые способны его отобразить.

Типы MIME работают в Android почти так же, как и в НТТР. Вы запрашиваете у контент-провайдера тип MIME определенного поддерживаемого им URI, и поставщик содержимого возвращает двухчастную последовательность символов, идентифицирующую тип MIME в соответствии с принятыми стандартами.

Обозначение MIME состоит из двух частей: типа и подтипа. Ниже приведены примеры некоторых известных пар типов и подтипов MIME:

text/html
text/css
text/xml
image/jpeg
audio/mp3
video/mp4
application/pdf
application/msword

Основные зарегистрированные типы содержимого:

application
audio
image
message
model
multipart
text
video

В Android применяется схожий принцип для определения типов MIME. Обозначение vnd в типах MIME в Android означает, что данные типы и подтипы являются нестандартными, зависящими от производителя. Для обеспечения уникальности в Android типы и подтипы разграничиваются при помощи нескольких компонентов, как и доменные имена. Кроме того, типы MIME в Android, соответствующие каждому типу содержимого, существуют в двух формах: для одиночной записи и для нескольких записей.

Типы MIME широко используются в Android, в частности при работе с намерениями, когда система определяет по МIМЕ-типу данных, какое именно явление следует активировать. Типы MIME всегда воспроизводятся контент-провайдерами на основании соответствующих URI. Работая с типами MIME, необходимо не упускать из виду три аспекта.

  1. Тип и подтип должны быть уникальными для того типа содержимого, который они представляют. Обычно это каталог с элементами или отдельный элемент. В контексте Android разница между каталогом и элементом может быть не такой очевидной, как кажется на первый взгляд.
  2. Если тип или подтип не являются стандартными, им должен предшествовать префикс vnd (обычно это касается конкретных видов записи).
  3. Обычно типы и подтипы относятся к определенному пространству имен в соответствии с вашими нуждами.

Необходимо еще раз подчеркнуть этот момент: основной тип MIME для коллекции элементов, возвращаемый командой cursor в Android, всегда должен иметь вид vnd.android.cursor.dir, а основной тип MIME для одиночного элемента, находимый командой cursor в Android, — вид vnd.android.cursor.item. Если речь идет о подтипе, то поле для маневра расширяется, как в случае с vnd.googlе.note; после компонента vnd. вы можете свободно выбирать любой устраивающий вас подтип.

ContentResolver

Каждый объект Content, принадлежащий приложению, включает в себя экземпляр класса ContentResolver, который можно получить через метод getContentResolver().

ContentResolver используется для выполнения запросов и транзакций от активности к контент-провайдеру. ContentResolver включает в себя методы для запросов и транзакций, аналогичные тем, что содержит ContentProvider. Объекту ContentResolver не нужно знать о реализации контент-провайдера, с которым он взаимодействует — любой запрос всего лишь принимают путь URI, в котором указано, к какому объекту ContentProvider необходимо обращаться.

Источник

Оцените статью