I have written some code to download a file with the Android DownloadManager to an external sd card. On Android 6.0.1 (API level 23) everything works perfectly fine, but on Android Oreo (API level 27) the download fails with "Download unsuccessful" although all permissions are granted. permissionUri is the Uri of the sd card that is chosen with the Intent.ACTION_OPEN_DOCUMENT_TREE ("/storage/2633-FECD").
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" />