从 Android11 开始,我是否需要遵守 Android 的 SAF 才能在 public 下载位置创建文件?
Starting from Android11, do I need to comply to Android's SAF just to even create a file at public Download location?
我在 Android 11。我只想能够在 phone 的 /storage/emulated/0/Download
目录中创建一个文件。因此,这是我需要在其中创建文件的 public 下载文件夹。
我不需要访问 /storage/emulated/0/Download
中的 read/modify/delete 个其他文件。我只希望我的应用程序能够在 /storage/emulated/0/Download
创建和替换自己的文件。就是这样!
问题:
- 我需要通过 Storage Access Framework 吗?
- 我需要任何特殊许可吗?
- 或者是否可以在不经历 Android SAF 的麻烦的情况下访问
/storage/emulated/0/Documents
?
我的应用程序能够使用 Android 10 在 /storage/emulated/0/Download
处创建一个文件,但自 Android 11.
以来它无法做到这一点
我的用例非常简单。我只想在 /storage/emulated/0/Download
创建一个文件,并通过不时用新数据替换它来不断向文件附加更多数据。
运行 Android 11 上的以下代码对我来说失败了:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(path, "Somefile.txt");
String location = file.getAbsolutePath();
try {
file.createNewFile();
byte[] data1 = {1,1,0,0};
OutputStream fo = new FileOutputStream(file);
fo.write(data1);
fo.close();
Log.i(TAG, "The file is created at " + location);
} catch (IOException e) {
Log.e(TAG, "Exception creating file");
return location;
}
Do I need to go by the Storage Access Framework for this?
没有
Do I need any special permission for this?
不,尽管您需要 WRITE_EXTERNAL_STORAGE
用于较旧的设备。
Or is it possible get access to /storage/emulated/0/Documents without going through the hassle of Android SAF?
Environment.getExternalStoragePublicDirectory()
is being undeprecated, so it is safe to use that to access Environment.DIRECTORY_DOWNLOADS
. That should give you the same access that you have with MediaStore
:
您可以在那里创建文件
您可以在那里读写自己的文件1
您无权访问其他应用程序的文件
1 就本项目符号而言,“您自己的”是指您当前的应用程序安装——如果用户卸载并重新安装您的应用程序,您的旧安装中的文件应用程序不再被视为“您自己的”。
因此,例如,这个 activity 在 targetSdkVersion 31
项目中没有任何权限也能正常工作:
package com.commonsware.downloadtest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeToDownloads();
}
private void writeToDownloads() {
try {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File target = new File(dir, "test.txt");
PrintWriter out = new PrintWriter(new FileWriter(target));
out.println("hello, world!");
out.flush();
out.close();
} catch (Exception e) {
Log.e("DownloadTest", "Exception writing to Downloads/", e);
}
}
}
现在,这段代码 糟透了 ,因为它不处理旧设备,在主应用程序线程上执行 I/O 等。但是,它写入数据到指定文件,三星A50 运行 Android 11.
请注意,如果文件已经存在,这将给出一个异常。所以,例如,我认为这个例子不起作用,直到我意识到我已经在 Downloads/
中得到了 test.txt
,这是我一个月前做的一些实验。一旦我删除了那个文件,样本就可以正常工作了。
我在 Android 11。我只想能够在 phone 的 /storage/emulated/0/Download
目录中创建一个文件。因此,这是我需要在其中创建文件的 public 下载文件夹。
我不需要访问 /storage/emulated/0/Download
中的 read/modify/delete 个其他文件。我只希望我的应用程序能够在 /storage/emulated/0/Download
创建和替换自己的文件。就是这样!
问题:
- 我需要通过 Storage Access Framework 吗?
- 我需要任何特殊许可吗?
- 或者是否可以在不经历 Android SAF 的麻烦的情况下访问
/storage/emulated/0/Documents
?
我的应用程序能够使用 Android 10 在 /storage/emulated/0/Download
处创建一个文件,但自 Android 11.
我的用例非常简单。我只想在 /storage/emulated/0/Download
创建一个文件,并通过不时用新数据替换它来不断向文件附加更多数据。
运行 Android 11 上的以下代码对我来说失败了:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(path, "Somefile.txt");
String location = file.getAbsolutePath();
try {
file.createNewFile();
byte[] data1 = {1,1,0,0};
OutputStream fo = new FileOutputStream(file);
fo.write(data1);
fo.close();
Log.i(TAG, "The file is created at " + location);
} catch (IOException e) {
Log.e(TAG, "Exception creating file");
return location;
}
Do I need to go by the Storage Access Framework for this?
没有
Do I need any special permission for this?
不,尽管您需要 WRITE_EXTERNAL_STORAGE
用于较旧的设备。
Or is it possible get access to /storage/emulated/0/Documents without going through the hassle of Android SAF?
Environment.getExternalStoragePublicDirectory()
is being undeprecated, so it is safe to use that to access Environment.DIRECTORY_DOWNLOADS
. That should give you the same access that you have with MediaStore
:
您可以在那里创建文件
您可以在那里读写自己的文件1
您无权访问其他应用程序的文件
1 就本项目符号而言,“您自己的”是指您当前的应用程序安装——如果用户卸载并重新安装您的应用程序,您的旧安装中的文件应用程序不再被视为“您自己的”。
因此,例如,这个 activity 在 targetSdkVersion 31
项目中没有任何权限也能正常工作:
package com.commonsware.downloadtest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeToDownloads();
}
private void writeToDownloads() {
try {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File target = new File(dir, "test.txt");
PrintWriter out = new PrintWriter(new FileWriter(target));
out.println("hello, world!");
out.flush();
out.close();
} catch (Exception e) {
Log.e("DownloadTest", "Exception writing to Downloads/", e);
}
}
}
现在,这段代码 糟透了 ,因为它不处理旧设备,在主应用程序线程上执行 I/O 等。但是,它写入数据到指定文件,三星A50 运行 Android 11.
请注意,如果文件已经存在,这将给出一个异常。所以,例如,我认为这个例子不起作用,直到我意识到我已经在 Downloads/
中得到了 test.txt
,这是我一个月前做的一些实验。一旦我删除了那个文件,样本就可以正常工作了。