java.io.FileNotFoundException打开失败:EEXIST(文件存在)Android11

我试图从服务器下载图像并将其保存在外部存储器中,但在 Android 11 中,当我尝试创建文件时出现错误。我已授予访问外部存储的权限。

我在互联网上搜索了一下,他们建议我将此代码放在清单中,但它不适用于 android 11

android:requestLegacyExternalStorage="true"

显现

<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TestDwonloadImgApp"
        android:usesCleartextTraffic="true">
        <activity android:name=".MainActivity2">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">
        </activity>
    </application>

主要活动

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView img = findViewById(R.id.img);

        ImmagineInterface ii = RetrofitManager.retrofit.create(ImmagineInterface.class);
        Call<ResponseBody> call = ii.downloadFile("/immaginimusei/arte-scienza.jpg");
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.code() == 200) {
                    boolean result = writeResponseBody(response.body(), "/immaginimusei/arte-scienza.jpg");
                    if(result) {
                        Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter/immaginimusei/arte-scienza.jpg");
                        img.setImageBitmap(bitmap);
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter/immaginimusei/arte-scienza.jpg");
                img.setImageBitmap(bitmap);
            }
        });
    }
}

写响应体

public static boolean writeResponseBody(ResponseBody body, String dir1) {
        try {
            String state = Environment.getExternalStorageState();
            if (Environment.MEDIA_MOUNTED.equals(state)) {
                // todo change the file location/name according to your needs

                String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter";

                String path1 = path + dir1;
                File f = new File(path1);
                String path2 = f.getPath();
                String nome = f.getName();
                path2 = path2.replaceAll("/" + nome, "");

                File directory = new File(path2);
                if (!directory.exists())
                    directory.mkdirs();

                File img = new File(path2, nome);
                if (img.exists())
                    return true;
                img.createNewFile();

                InputStream inputStream = null;
                FileOutputStream outputStream = null;

                try {
                    byte[] fileReader = new byte[4096];

                    inputStream = body.byteStream();
                    outputStream = new FileOutputStream(img); //error here!

                    while (true) {
                        int read = inputStream.read(fileReader);

                        if (read == -1) {
                            break;
                        }

                        outputStream.write(fileReader, 0, read);

                    }

                    outputStream.flush();

                    return true;
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }

                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
            }
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

错误

/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/ArtHunter/immaginimusei/arte-scienza.jpg: open failed: EEXIST (File exists)
W/System.err:     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 com.theapplegeek.testdwonloadimgapp.MainActivity.writeResponseBody(MainActivity.java:93)
        at com.theapplegeek.testdwonloadimgapp.MainActivity$1.onResponse(MainActivity.java:47)
        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
        at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$hVGjmafRi6VitDIrPNdoFizVAdk.run(Unknown Source:6)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:245)
        at android.app.ActivityThread.main(ActivityThread.java:8004)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
    Caused by: android.system.ErrnoException: open failed: EEXIST (File exists)
        at libcore.io.Linux.open(Native Method)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
        at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
        at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7865)
        at libcore.io.IoBridge.open(IoBridge.java:478)
        ... 13 more

回答

在 Android 11android:requestLegacyExternalStorage="true"中将被简单地忽略,因为它是 Android < 11 的临时解决方案,不会破坏旧应用程序。现在,您必须使用

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

您也可以使用 SAF 来避免所有这些“权限”的麻烦。这是 Google 为不需要管理大多数内部存储数据的应用程序推荐的。参考:https :
//developer.android.com/guide/topics/providers/document-provider

但是,如果您不想破坏您的应用程序并失去您所有的辛勤工作,请考虑

if(Environment.isExternalStorageManager())
{
    internal = new File("/sdcard");
    internalContents = internal.listFiles();
}
else
{
    Intent permissionIntent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
    startActivity(permissionIntent);
}

这将打开一个设置页面,您可以在其中授予对应用程序的存储访问权限。如果应用程序已经拥有权限,那么您将能够访问该目录。设置布局资源后,将此放在onCreate()方法的最开始处。

最好不要为您将来构建的任何应用程序执行此操作。


以上是java.io.FileNotFoundException打开失败:EEXIST(文件存在)Android11的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>