问题
My code is follows:
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 equals to /storage/9C33-6BBD/DCIM/Camera before if and it exists. This where my Camera application stores it's files.
I am trying to write file into this directory too, but fails with the following exception:
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
Apparently, I have no permission to write to this directory. How to obtain this permission?
UPDATE
I have modified the code in the following way:
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();
}
and then allowing user to manually select DCIM/Camera and this doesn't help.
回答1:
You are attempting to write directly to the filesystem of removable storage. That will not work, except for select directories that are unique to your app (e.g., ones returned by getExternalFilesDirs()).
Using ACTION_OPEN_DOCUMENT_TREE does not magically grant you filesystem access. What it does do is give you a Uri that you can use, in conjunction with ContentResolver, DocumentFile, and kin, to work with documents and collections based on that Uri.
ACTION_OPEN_DOCUMENT_TREE is part of the storage access framework, covered in the documentation.
Android 7.0+ also provides scoped directory access, which provides a simpler way for the user to grant you access to something like DCIM/ on removable storage. However, it too gives you a Uri, and you would still use ContentResolver, DocumentFile, and so on to work with content and collections based on that Uri.
来源:https://stackoverflow.com/questions/42040984/how-gain-write-access-to-dcim-directory-on-removable-media-in-android