Подтвердить что ты не робот

Android 6: больше не могут делиться файлами?

Я использую изображение, и этот код работает правильно для устройств до Android 6:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri uri = Uri.fromFile(new File(mFilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));

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

Я проверил, что файл существует, и он не является нулевой длиной.

У кого-нибудь есть решение для этого?

4b9b3361

Ответ 1

Одно из ограничений системы разрешений для работы с Android 6.0 заключается в том, что будут проблемы с углами, которые вызывают проблемы. То, с чем вы столкнулись, - это одно: попытка поделиться файлом на внешнем хранилище с приложением, которое не имеет проверок разрешения времени выполнения для этого конкретного пути пользовательского интерфейса.

Я говорю, что это "угловой случай", потому что, поскольку эта ошибка в принимающем приложении влияет на пользователя, пользователь не может ранее использовать это приложение и предоставил необходимое разрешение. Или:

  • Пользователь никогда не использовал это приложение раньше, но все же пытается поделиться им с ним, или

  • Пользователь отменил разрешение с помощью настроек, но не понял, что он сломает этот бит функциональности

Оба из них - события с низкой вероятностью.

Вы, как отправитель, имеете два основных варианта:

  • Отключите использование значений file:// Uri в пользу файлового обслуживания ContentProvider, например FileProvider, поэтому разрешение больше не требуется или

  • Просто живу с угловым футляром

Ответ 2

Я решил это, реализовав FileProvider, как это было предложено @CommonsWare

Сначала вам нужно настроить FileProvider:

  • сначала добавьте <provider> в манифест файла XML

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.myfileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>
    
  • second, определите ваши пути к файлам в отдельном файле XML, я назвал его " file_provider_paths.xml"

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

вы можете найти полное объяснение на этой странице документации

после того, как вы настроили поставщика файлов в XML, это код для совместного использования файла изображения:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", new File(mFilename));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));

Ответ 3

Кроме того, вам не нужно иметь ContentProvider/FileProvider. Вы можете просто добавить флаг, который предоставляет разрешение на чтение для общего ресурса uri. В частности, share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); должен сделать трюк.

Ответ 4

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

        MediaScannerConnection.scanFile(context, new String[] {imageFile.toString()}, yourMimeType, new OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                //uri = "content://" style URI that is safe to attach to share intent
            }
        });

Это может быть более короткое решение для ваших нужд.