我在网上搜索了一下,他们建议我将此代码放在清单中,但对于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
path2 = path2.replaceAll("/" + nome, "");
这里你在构建路径,但是没有人能够理解你的思路,我认为你自己也迷失了方向。请进一步检查mkdirs的返回值,如果为false则进行相应处理。移除.createNewFile
调用。请重新编写你的代码。同样的问题也存在于这里。 - blackapps