Совместное использование кэшированных изображений с помощью FileProvider

У меня есть приложение, которое использует Универсальный загрузчик изображений для загрузки фотографий из Интернета, кэширования их в данные/ data/com.myapp/cache и отображать в ImageViews.

Я также хотел добавить обмен (WhatsApp, Facebook, Instagram, Dropbox и т. д.) в свое приложение, поэтому я попытался использовать этот код:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");
startActivity(Intent.createChooser(intent, "Share image"));

photoUri был uri в папке кеша, которую другие приложения не имеют права читать.

Итак, я погуглил/погуглил и обнаружил, что мне нужно использовать FileProvider.

Я настроил FileProvider следующим образом (как было написано здесь) в своем манифесте:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.myapp.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

И файл_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="photo_cache" path="/"/>
</paths>

Затем я использую следующий код в своей активности в кнопке onClickListener:

File photoFile = ImageLoader.getInstance().getDiscCache().get("HTTP LINK HERE"); 
// returns File of "/data/data/com.myapp/cache/-1301123243"
Uri photoUri = FileProvider.getUriForFile(MyActivity.this, "com.myapp.fileprovider", photoFile);
// returns Uri of "content://com.myapp.fileprovider/photo_cache/-1301123243"
photoUri = Uri.parse(photoUri.toString() + ".jpg");
// then I add .jpg to file name

// Create intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");

// Grant permissions to all apps that can handle this intent
// thanks to this answer http://stackoverflow.com/a/18332000
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    grantUriPermission(packageName, photoUri, 
        Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

// And start
startActivity(Intent.createChooser(intent, "Share image"));

Однако, в зависимости от приложения, я получаю странные исключения. Как это:

1974-1974/com.whatsapp W/Bundle﹕ Key android.intent.extra.STREAM expected ArrayList but value was a android.net.Uri$HierarchicalUri.  The default value <null> was returned.
1974-1974/com.whatsapp W/Bundle﹕ Attempt to cast generated internal exception:
java.lang.ClassCastException: android.net.Uri$HierarchicalUri cannot be cast to java.util.ArrayList
        at android.os.Bundle.getParcelableArrayList(Bundle.java:1223)
        at android.content.Intent.getParcelableArrayListExtra(Intent.java:4425)
        at com.whatsapp.ContactPicker.d(ContactPicker.java:320)
        at com.whatsapp.ContactPicker.onCreate(ContactPicker.java:306)
        at android.app.Activity.performCreate(Activity.java:5104)

Или я просто вижу такие журналы:

591-963/system_process W/ActivityManager﹕ Permission denied: checkComponentPermission()

И, конечно же, сами приложения выдают мне тосты с ошибками (что они не могут открыть или загрузить файл).

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

Любая помощь будет оценена!


person Makks129    schedule 29.10.2013    source источник
comment
Вы можете поместить разрешение на доступ в Интернет в файл Android xml   -  person Riskhan    schedule 29.10.2013
comment
@kTekkie Я не думаю, что ты правильно понял вопрос, извини   -  person Makks129    schedule 29.10.2013
comment
@Makks129 вы загружаете изображения с помощью JSON, если да, то можете ли вы поделиться со мной образцом кода или есть что-то похожее, что я могу разветвить на github, мое требование: универсальный загрузчик изображений + с JSON в GridView ---- не хотите использовать постоянные ссылки для изображений   -  person Sun    schedule 07.08.2014


Ответы (1)


Я думаю, что это может быть проблема либо с инфраструктурой FileProvider, либо с приложением, с которым вы делитесь.

Я пытался использовать эту поддержку для обмена изображениями с другими приложениями. Он отлично работает с Галереей, Диском, Gmail и Keep. Не работает с Фото и Google+.

Я вижу такие записи в LogCat, что наводит меня на мысль, что Uri передается от одного действия к другому. Однако (временное) разрешение, установленное в Intent, теряется.

11-19 21:14:06.031: I/ActivityManager(433): отображается com.google.android.apps.plus/.phone.HostPhotoViewIntentActivity: +848 мс

person Rich T    schedule 20.11.2013
comment
Вы пробовали этот подход с Instagram, Facebook или Messenger? Он должен работать, но это не так. - person Mario Lenci; 25.02.2016