web-dev-qa-db-ja.com

Android SAF(Storage Access Framework)を使用したSDカード書き込み許可

SDカード(Android 5以降)にファイルを書き込む(および名前を変更する)方法に関する多くの発見の後、Androidによって提供される新しいSAFはユーザーから許可を得るために必要になると思いますSDカードファイルを書き込む。

このファイルマネージャーアプリケーションESファイルエクスプローラーで、写真に示すように、最初は次の方法で読み取りおよび書き込み権限を取得することを見てきました。

enter image description here

Picture 2

SDカードを選択すると、書き込み許可が付与されます。

そのため、同じ方法でSAFを使用しようとしましたが、ファイル名の変更に失敗しました。私のコード:

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

    rename = (Button) findViewById(R.id.rename);

    startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), 42);
}

@Override
public void onActivityResult(int requestCode,int resultCode,Intent resultData) {
    if (resultCode != RESULT_OK)
        return;
    Uri treeUri = resultData.getData();
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
    grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}

public void renameclick(View v) {
    File ff = new File("/storage/sdcard1/try1.jpg");
    try {
        ff.createNewFile();
    } catch (Exception e) {
        Log.d("error", "creating");
        e.printStackTrace();
    }
}

それでもコードを実行した後、EAaccesの許可が拒否されます。

ユーザーに「SDカード」または「内部ストレージ」SAFルートを選択させると、アプリケーションは対応するストレージにアクセスできますが、ファイルシステム経由ではなく、SAF API経由でのみアクセスできます。たとえば、コードは次のようなものに変換できます。

public void writeFile(DocumentFile pickedDir) {
    try {
        DocumentFile file = pickedDir.createFile("image/jpeg", "try2.jpg");
        OutputStream out = getContentResolver().openOutputStream(file.getUri());
        try {

            // write the image content

        } finally {
            out.close();
        }

    } catch (IOException e) {
        throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
    }
}

Androidの最近のバージョンでは、Java.io.Fileを使用してアプリケーションの外部のデータにアクセスすることはほぼ完全に非推奨です。

21
bwt