1

I am using Asynctask to download files in my Android app. As the file size is generally large, I start the file download in the background. There is no progressbar or anything shown so that the user can access other parts of the app while the download is in progress.

On completion of file download, I want to inform the user that his file has been successfully downloaded.

Using onPostexecute() method creates problems because the user is no longer on the same activity when the download process began. As a result I cannot use Alert dialog & Notifications from onPostExecute() as there are problems about the context.

I have pasted below the code for my Asynctask. So, kindly suggest me a way to fix this.

class DownloadProcess extends AsyncTask<Void,Void,Void>{

        Context cxt;

        public DownloadProcess(Context context) {
            cxt=context;
        }


        @Override
        protected Void doInBackground(Void... arg0) {
             try {
                    String fileurl="http://www.bigfiles/" + filenm;
                    URL url = new URL(fileurl); 
                    HttpURLConnection c = (HttpURLConnection) url.openConnection();
                    c.setRequestMethod("GET");
                    c.setDoOutput(true);
                    c.connect();


                    Path = Environment.getExternalStorageDirectory() + "/download/";
                    File pth=new File(Path);
                    File file = new File(pth,filenm);
                    FileOutputStream fos = new FileOutputStream(file);

                    InputStream is = c.getInputStream();

                    byte[] buffer = new byte[1024];
                    int len1 = 0;
                    while ((len1 = is.read(buffer)) != -1) {
                        fos.write(buffer, 0, len1);
                    }
                    fos.close();
                    is.close();

                } catch (IOException e) {
                    Log.d("amit", "Error: " + e);
                }

            return null;
        }


        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            if (((Activity) AppDet.this).isFinishing() == false) {      
                AlertDialog.Builder builder = new AlertDialog.Builder(AppDet.this);
                builder.setMessage("The app download is complete. Please check " +Path+ " on your device and open the " + filenm+ " file downloaded");
                builder.setCancelable(true);
                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                    });
                AlertDialog alert = builder.create();
                alert.show();
                MediaPlayer md=MediaPlayer.create(AppDet.this, R.raw.ding);
                md.start();
            }
            else {
                //Not sure what to do here
            }
        }
ambit
  • 1,099
  • 2
  • 28
  • 43

3 Answers3

2

How about using IntentService instead ... it has a context so you could use notifications .. dialog boxes are annoying and must die

Moog
  • 10,193
  • 2
  • 40
  • 66
1

I think you should use

AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());

in your code Instead

QAMAR
  • 2,684
  • 22
  • 28
  • If I do that, I get an error like: http://stackoverflow.com/questions/5796611/dialog-throwing-unable-to-add-window-token-null-is-not-for-an-application-wi – ambit Feb 02 '13 at 15:47
0

Use a notification (not an alert pop-up, that is bad UX) together with the application context as pointed out by @QAMAR.

However, in our app we show a notification from an android.app.Service which manages a subset of tasks (we do not add results to the UI direct from the AsyncTask - they are liable to be killed off as your activity life cycle comes to a close, a service gives far more explicit control over when the service and it's child tasks can end)

final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentIntent(pendingIntent)
.setSmallIcon(<some drawable>)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle(<some internationalised message>)
.setContentText(<some internationalised subtitle>);

// Send the notification.
((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(<notification id>, builder.getNotification());

If you need the results of the async task to affect the activity you are working with then bound services is what you need. I'm about to delve into these today so will post back with any insights I have...

BrantApps
  • 6,362
  • 2
  • 27
  • 60