1

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" />
  • `ACTION_OPEN_DOCUMENT_TREE` does not magically give you or another process write access to removable storage via the filesystem. – CommonsWare May 02 '19 at 18:35
  • ACTION_OPEN_DOCUMENT_TREE opens a dialog where I can choose the removable storage (/storage/2633-FECD). After that I can save files to this path in Android 6.0.1 but not in Android 8.1. – AndroidNewbieProgrammer May 02 '19 at 18:41
  • I would not assume that it will work on all Android 6.0 devices. Also note that `file` `Uri` values will not work in general on Android 7.0+. – CommonsWare May 02 '19 at 18:49
  • What would be the alternative to file Uri on Android 7.0+? – AndroidNewbieProgrammer May 02 '19 at 18:53
  • You can try `FileProvider`, though you will not be able to download directly to your desired location. Download to internal storage (e.g., `getCacheDir()`). – CommonsWare May 02 '19 at 18:56
  • 1
    So there is no way to download files directly to removable storage in Android Oreo? Download to internal storage is no option for me because the files I would like to download are either to large for internal storage or it would take too much extra time to download them to internal storage first an then copy them to removable storage. – AndroidNewbieProgrammer May 02 '19 at 19:10
  • You can download direct to removable storage. You have to do that yourself, not using `DownloadManager`. For example, [use OkHttp](https://stackoverflow.com/a/29012988/115145). – CommonsWare May 02 '19 at 19:18
  • Ok, thank you, I could make it work writing my own download code. I didn't no that DownloadManger doesn't work with removable storage on Android Oreo. – AndroidNewbieProgrammer May 02 '19 at 21:41

0 Answers0