Android 使用 SAF(存储访问框架)的 SD 卡写入权限
Android SD Card Write Permission using SAF (Storage Access Framework)
经过大量关于如何在 SD 卡(android 5 及更高版本)中写入(和重命名)文件的发现,我认为 android 提供的新 SAF 将需要获得用户写入 SD 卡文件的许可。
我在这个文件管理器应用程序 ES 文件资源管理器 中看到,最初它通过以下方式获取读写权限,如图所示。
选择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 card" 甚至 "Internal storage" 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
访问应用程序外部的数据几乎已完全弃用。
经过大量关于如何在 SD 卡(android 5 及更高版本)中写入(和重命名)文件的发现,我认为 android 提供的新 SAF 将需要获得用户写入 SD 卡文件的许可。
我在这个文件管理器应用程序 ES 文件资源管理器 中看到,最初它通过以下方式获取读写权限,如图所示。
选择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 card" 甚至 "Internal storage" 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
访问应用程序外部的数据几乎已完全弃用。