Android 11 更新破坏了我的文件编写代码

Posted

技术标签:

【中文标题】Android 11 更新破坏了我的文件编写代码【英文标题】:Android 11 update broke my File writing code 【发布时间】:2021-12-13 16:03:55 【问题描述】:

我之前使用过这个 sn-p 来编写一个简单的文本文件,带有名称和正文:

public static File writeTextFile(String sFileName, String sBody) throws IOException 
        File root = new File(Environment.getExternalStorageDirectory(), FOLDER_NAME);

    if (!root.exists()) 
        logFile("Not yet created, creating right now: " + root.getPath());
        root.mkdirs();

        logFile("Creation was successful? " + (root.exists() ? "Yes." : "No."));

     else 
        logFile("Path exists: " + root.getPath());
    

  
    File       measurementFile = new File(root, sFileName);
    FileWriter writer  = new FileWriter(measurementFile);
    writer.append(sBody);
    writer.flush();
    writer.close();

    return measurementFile;


它运行良好Android 11 除外,这是我今天在运行 android 11 的 OnePlus N10 上测试后才意识到的。


问题是我没有收到任何描述的错误消息,只是一个简单的异常,并且在发生此问题后我似乎找不到继续的方法。

 java.io.FileNotFoundException: /storage/emulated/0/example_myapp/content_file_to_upload_1635424827184: open failed: ENOENT (No such file or directory)
     at libcore.io.IoBridge.open(IoBridge.java:492)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
     at java.io.FileWriter.<init>(FileWriter.java:90)
     at com.myapp.example.util.FileUtil.writeTextFile(FileUtil.java:39)
     at com.myapp.example.services.ConnectionServiceForDownloadData$1.onCharacteristicChanged(ConnectionServiceForDownloadData.java:265)
     at android.bluetooth.BluetoothGatt$1$8.run(BluetoothGatt.java:478)
     at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:780)
     at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:41)
     at android.bluetooth.BluetoothGatt$1.onNotify(BluetoothGatt.java:472)
     at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:306)
     at android.os.Binder.execTransactInternal(Binder.java:1170)
     at android.os.Binder.execTransact(Binder.java:1134)
 Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
     at libcore.io.Linux.open(Native Method)
     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
     at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7924)
     at libcore.io.IoBridge.open(IoBridge.java:478)
    ... 12 more

非常感谢任何帮助。

【问题讨论】:

嗯,scoped storage 已经有两年多了。您不能在外部存储根目录之外创建目录,也不能在任意位置写入文件。写入您可以写入的位置(Context 上的任何 File-returning 方法,例如 getExternalFilesDir()),或者使用存储访问框架让用户选择用户设备(或用户的云)上的位置storage) 用户希望你写用户的文本。 root.mkdirs(); logFile("Creation was successful? " + (root.exists() ? "Yes." : "No.")); 如果“否”,则不应继续尝试在不存在的目录中创建文件。 @CommonsWare 嗯 如果您的评论是针对已接受的答案,那是您可以写的另一个地方(如DIRECTORY_DOWNLOADS)。请注意,其他应用程序可能无法使用您在这些位置创建的文件,除非该应用程序使用存储访问框架让用户选择您创建的文件。但是,我原来评论的观点仍然成立:您不能在外部存储根目录之外创建目录,也不能在任意位置写入文件。 @CommonsWare 未阅读 【参考方案1】:

文件根 = 新文件(Environment.getExternalStorageDirectory(), FOLDER_NAME);

改为:

File root = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), FOLDER_NAME);

【讨论】:

非常感谢! 由于 getExternalStoragePublicDirectory 在 Android 10 中已被弃用,这怎么能成为解决方案? 它不再是@MPaulo。 你是对的。奇怪,但真实。谢谢。 DIRECTORY_DOWNLOADS 较旧。使用 DIRECTORY_DOCUMENTS,更好地测试版本: if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) 【参考方案2】:

尝试将android:requestLegacyExternalStorage="true" 添加到您的清单中。

或将其更改为符合 Android 11 的新范围存储系统。 见https://developer.android.com/about/versions/11/privacy/storage

【讨论】:

以上是关于Android 11 更新破坏了我的文件编写代码的主要内容,如果未能解决你的问题,请参考以下文章

最新的 AG 网格更新 (26.2.0) 破坏了我的脚本

Android Studio - 破坏了我的 AVD 路径,破坏了我的模拟器

CocoaPods 破坏了我的项目

Xcode 11 破坏了 DateFormatter?

升级 android studio 破坏了我的颤振构建(macOS)

将角度从 1.2 更新到 1.3 破坏了我的指令