Java.io.FileNotFoundException:/storage/emulated/0/Notes/fact50Result.txt:打开失败 ENOENT(没有这样的文件或目录)

5
我正在尝试将阶乘计算的结果导出到一个txt文件中。我从这里找到了一段代码,看起来非常直观。然而,我得到了标题上的错误。我做错了什么?
我已经在清单文件中输入了以下内容:
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

以下是我与保存相关的代码:

    public void save(View v) {
     if(numOnRAM!=-1) {
         EditText text = (EditText) findViewById(R.id.resultTextBox);
         String data = text.getText().toString();
         generateNoteOnSD(this,"fact"+numOnRAM+"Results.txt", data);
     }
}

public void generateNoteOnSD(Context context, String sFileName, String sBody) {
    try {
        File root = new File(Environment.getExternalStorageDirectory(), "Notes");
        if (!root.exists()) {
            root.mkdirs();
        }
        File gpxfile = new File(root, sFileName);
        FileWriter writer = new FileWriter(gpxfile);
        writer.append(sBody);
        writer.flush();
        writer.close();
        Toast.makeText(context, "File "+sFileName+" saving success!", Toast.LENGTH_LONG).show();

    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();//After adding this 
//toast message did I realise the error thar occurs.

    }
}

root.mkdirs() 的执行结果成功了吗?你的目标 API 是什么?如果是 API 23 或更高版本,你需要在运行时请求权限 - Michael Dodd
@MichaelDodd 对不起,我刚开始学习Android。如何找出root.mkdirs()是否成功?创建项目后如何找出我正在针对哪个API?谢谢。 - Nick
mkdirs() 返回一个布尔值,如果目录被创建则返回 true,否则返回 false。您可以在应用的 build.gradle 文件中找到您的 API 目标级别。 - Michael Dodd
@MichaelDodd 这个是指 targetSdkVersion 26 吗?我找不到任何新目录。 - Nick
是的。这意味着您需要在运行时请求写入外部存储的权限。 - Michael Dodd
@MichaelDodd 我需要做什么才能实现它? - Nick
3个回答

11

如评论中所讨论的那样,您需要在运行时请求权限,以允许您的应用程序写入外部存储。您可以使用checkSelfPermission()检查您的应用程序是否已经具有该权限。例如:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
    // Do the file write
} else {
    // Request permission from the user
    ActivityCompat.requestPermissions(this, 
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
    ...
}
为了处理此权限请求,您还需要从OnRequestPermissionsResultCallback实现onRequestPermissionsResult(),例如:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 0:
            // Re-attempt file write
    }
}

阅读文档以获取完整信息。


5

我认为您需要在运行时请求权限。请查看下面的代码:

 final private int REQUEST_CODE_ASK_PERMISSIONS = 123;

      private void requestPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
            ActivityCompat
                    .requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSIONS);
        }
    }

        @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_PERMISSIONS:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission Granted
                    Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT)
                            .show();
                } else {
                    // Permission Denied
                    Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT)
                            .show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

0

对于遇到相同问题的人,您可以按照以下步骤从合并清单中删除android:MaxSdkVersion属性。

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:remove="android:maxSdkVersion" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接