0

FileProvider はマイクロ SD カードからサービスを提供できないため、独自の拡張 ContentProvider を作成する必要があります。

だから私は昔やった。そして、11未満のすべてのAndroidバージョンで正常に機能していました.

マイクロSDカードを含むデバイス全体からファイルを提供できます。

プライベートな getExternalFilesDirs()[0] と getExternalFilesDirs()[1] からも同様です。

これら 2 つのパスの両方が同じ micro-sd にあることを確認します。

/storage/1234-5678/Documents/mytext.txt
/storage/1234-5678/Android/data/<package>/files/mytext.txt

彼らは奉仕することができました。

ただし、Android 11 以降のデバイスでは、HTMLViewer と Chrome は最初のパスしか処理できません。アプリ自体は、パスまたは独自のプロバイダーを使用して、常に独自のファイルを処理できます。

Android 11 以降では、ACTON_VIEW で選択され、.readLine() を使用して uri から読み取る独自のアプリは、最初のパスを処理でき、2 番目のパスで失敗しました。.readLine() を使用せずに .available() を見て、入力ストリームから直接 .read() を実行することで、自分のアプリで最終的に解決できました。

これは私が使用するプロバイダークラスです:

public class ABCContentProvider extends ContentProvider {
String TAG = "abccontentprovider";

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
    Log.d(TAG, "open-File() mode: " + mode );  // "r" | "w"
    Log.d(TAG, "open-File() uri.getEncodedPath(): " + uri.getEncodedPath() );

    String path = uri.getEncodedPath();

    File f = new File(path);

    if ( ! f.exists() )
    {
        Log.d(TAG, "path does not exist" );
        throw new FileNotFoundException(
                "in ABCProvider\n"
                        + path
                        + "\nmode: " + mode
        );
    }

    if ( mode.equals("r") )
        return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_ONLY));

    return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_WRITE));
}

// Omitted all other methods as they are not used.
// Android Studio will add them for you
}

AndroidManifest.xml で:

    <provider
        android:name=".ABCContentProvider"
        android:authorities="aaa.bbb.ccc.provider"
        android:enabled="true"
        android:exported="true" />

ACTIEN_VIEW インテントには次の URI を使用します。(1234-5678 は、使用するマイクロ SD カードに応じて変更してください)

Uri uri1 = Uri.parse("content://aaa.bbb.ccc.provider/storage/1234-5678/Documents/mytext.txt");
Uri uri2 = Uri.parse("content://aaa.bbb.ccc.provider/storage/1234-5678/Android/data/<package>/files/mytext.txt");

最初に提供アプリで uries をテストします。

次のインテントは、外部アプリを起動するために使用されます。

 Intent intent = new Intent(Intent.ACTION_VIEW);
 intent.setDataAndType(uri, "text/plain");
 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 startActivity(intent);

私の質問は次のとおりです: Android 11 および 12 で、マイクロ SD カード上のファイルの ContentProvider が、異なる場所からのファイルに対して異なる動作をするのはなぜですか?

.txt ファイルの読み取りの問題は解決できましたが、外部アプリで編集内容を保存しようとすると失敗します。

更新 (11 月 5 日):

MANAGE_EXTERNAL_STORAGE のみに続きます。ディレクトリ ツリーの奥深くにあるファイルがこの動作に悩まされるという考えが頭に浮かびました。だからコピーした

/storage/1234-5678/Android/data/<package>/files/mytext.txt

/storage/1234-5678/Endroid/data/<package>/files/mytext.txt

後者は、外部アプリによる表示と編集には問題ありません。問題は、マイクロ SD カードのアプリ固有のディレクトリにあるファイルのみです。

4

0 に答える 0