我的代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeFile();
}
public void writeFile() {
File removableRoot = RootsUtil.getRemovableRoots(this)[0];
File DCIMDirectory = new File(removableRoot, "DCIM");
File cameraDirectory = new File(DCIMDirectory, "Camera");
if( cameraDirectory.exists() ) {
try {
String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".txt";
//cameraDirectory.mkdirs();
File file = new File(cameraDirectory, filename);
FileWriter writer = null;
writer = new FileWriter(file);
PrintWriter printWriter = new PrintWriter(writer);
printWriter.println("Hello World");
printWriter.close();
writer.close();
System.out.println("Number of files: " + cameraDirectory.listFiles().length);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
如果且存在, cameraDirectory
等于/storage/9C33-6BBD/DCIM/Camera
。这是我的Camera
应用程序存储它的文件。
我也试图将文件写入此目录,但失败并出现以下异常:
java.io.FileNotFoundException: /storage/9C33-6BBD/DCIM/Camera/20170204_192001.txt: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:452)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
at java.io.FileWriter.<init>(FileWriter.java:42)
at com.inthemoon.trycamerawrite.MainActivity.writeFile(MainActivity.java:48)
at com.inthemoon.trycamerawrite.MainActivity.onCreate(MainActivity.java:28)
at android.app.Activity.performCreate(Activity.java:6876)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
... 17 more
显然,我无权写入此目录。如何获得此权限?
更新
我已按以下方式修改了代码:
private static final int RQS_OPEN_DOCUMENT_TREE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE, Uri.fromFile(cameraDirectory));
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, RQS_OPEN_DOCUMENT_TREE);
//writeFile();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
writeFile();
}
然后允许用户手动选择DCIM/Camera
,这无济于事。
答案 0 :(得分:1)
您正在尝试直接写入可移动存储的文件系统。除了您的应用独有的精选目录(例如<div>
<div style="display: block">
<canvas baseChart
[datasets]="barChartData"
[labels]="barChartLabels"
[options]="barChartOptions"
[legend]="barChartLegend"
[chartType]="barChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
<div align="center">{{barChartTitle}}</div>
</div>
</div>
返回的目录)之外,这不起作用。
使用getExternalFilesDirs()
并不会神奇地授予您文件系统访问权限。 做所做的是为您提供一个ACTION_OPEN_DOCUMENT_TREE
,您可以与Uri
,ContentResolver
和kin一起使用DocumentFile
来处理基于文档和集合的内容在Uri
上。
ACTION_OPEN_DOCUMENT_TREE
是the storage access framework的一部分,在文档中有介绍。
Android 7.0+还提供了scoped directory access,它为用户提供了一种更简单的方式,允许您访问可移动存储上的DCIM/
。但是,它也会为您提供Uri
,您仍然会使用ContentResolver
,DocumentFile
等来处理基于Uri
的内容和集合。