Фильтр намерений, который регистрирует расширение файла, получает 2 файловых протокола в URI - PullRequest
1 голос
/ 19 июня 2020

Приложение регистрируется для определенного расширения файла «.foo», обычно расположенного в root того, что Android API называет «Внешним хранилищем», но Google File Explorer называет «Внутреннее хранилище».

Однако, когда я нажимаю на файл, я получаю странный URI:

file: ///1/file%3A/storage/emulated/0/config.foo

Это приводит к исключению «файл не найден», когда я пытаюсь выполнить на нем OpenInputStream:

/ 1 / file: /storage/emulated/0/config.foo : open failed: ENOENT (Нет такого файла или каталога)

Манифест:

<activity
    android:name=".MainActivity">
    <intent-filter>
        <!-- Can receive a transfer file and decrypt it -->
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="content" />
        <data android:mimeType="*/*"/>
        <data android:pathPattern=".*\\.foo"/>
        <data android:host="*"/>
    </intent-filter>
</activity>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application android:requestLegacyExternalStorage="true">

В случае, когда я тестирую, пользователь принял разрешения времени выполнения через стандарт Android диалоговое окно разрешения:

Gradle:

android {
    compileSdkVersion 29

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 29
    }
}

Исходный код, который не работает с исключением FileNotFound:

Uri fileUri = getIntent().getData();
InputStream fis = appContext.getApplicationContext().getContentResolver().openInputStream(fileUri);

Эксперименты:

1: попробуйте открыть файл напрямую, чтобы узнать, есть ли у нас доступ:

String[] parts = fileUri.toString().split("%3A");
String path = parts[1];
File file = new File(path);
if (file.exists()) {
    Log.i(TAG, "Exists");
}

2: проверьте, может ли openInputStream открыть файл:

InputStream fis = appContext.getApplicationContext().getContentResolver().openInputStream(Uri.parse("file:///storage/emulated/0/config.foo"));

Эксперименты 1 и 2 обе успешно.

Я считаю, что этот код работал на более старых версиях Android. Устройство, на котором я его сейчас тестирую, - это Android Одно работающее устройство Android 10.

Я понимаю, что Google изменил направление в отношении файловой системы, и весь код, касающийся внешнего хранилища, необходимо переписать. . Однако я пытаюсь найти временное решение этой проблемы.

Кто-нибудь знает, почему он дважды добавляет протокол «файла» к URI, когда файл открывается из проводника файлов Google? Буду благодарен за любые предположения или попытки. Спасибо!

enter image description here

Версия: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...