问题
I have a problem to create file in Android M.
I use Nexus 9 with Android 6.0.1. Then I set in my project as below:
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
build.gradle
android {
defaultConfig {
targetSdkVersion 23
...
}
}
MainActivity.Java
public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String rootPath = storagePath + "/test";
String fileName = "/test.zip";
File root = new File(rootPath);
if(!root.mkdirs()) {
Log.i("Test", "This path is already exist: " + root.getAbsolutePath());
}
File file = new File(rootPath + fileName);
try {
if (!file.createNewFile()) {
Log.i("Test", "This file is already exist: " + file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
Build was success and application was launched, but I got exception message like this:
IOExceiption
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: java.io.IOException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: at java.io.File.createNewFile(File.java:939)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: at com.sample.myapplication.MainActivity.onCreate(MainActivity.java:36)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.Activity.performCreate(Activity.java:6251)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.os.Looper.loop(Looper.java:148)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at java.lang.reflect.Method.invoke(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at libcore.io.Posix.open(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at java.io.File.createNewFile(File.java:932)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: ... 13 more
How can I solve this problem? I don't catch what I miss....
Please help.
回答1:
I edit my code: Add "request to checks permission" code at onCreate
.
Thanks, laalto.
I didn't know about runtime permission.
I solved exception like this:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Request user permissions in runtime */
ActivityCompat.requestPermissions(MainActivity.this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
100);
/* Request user permissions in runtime */
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String rootPath = storagePath + "/test";
String fileName = "/test.zip";
File root = new File(rootPath);
if(!root.mkdirs()) {
Log.i("Test", "This path is already exist: " + root.getAbsolutePath());
}
File file = new File(rootPath + fileName);
try {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
if (!file.createNewFile()) {
Log.i("Test", "This file is already exist: " + file.getAbsolutePath());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@TargetApi(23)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 100:
if (grantResults.length > 0
|| grantResults[0] == PackageManager.PERMISSION_GRANTED
|| grantResults[1] == PackageManager.PERMISSION_GRANTED) {
/* User checks permission. */
} else {
Toast.makeText(MainActivity.this, "Permission is denied.", Toast.LENGTH_SHORT).show();
finish();
}
//return; // delete.
}
}
}
It works!
回答2:
I was having the same problem. I got an IOException on the file.createNewFile. A closer look at the exception reveals that it was due to "permissions denied". I was writing to my getFilesDir, so I shouldn't need an in the android manifest to accomplish this task. I of course added both READ and WRITE permissions for external storage, and of course, that didn't fix the problem.
I had been testing the code using a NEXUS 6 emulator with sdk 26. Without changing any code, I tried testing using a PIXEL C emulator with sdk 26 and the problem did not occur. So there seems to be some problem with my Nexus 6 emulator.
I suspect that this hasn't always been a problem and that this emulator instance got corrupted, but I haven't verified that. I did take the time to look at the linux file permission on the directories I was creating the file into an it reported "drwxrwxrwx", which is correct. I will add that I've implemented a FileProvider with paths to the directory I'm trying to create the new file at. The code I'm using pretty much looks like the code that Kae10 shows.
I traced the problem down to this code in UnixFileSystem:
public boolean createFileExclusively(String path) throws IOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return createFileExclusively0(path);
}
the exception is thrown from createFileExlussively0, which I not able to debug into. I haven't investigated this issue any further (i.e. 1.) would deleting the avd instance and recreating it help, my guess is that might, 2.) is there a later system image I should be using?)
来源:https://stackoverflow.com/questions/34651771/file-createnewfile-method-throws-exception-in-android-m