10

Android Storage Access Framework を使用して、SD カード上のいくつかのファイルにアクセスします。デバイスの再起動後にファイルを編集できるようにするには、この権限を保持することが重要です。

そのため、 Storage Access Framework のドキュメントによると、デバイスが再起動された場合でも、ユーザーがアプリを介してファイルに引き続きアクセスできるようにする Persist アクセス許可を使用します。

しかし、しばらくして、一部のユーザーのアクセス許可が取り消されていることに気付きました。書き込みにSAFを使用しようとするとandroid.system.ErrnoException: open failed: EACCES (Permission denied) 、例外が発生した後、使用している権限を確認しますが、mContext.getContentResolver().getPersistedUriPermissions()空のリストが返されます。データベースでこのアクションを追跡しているため、ユーザーが適切なアクセス許可を提供し、そのアクセス許可が現在インストールされている Sd カードに対するものであると確信しています。

現在、この場合、ドキュメント ピッカーを表示しているため、ユーザーはもう一度新しいアクセス許可を提供できますが、ユーザーに同じアクションを実行するように求めることは、多くの場合、ユーザー フレンドリーではありません。

権限が取り消される原因は何ですか? そして、どうすればこの取り消しを防ぐことができますか?

私はすべてのデバイスで電話の複数回の再起動、時刻の変更、sd カードの挿入の取り外しをテストしましたが、安全なアクセス許可を失うことはできませんでした。

アクセス許可を取得するための次のコードがあります。

private void openDocumentTree() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivityForResult(intent, REQUEST_CODE);
    }

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
            Uri treeUri = data.getData();
            final int takeFlags = data.getFlags() & ( 
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            mContext.getContentResolver().takePersistableUriPermission(treeUri,
                    takeFlags);

                    //this is my internal class for saving and restoring tree uri permissions.
                    final Permission permission = Permission.from(treeUri);
                    mPermissionDao.save(permission);
        }
    }
4

1 に答える 1

5

をリクエストするときは、追加のフラグが必要ですACTION_OPEN_DOCUMENT_TREE

openDocumentTreeのように見えるはずです

private void openDocumentTree() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.addFlags(
        Intent.FLAG_GRANT_READ_URI_PERMISSION
        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
        | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
    startActivityForResult(intent, REQUEST_CODE);
}

FLAG_GRANT_PERSISTABLE_URI_PERMISSIONおよびFLAG_GRANT_PREFIX_URI_PERMISSIONのドキュメントを確認する

于 2016-06-24T00:52:58.297 に答える