0

Android 6.0.1、API 23、

ユーザーが SAF ( Storage Access Framework )のドキュメント ピッカーで選択したストレージの場所からファイルを読み取る実装に成功しました。

ここで、アプリが常に同じファイルを選択できるようにするために、SAF が許可する を使用したいと思いPersist permissionsます (ただし、ドキュメント ピッカー ウィンドウ [およびサブウィンドウ] が常に表示されることはありません)。

私はどうにかして Persist-permissions の実装に成功しました ( SAF-docに示されているように) (...そのためには、以下の私のコード例を参照してください...) - しかし、疑問が生じました:

  1. persistence-permission が機能しているにもかかわらず、ドキュメント ピッカー ウィンドウがポップアップし続けるのはなぜですか? ファイルがユーザーによって選択されると、この瞬間から、ピッカーウィンドウが前面に表示されることなく、ファイルの内容を単純に取得したいと思います。これは可能ですか?はいの場合、どのように?(ユーザーがもう一度選択しなくてもファイルがすぐに読み取られるため、永続化の許可が何らかの形で機能していることがわかります。しかし、それでもこの厄介なピッカー ウィンドウが表示される必要はありません。または表示されますか?)
  2. アプリが閉じられたり停止されたりしても、SAF 永続許可を維持することはできますか? はいの場合、どのように?

これは、永続化権限のある私の試用版を含む、ファイル コンテンツを取得するコード サンプルです。

StorageClientFragment クラス内:

public String locationFileContent;

public void performFileSearch() {
    Intent openDocumentIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    openDocumentIntent.addCategory(Intent.CATEGORY_OPENABLE);
    openDocumentIntent.setType("text/plain");
    openDocumentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    startActivityForResult(openDocumentIntent, READ_REQUEST_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        Uri uri = null;
        if (resultData != null) {
            uri = resultData.getData();

            // Here is my Persist-permission trial !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            getActivity().getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

            try {
                this.locationFileContent = readTextFromUri(uri);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

private String readTextFromUri(Uri uri) throws IOException {
    InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder stringBuilder = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        stringBuilder.append(line);
    }
    inputStream.close();
    return stringBuilder.toString();
}

Fragment の作成は MainActivity で行われます。

StorageClientFragment storageClientFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        storageClientFragment = new StorageClientFragment();
        transaction.add(storageClientFragment, FRAGTAG);
        transaction.commit();
    }
}

Test-Button がクリックされると、FileSearch の呼び出しが行われます。

public void TestingButtonClicked(View view) {
    this.storageClientFragment.performFileSearch();
    String stringFileContent = this.storageClientFragment.locationFileContent;
    Toast.makeText(this, "Back in Main, Content = " + stringFileContent, Toast.LENGTH_SHORT).show();
}

上記のコードはうまく機能します。しかし、繰り返しになりますが、SAF ドキュメント ピッカー ウィンドウが常に表示されないようにするにはどうすればよいでしょうか (永続的なアクセス許可が設定されている場合でも)。

4

1 に答える 1

0

ドキュメント ピッカー ウィンドウがクロップアップし続けるのはなぜですか?

おそらく、ACTION_OPEN_DOCUMENT活動を開始し続けるためです。ユーザーにドキュメントの選択を求めたくない場合は、このアクティビティを開始しないでください。

ピッカーウィンドウが前面に出ないように、ファイルの内容を簡単に取得したいと思います。これは可能ですか?はいの場合、どのように??

最初にコンテンツを取得したのと同じ方法: に をUri渡しopenInputStream()ますContentResolver

takePersistableUriPermissions()コンテンツへの長期アクセスを目指してを使用している場合でも、を保持するのはあなたの仕事Uriです。これは、この種のことが他の環境でどのように機能するか (たとえば、デスクトップ OS プログラムのローカル ファイル パスのユーザーの履歴を記憶すること) と大きな違いはありません。

Uriは との間で簡単に変換できるため、どこかに (データベース、 、またはその他のファイル) をString保存することは特に難しくありません。UriSharedPreferences

アプリが閉じられたり停止されたりしても、SAF 永続許可を維持することはできますか? はいの場合、どのように??

takePersistableUriPermission()、既に実装したように。

于 2016-08-15T12:36:27.737 に答える