0

LEVEL: Beginner
Language: Java
IDE: Android Studio
CASE: Downloading multiple MP3 files from multiple URL's in a row in the background.
ISSUE: download task in the loop to download all the urls. the songs did download in the following path but aren't fully downloaded (every song is downloaded for 3 seconds/4 seconds basically very less). don't know what's the problem, It'll be great if i can get any help

  • receive mp3 url's from API
  • download them using the following code. (ISSUE)
  • get the path of all and store them in the Database
  • fetch the path and play one by one continuously.

    private class DownloadTask extends AsyncTask<SongDetails, Integer, String> {
    Context context;
    
    public DownloadTask(Context context) {
        this.context = context;
    }
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Utilities.showProgressDialog(getActivity(), getFragmentManager());
    }
    
    @Override
    protected String doInBackground(SongDetails... songDetails) {
        for (SongDetails songs : songDetails
        ) {
            donwloadsong(songs);
        }
        return null;
    }
    
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Utilities.dismissProgressDialog();
    }
    }
    
    
    
    
     for (SongDetails songs : songDetails
        ) {
            downloadTask(songs);
        }
    
    
     public void downloadTask(SongDetails songs){
       HttpURLConnection httpURLConnection = null;
       try {
         URL url = new URL(songs.getUrl());
         httpURLConnection = (HttpURLConnection) url.openConnection();
         httpURLConnection.setRequestMethod("GET");
         httpURLConnection.connect();
    
        int fileLength = httpURLConnection.getContentLength();
             InputStream inputStream = new 
        BufferedInputStream(url.openStream(), 8192);
        OutputStream outputStream1;
        outputStream1 = new 
        FileOutputStream(Environment.getExternalStorageDirectory() + "/gbeduwarssongs/" + songDetails.getTitle().trim() + ".mp3");
        int count = 0;
             byte data[] = new byte[1024];
        int buffer_length;
    
        while ((buffer_length = inputStream.read(data)) != -1) {
            outputStream1.write(data, 0, count);
              count += buffer_length;
        }
        outputStream1.flush();
        outputStream1.close();
        inputStream.close();
    
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("Error", "Download Error Exception " + e.getMessage());
    } finally {
        if (httpURLConnection != null)
            httpURLConnection.disconnect();
      }
    }
    
Honey
  • 19
  • 10
  • can you post more code i mean complete actitivity code.. – Abdul Waheed Apr 04 '19 at 12:27
  • If you expect the download to last longer than a couple of seconds, then I'd suggest you use something other than `AsyncTask`, which is really only suitable for short off-UI-thread work. A Foreground `Service` perhaps, or maybe `DownloadManager` – PPartisan Apr 04 '19 at 12:30
  • Sure i'll update the code @AbdulWaheed – Honey Apr 04 '19 at 12:31
  • DownloadManager notifies the user in the notification section if am not wrong, I don't want user to know what's happening in the background @PPartisan Also i'll try with Foreground Service – Honey Apr 04 '19 at 12:32
  • DownloadManager did the work. Thankyou – Honey Apr 09 '19 at 08:29
  • DownloadManager doesn't work below Nougat. Could you tell me what could i use for lower level API's @PPartisan – Honey Apr 17 '19 at 05:56
  • [`DownloadManager`](https://developer.android.com/reference/android/app/DownloadManager) is compatible with Android Gingerbread and up – PPartisan Apr 17 '19 at 06:39
  • I got it yesterday, i was adding a method named setRequiresCharging(false) which needed API 24 in DownloadManager. Thank you for your revert :) @PPartisan – Honey Apr 18 '19 at 08:19

2 Answers2

0

Rather calling iteration inside a new thread, use iteration first and then start new thread in every iteration. I hope it will help you. I am posting code for your help.

for (SongDetails songs : songDetails) {
        new DownloadTask(pass your song object in constructor).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

and in doInBackground call your downloading method stuff.

Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58
  • Tried this, but i got an Error: Cannot execute task: the task is already running. Also AsyncTask can only be executed once as i searched the error. So iterating it did not go well. @AbdulWaheed – Honey Apr 04 '19 at 13:58
0

I offer to use DownloadManager or workmanager for it. AsyncTask has used a bad idea. It has a problem with a memory leak. The asyncTask use only one thread

The same question

Alexander
  • 511
  • 4
  • 14