0

I have a activity with recycler-view, and each list item has a download button.inside button click event i manage make call for download-service.so how can i manage queue when user click more than one download button with custom notification update.

I have googled and tried some solutions are:

1.How to Manage Queue of Runnable Tasks in Android

2.how to handle a queue in android?? java

3.Best way to update Activity from a Queue

but doesn't find the correct way to implement queue with notification update.

Here is my DownloadService Code:

public class DownloadApkService extends Service {

    private NotificationCompat.Builder notificationBuilder;
    private NotificationManager notificationManager;

    String downloadLocation;

    String appId = null;
    String appLink = null;
    String appName = null;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Queue", "queue");

        appId = intent.getStringExtra(Constants.COM_APP_ID);
        appLink = intent.getStringExtra(Constants.COM_APP_LINK);
        appName = intent.getStringExtra(Constants.COM_APP_NAME);

        Thread thread=new Thread(new MyThread(startId));
        thread.start();

        return START_STICKY;
    }

    final class MyThread implements Runnable {

        int service_id;

        MyThread(int service_id) {
            this.service_id = service_id;
        }

        @Override
        public void run() {

            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            notificationBuilder = new NotificationCompat.Builder(DownloadApkService.this)
                    .setSmallIcon(R.drawable.ic_list_app_icon)
                    .setContentTitle(appName).setProgress(0, 0, true)
                    .setContentText("Downloading APK")
                    .setOngoing(true)
                    .setAutoCancel(true);
            notificationManager.notify(0, notificationBuilder.build());

            downloadApk();

        }
    }

    private void downloadApk() {

        downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
        String fileName = appName + ".apk";
        downloadLocation += fileName;

        File sourceFile = new File(downloadLocation);
        if (sourceFile.exists()) {
            sourceFile.delete();
        }

        Intent intentResponse = new Intent();
        intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
        intentResponse.putExtra(Constants.COM_APP_ID, appId);
        intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, "0");
        sendBroadcast(intentResponse);

        new DownloadFileFromURL().execute(appLink);

    }

    public void installApk(Uri uri) {
        Intent install = new Intent(Intent.ACTION_VIEW);
        install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.setDataAndType(uri,
                "application/vnd.android.package-archive");
        DownloadApkService.this.startActivity(install);

    }

    /**
     * Background Async Task to download file
     */
    class DownloadFileFromURL extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Bar Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        /**
         * Downloading file in background thread
         */
        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                Log.e("ULR", f_url[0]);
                URL url = new URL(f_url[0].trim());
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.connect();

                // this will be useful so that you can show a tipical 0-100%
                // progress bar
                int lenghtOfFile = connection.getContentLength();
                Log.e("Length", lenghtOfFile + "");

                // download the file
                InputStream input = connection.getInputStream();

                downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
                String fileName = appName + ".apk";
                downloadLocation += fileName;

                // Output stream
                FileOutputStream output = new FileOutputStream(downloadLocation);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress("" + (int) ((total * 100) / lenghtOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();

            } catch (Exception e) {
                Log.e("Error: ", e.getStackTrace().toString());
            }

            return null;
        }

        /**
         * Updating progress bar
         */
        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            Intent intentResponse = new Intent();
            intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
            intentResponse.putExtra(Constants.COM_APP_ID, appId);
            intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, progress[0]);
            sendBroadcast(intentResponse);
        }

        /**
         * After completing background task Dismiss the progress dialog
         **/
        @Override
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after the file was downloaded
            notificationManager.cancel(0);
            installApk(Uri.fromFile(new File(downloadLocation)));

        }

    }
}

any help would be appriciated...

1 Answer 1

2

Finally got answer for my own question. I managed it with Queue class that is in java.util package. The code i have been used is below:

public class DownloadApkService extends Service {

    private NotificationManager notificationManager = null;

    String downloadLocation;

    String appId = null;
    String appLink = null;
    String appName = null;
    String isApkFromServer = null;

    public boolean isDownloading = false;

