title: How to Download File Using DownloadManager in API 29 or Android Q?
body: <p>As I am new in Android Development, I am trying to simple App using DownloadManager.</p>
  
  <p>Here is the code</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
  
  Button btn;
  
  private long referenceID;
  private DownloadManager downloadManager;
  private static final int PERMISSION_REQUEST_CODE = 1;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      btn = findViewById(R.id.btn);
  
      btn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
  
  
  
              if(Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M){
  
  
                  if (checkPermission())
                  {
  
                      /*** If Storage Permission Is Given, Check External storage is available for read and write***/
  
                      Uri image_uri = Uri.parse("https://unifiedclothes.com/Unifiedclothes/App_Gallery/thumb_8_121432471036-1432471036-SC-505.jpg");
  
                      referenceID = DownloadImage(image_uri);
  
  
  
  
                  } else {
  
                      requestPermission();
                  }
  
              }
  
              else{
                  Toast.makeText(MainActivity.this,"Permission Is Granted..",Toast.LENGTH_SHORT).show();
  
              }
          }
      });
  
      registerReceiver(receiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
  }
  
  private BroadcastReceiver receiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
  
          String action = intent.getAction();
  
          if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)){
  
  
  
              DownloadManager.Query ImageDownloadQuery = new DownloadManager.Query();
              //set the query filter to our previously Enqueued download
              ImageDownloadQuery.setFilterById(referenceID);
  
              //Query the download manager about downloads that have been requested.
              Cursor cursor = downloadManager.query(ImageDownloadQuery);
  
              if(cursor.moveToFirst()){
  
                  Toast.makeText(MainActivity.this,DownloadStatus(cursor),Toast.LENGTH_SHORT).show();
              }
  
  
  
          }
  
      }
  };
  
  private String DownloadStatus(Cursor cursor){
  
      //column for download  status
      int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
      int status = cursor.getInt(columnIndex);
      //column for reason code if the download failed or paused
      int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
      int reason = cursor.getInt(columnReason);
  
  
  
      String statusText = "";
      String reasonText = "";
  
      switch(status){
          case DownloadManager.STATUS_FAILED:
              statusText = "STATUS_FAILED";
              switch(reason){
                  case DownloadManager.ERROR_CANNOT_RESUME:
                      reasonText = "ERROR_CANNOT_RESUME";
                      break;
                  case DownloadManager.ERROR_DEVICE_NOT_FOUND:
                      reasonText = "ERROR_DEVICE_NOT_FOUND";
                      break;
                  case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
                      reasonText = "ERROR_FILE_ALREADY_EXISTS";
                      break;
                  case DownloadManager.ERROR_FILE_ERROR:
                      reasonText = "ERROR_FILE_ERROR";
                      break;
                  case DownloadManager.ERROR_HTTP_DATA_ERROR:
                      reasonText = "ERROR_HTTP_DATA_ERROR";
                      break;
                  case DownloadManager.ERROR_INSUFFICIENT_SPACE:
                      reasonText = "ERROR_INSUFFICIENT_SPACE";
                      break;
                  case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
                      reasonText = "ERROR_TOO_MANY_REDIRECTS";
                      break;
                  case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
                      reasonText = "ERROR_UNHANDLED_HTTP_CODE";
                      break;
                  case DownloadManager.ERROR_UNKNOWN:
                      reasonText = "ERROR_UNKNOWN";
                      break;
              }
              break;
          case DownloadManager.STATUS_PAUSED:
              statusText = "STATUS_PAUSED";
              switch(reason){
                  case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
                      reasonText = "PAUSED_QUEUED_FOR_WIFI";
                      break;
                  case DownloadManager.PAUSED_UNKNOWN:
                      reasonText = "PAUSED_UNKNOWN";
                      break;
                  case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
                      reasonText = "PAUSED_WAITING_FOR_NETWORK";
                      break;
                  case DownloadManager.PAUSED_WAITING_TO_RETRY:
                      reasonText = "PAUSED_WAITING_TO_RETRY";
                      break;
              }
              break;
          case DownloadManager.STATUS_PENDING:
              statusText = "STATUS_PENDING";
              break;
          case DownloadManager.STATUS_SUCCESSFUL:
              statusText = "Image Saved Successfully";
              //reasonText = "Filename:\n" + filename;
              Toast.makeText(MainActivity.this, "Download Status:" + "\n" + statusText + "\n" + reasonText, Toast.LENGTH_SHORT).show();
              break;
      }
  
      return statusText + reasonText;
  
  
  }
  
  
  private long DownloadImage(Uri uri){
  
      long downloadReference;
  
      downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  
      DownloadManager.Request request = new DownloadManager.Request(uri);
      //Setting title of request
      request.setTitle("Image Download");
  
      //Setting description of request
      request.setDescription("Image download using DownloadManager.");
  
  
      request.setDestinationInExternalPublicDir(getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/NewFile","sample2.jpg");
      //request.allowScanningByMediaScanner();
      request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
      downloadReference = downloadManager.enqueue(request);
  
  
      return  downloadReference;
  }
  
  
  private boolean checkPermission() {
      int result = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
      if (result == PackageManager.PERMISSION_GRANTED) {
          return true;
      } else {
          return false;
      }
  }
  
  
  private void requestPermission() {
  
      ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
  }
  
  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  
      if (requestCode == PERMISSION_REQUEST_CODE) {
  
          if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  
              Uri image_uri = Uri.parse("https://www.dccomics.com/sites/default/files/Char_GetToKnow_Batman80_5ca54cb83a27a6.53173051.png");
  
              referenceID = DownloadImage(image_uri);
  
  
          }
  
          else {
  
              Toast.makeText(MainActivity.this, "Permission Denied... \n You Should Allow External Storage Permission To Download Images.", Toast.LENGTH_LONG).show();
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>It works well when i run it on any device below API 29(My testing device was Nexus 5X ,ApI 28 emulator). But when I run it on Nexus 5X ,API 29 The app gets crashed. Here is the Logs:</p>
  
  <pre><code>2019-09-24 20:51:46.354 11322-11344/? E/DatabaseUtils: Writing exception to parcel
  java.lang.IllegalStateException: Not one of standard directories: /storage/emulated/0/Android/data/com.blz.prisoner.downloadmanager/files/Pictures/NewFile
      at com.android.providers.downloads.DownloadProvider.call(DownloadProvider.java:651)
      at android.content.ContentProvider.call(ContentProvider.java:2152)
      at android.content.ContentProvider$Transport.call(ContentProvider.java:477)
      at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:277)
      at android.os.Binder.execTransactInternal(Binder.java:1021)
      at android.os.Binder.execTransact(Binder.java:994)
  </code></pre>
  
  <p>2019-09-24 20:51:46.355 15023-15023/com.blz.prisoner.downloadmanager D/AndroidRuntime: Shutting down VM</p>
  
  <pre><code>--------- beginning of crash
  2019-09-24 20:51:46.360 15023-15023/com.blz.prisoner.downloadmanager E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.blz.prisoner.downloadmanager, PID: 15023
      java.lang.IllegalStateException: Not one of standard directories: /storage/emulated/0/Android/data/com.blz.prisoner.downloadmanager/files/Pictures/NewFile
          at android.os.Parcel.createException(Parcel.java:2079)
          at android.os.Parcel.readException(Parcel.java:2039)
          at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
          at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
          at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
          at android.content.ContentProviderClient.call(ContentProviderClient.java:558)
          at android.content.ContentProviderClient.call(ContentProviderClient.java:546)
          at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:567)
          at com.blz.prisoner.downloadmanager.MainActivity.DownloadImage(MainActivity.java:206)
          at com.blz.prisoner.downloadmanager.MainActivity.access$200(MainActivity.java:29)
          at com.blz.prisoner.downloadmanager.MainActivity$1.onClick(MainActivity.java:60)
          at android.view.View.performClick(View.java:7140)
          at android.view.View.performClickInternal(View.java:7117)
          at android.view.View.access$3500(View.java:801)
          at android.view.View$PerformClick.run(View.java:27351)
          at android.os.Handler.handleCallback(Handler.java:883)
          at android.os.Handler.dispatchMessage(Handler.java:100)
          at android.os.Looper.loop(Looper.java:214)
          at android.app.ActivityThread.main(ActivityThread.java:7356)
          at java.lang.reflect.Method.invoke(Native Method)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
  </code></pre>
  
  <p>I think the problem is on line " <strong>request.setDestinationInExternalPublicDir(getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/NewFile","sample2.jpg");</strong>" in <strong>DownloadImage(Uri uri)</strong> function. How to solve the problem??</p>
  
  <p>Another Problem is when I run the app on the device below API 29 it runs well but when I click on notification after completing the download it doesn't open the image on gallery/on the folder it was saved.</p>