Невозможно загрузить изображение при выборе из галереи на Android 4.4 (KitKat) с помощью PhoneGap Camera Plugin

Я пытаюсь установить источник тега img в своем приложении на основе изображения, выбранного из галереи изображений устройства, используя плагин камеры PhoneGap / Cordova.

Он работал ранее по назначению в более старых версиях Android (3.3) и отлично работает на iOS, но теперь не удается разрешить путь изображения на 4.4 (KitKat).

Возвращенный путь для возвращаемого URL-адреса изображения выглядит примерно так:

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

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

Я попытался кодировать base64, а также попробовал метод, упомянутый в документации resolveLocalFileSystemURI(); но мне не повезло с ними. Я также попытался удалить плагин камеры и восстановить приложение, но не радость.

Я предполагаю, что что-то изменилось с тем, как KitKat обрабатывает галерею, а плагин PhoneGap / Camera не обновлен, чтобы разместить его для этого.

    Что-то сломалось в Android 4.4 с кодировкой URI изображений.

    В Кордове была подана ошибка: https://issues.apache.org/jira/browse/CB-5398

    В документах для getPicture в разделе «Быстрый поиск Android» обсуждается эта проблема и указывается на вопрос StackOverflow с обходным решением (отредактируйте код Java для плагинов камеры, чтобы заставить его открыть приложение «Галерея» вместо приложения «Access Access Framework»).

    Кажется, еще одна вещь, которую вы могли бы сделать, – установить тип назначения DATA_URL.

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

     if (imageURI.substring(0,21)=="content://com.android") { photo_split=imageURI.split("%3A"); imageURI="content://media/external/images/media/"+photo_split[1]; } 

    Adobe уверяет меня, что эта проблема будет исправлена ​​в 3.5.0. Это не зафиксировано в 3.4. Поскольку 3.5.0 планируется выпустить в середине мая, я просто буду ждать до тех пор.

    Adobe утверждает, что это не было изменение, которое может быть сделано на уровне плагина. Это было принципиальное изменение в коде кордовы. Слишком плохо, что им потребовалось столько времени, чтобы они придумали это решение.

    ОБНОВЛЕНИЕ: Кордова 3.5.0 была выпущена 9 мая. Вы можете скачать ее узел bia и посмотреть, действительно ли проблемы решены.

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

    замените это:

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

    этим:

     content://com.android.providers.media.documents/document/image%253A352 

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

     var path = content://com.android.providers.media.documents/document/image%3A352; path = path.replace("%", "%25"); 

    этот метод заставляет https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri пропускать «% 3A» так, как он есть, не меняя его на «:», надеюсь, что он сработает для вас!

    Не намного надежнее всего несколько проверок особых условий, таких как «контент:» без расширений и т. Д. Кроме того, поскольку мне нужно загрузить его, я обнаруживаю расширение или создаю расширение .jpg, если файл не имеет одного:

     // Android 4.4 cordova workarounds ... returns new kind or URL for content from chooser //if (imageUrl.substring(0,21)=="content://com.android") { if(imageUrl.indexOf('content://') != -1 && imageUrl.indexOf("%3A") != -1){ //"PlainFileUrl = content://com.android.providers.media.documents/document/image%3A14", photo_split=imageUrl.split("%3A"); imageUrl="content://media/external/images/media/"+photo_split[1]; } // workaround end var fileName = imageUrl.substr(imageUrl.lastIndexOf('/') + 1); var extension; // check for content: protocol to make sure is not // a file with no extension if (imageUrl.indexOf('content://') != -1) { if(imageUrl.lastIndexOf('.') > imageUrl.lastIndexOf('/')){ extension = imageUrl.substr(imageUrl.lastIndexOf('.') + 1); }else{ extension = "jpg"; fileName = fileName + ".jpg"; LogService.log("Created File Extension jpg"); } } else { if (imageUrl.lastIndexOf('.') == -1 || (imageUrl.lastIndexOf('.') < imageUrl.lastIndexOf('/')) ) { extension = "invalid"; } else { extension = imageUrl.substr(imageUrl.lastIndexOf('.') + 1); } } 

    Всякий раз, когда некоторый https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/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.Sechttps://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/urityException: Разрешение: чтение com.android.providers.media.MediaDocumentsProvider https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri content: //com.android.providers.media.documents/document/image: 9888 из pid = 13163, uid = 10165 требует android. разрешение.MANAGE_DOCUMENTS или grantUriPermission ()

    или

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

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

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

      String https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uriToUseInWebView = transformForWebView(https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri.toString()); private String transformForWebView(String https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri) { for (int i = 0; i < timesDecodingWebView(); i++) https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri = https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri.replace("%", Uri.encode("%")); return https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri; } private int timesDecodingWebView() { if (Build.VERSION.RELEASE.equals("4.4.2")) { return 2; } else { return 1; } } 

    в вашем Java-коде перед передачей https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri в HTML / JS, чтобы гарантировать, что (1) будет фактически загружен.

    Я тестировал это на 4.4.2, 4.4.4 и 5.0. Самое забавное, что Android 4.4.2 дважды декодирует https://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin/uri .

    Давайте будем гением компьютера.