Manish Karena
Manish Karena

Reputation: 734

Manage Queue in android with service

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...

Upvotes: 0

Views: 2582

Answers (1)

Manish Karena
Manish Karena

Reputation: 734

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.

Upvotes: 2

Related Questions