    public static Queue<QueueData> downloadQueue = new LinkedList<>();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (isDownloading) {
            QueueData queueData = new QueueData();
            queueData.setAppId(intent.getStringExtra(Constants.COM_APP_ID));
            queueData.setAppLink(intent.getStringExtra(Constants.COM_APP_LINK));
            queueData.setIsApkFromServer(intent.getStringExtra(Constants.COM_APK_FROM_SERVER));
            queueData.setAppName(intent.getStringExtra(Constants.COM_APP_NAME));

            downloadQueue.add(queueData);
            Intent intentQueueingApk = new Intent();
            intentQueueingApk.setAction(Constants.ACTION_QUEUEING_APK);
            sendBroadcast(intentQueueingApk);
            return START_NOT_STICKY;
        } else {
            appId = intent.getStringExtra(Constants.COM_APP_ID);
            appLink = intent.getStringExtra(Constants.COM_APP_LINK);
            appName = intent.getStringExtra(Constants.COM_APP_NAME);
            isApkFromServer = intent.getStringExtra(Constants.COM_APK_FROM_SERVER);
        }
        Thread thread = new Thread(new MyThread());
        thread.start();

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (notificationManager != null) {
            notificationManager.cancel(0);
        }
    }

    class MyThread implements Runnable {

        MyThread() {
        }

        @Override
        public void run() {

            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(DownloadApkService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle(appName).setProgress(0, 0, true)
                    .setContentText(getResources().getText(R.string.downloading_notification))
                    .setOngoing(true)
                    .setAutoCancel(true);
            notificationManager.notify(0, notificationBuilder.build());
            new DownloadFileFromURL().execute(appLink);

        }
    }

    public void installApk(Uri uri) {
        Intent install = new Intent(Intent.ACTION_VIEW);
        install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.setDataAndType(uri,
                "application/vnd.android.package-archive");
        DownloadApkService.this.startActivity(install);

    }

    /**
     * Background Async Task to download file
     */
    class DownloadFileFromURL extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Bar Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            isDownloading = true;

            Intent intentResponse = new Intent();
            intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
            intentResponse.putExtra(Constants.COM_APP_ID, appId);
            intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, "0");
            sendBroadcast(intentResponse);
        }

        /**
         * Downloading file in background thread
         */
        @Override
        protected String doInBackground(String... f_url) {
            int count;
            HttpURLConnection connection=null;
            try {
                String link=f_url[0].replace(" ","%20");
                URL url = new URL(link);
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestProperty("Accept-Encoding", "identity");
                int lenghtOfFile = connection.getContentLength();
                connection.connect();

                // this will be useful so that you can show a tipical 0-100%
                // progress bar


                // download the file
                InputStream input = new BufferedInputStream(connection.getInputStream());


                downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
                String fileName = appName + ".apk";
                downloadLocation += fileName;

                File sourceFile = new File(downloadLocation);
                if (sourceFile.exists()) {
                    sourceFile.delete();
                }

                // Output stream
                FileOutputStream output = new FileOutputStream(downloadLocation);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress("" + (int) ((total * 100) / lenghtOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();

            } catch (Exception e) {
                return "fail";
            }finally {
                if(connection != null)
                    connection.disconnect();
            }

            return "success";
        }

        /**
         * Updating progress bar
         */
        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            Intent intentResponse = new Intent();
            intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
            intentResponse.putExtra(Constants.COM_APP_ID, appId);
            intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, progress[0]);
            sendBroadcast(intentResponse);

            Intent intentQueueingApk = new Intent();
            intentQueueingApk.setAction(Constants.ACTION_QUEUEING_APK);
            sendBroadcast(intentQueueingApk);
        }

        /**
         * After completing background task Dismiss the progress dialog
         **/
        @Override
        protected void onPostExecute(String file_url) {

            notificationManager.cancel(0);
            if (file_url.equals("success")) {
                Intent intentResponse = new Intent();
                intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK_COMPLETE);
                intentResponse.putExtra(Constants.COM_APP_ID, appId);
                sendBroadcast(intentResponse);

                isDownloading = false;

                if (isApkFromServer!=null && isApkFromServer.equals("0")) {
                    Intent intent = new Intent(DownloadApkService.this, UploadApkService.class);
                    intent.putExtra(Constants.COM_APP_ID, mAppDetails.getId());
                    intent.putExtra(Constants.COM_APK_FILE_PATH, downloadLocation);
                    startService(intent);
                }

                installApk(Uri.fromFile(new File(downloadLocation)));
            } else if (file_url.equals("fail")) {
                isDownloading = false;
                Intent intentResponse = new Intent();
                intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK_FAILED);
                intentResponse.putExtra(Constants.COM_APP_ID, appId);
                sendBroadcast(intentResponse);
            }

            if (/*isDownloading &&*/ !downloadQueue.isEmpty()) {
                QueueData queueData = downloadQueue.poll();
                appId = queueData.getAppId();
                appLink = queueData.getAppLink();
                appName = queueData.getAppName();
                isApkFromServer = queueData.getIsApkFromServer();

                Thread thread = new Thread(new MyThread());
                thread.start();
            }

        }

    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        if (notificationManager != null)
            notificationManager.cancel(0);
    }
}

I hope it's going to be helpful for someone.

Sign up to request clarification or add additional context in comments.

1 Comment

Instead of implementing a custom queue, you can use android.os.Handler which takes care of this automatically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.