我已经编写了一些代码,可以使用Android DownloadManager将文件下载到外部SD卡。在Android 6.0.1(API级别23)上,一切都可以正常工作,但是在Android Oreo(API级别27)上,尽管授予了所有权限,但下载失败并显示“下载失败”。 PermissionUri是使用Intent.ACTION_OPEN_DOCUMENT_TREE(“ / storage / 2633-FECD”)选择的sd卡的Uri。
public static Uri permissionUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences pref = getApplicationContext().getSharedPreferences("AppPrefs", 0);
String sdUriString = pref.getString("sdUri", null);
if(sdUriString==null){
startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), 732);
}
else{
permissionUri = Uri.parse(sdUriString);
}
final Button DownloadButton = (Button) findViewById(R.id.downloadButton);
DownloadButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
DownloadManager dm = (DownloadManager) v.getContext().getSystemService(DOWNLOAD_SERVICE);
Long downloadID = dm.enqueue(new DownloadManager.Request(Uri.parse("https://www.google.de/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"))
.setAllowedOverRoaming(false)
.setTitle("Download")
.setDestinationUri(Uri.fromFile(new File("/storage/2633-FECD/Test.jpg")))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 732){
if(resultCode == RESULT_OK){
permissionUri = data.getData();
try {
grantUriPermission(getPackageName(), permissionUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(permissionUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
SharedPreferences settings = getSharedPreferences("AppPrefs", MODE_PRIVATE);
settings.edit().putString("sdUri", permissionUri.toString()).apply();
}
catch (Exception e){
}
}
}
}
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />