io.demiseq.jetreader.service.DownloadService.java Source code

Java tutorial

Introduction

Here is the source code for io.demiseq.jetreader.service.DownloadService.java

Source

///*
// * Copyright (C) 2015 Hai Nguyen Thanh
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// *      http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
//// */

package io.demiseq.jetreader.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import java.util.ArrayList;

import io.demiseq.jetreader.R;
import io.demiseq.jetreader.activities.DownloadedReadActivity;
import io.demiseq.jetreader.activities.GeneralSettingsActivity;
import io.demiseq.jetreader.api.MangaLibrary;
import io.demiseq.jetreader.model.Chapter;
import io.demiseq.jetreader.model.Page;
import io.demiseq.jetreader.utils.FileDownloader;
import io.demiseq.jetreader.utils.FileUtils;
import io.demiseq.jetreader.utils.NotificationUtils;

public class DownloadService extends Service {

    private static ArrayList<Chapter> list = new ArrayList<>();
    private FileUtils fileUtils;
    private String image;
    private static int numberOfDownload = 0;
    private int maxDownload = 3;
    private boolean isNotificationEnabled = true;
    NotificationManager notificationManager;
    NotificationCompat.Builder builder;
    SharedPreferences prefs;
    private int numberOfCompleted = 0;
    private int numberOfFailed = 0;
    private boolean stop;

    protected BroadcastReceiver stopServiceReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            stop = true;
            stopSelf();
        }
    };

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

    private void handleIntent(Intent intent) {

        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        String numberString = prefs.getString(GeneralSettingsActivity.KEY_DOWNLOAD_NUM, "3");
        maxDownload = Integer.parseInt(numberString);

        isNotificationEnabled = prefs.getBoolean(GeneralSettingsActivity.KEY_SHOW_NOTIFICATION, true);

        fileUtils = new FileUtils();
        image = intent.getStringExtra("image");

        ArrayList<Chapter> chapters = intent.getParcelableArrayListExtra("list");

        list.addAll(chapters);

        if (notificationManager == null && builder == null) {
            registerReceiver(stopServiceReceiver, new IntentFilter("stopFilter"));
            PendingIntent stopIntent = PendingIntent.getBroadcast(this, 0, new Intent("stopFilter"), 0);
            notificationManager = (NotificationManager) DownloadService.this
                    .getSystemService(Context.NOTIFICATION_SERVICE);
            builder = new NotificationCompat.Builder(DownloadService.this);
            builder.setContentTitle("Jet Reader")
                    .setContentText(getResources().getString(R.string.background_progress))
                    .setSmallIcon(R.drawable.ic_stat_notification).setAutoCancel(false).setOngoing(true)
                    .setPriority(NotificationCompat.PRIORITY_MAX).addAction(R.drawable.ic_action_stop,
                            getResources().getString(R.string.stop_download), stopIntent);

            Notification note = builder.build();

            notificationManager.notify(1337, builder.build());
            startForeground(1337, note);
        }

        if (list.size() > 0 && list != null) {
            getChapterToDownload();
        }
    }

    private void getChapterToDownload() {
        synchronized (list) {
            while (numberOfDownload < maxDownload && list.size() > 0) {
                if (stop)
                    break;
                Chapter c = list.get(0);
                RetrieveAllPages task = new RetrieveAllPages(c.getMangaName(), c.getName());
                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, c.getUrl());
                numberOfDownload++;
                list.remove(0);
                builder.setContentText(getResources().getString(R.string.background_progress));
                builder.setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(getResources().getString(R.string.downloading) + " " + numberOfDownload + "\n"
                                + getResources().getString(R.string.queuing) + " " + list.size()));
                notificationManager.notify(1337, builder.build());
            }
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleIntent(intent);
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(stopServiceReceiver);
        list = new ArrayList<>();
        stopForeground(true);
    }

    public class RetrieveAllPages extends AsyncTask<String, Void, ArrayList<Page>> {
        private String mangaName;
        private String chapterName;

        public RetrieveAllPages(String m, String c) {
            mangaName = m;
            chapterName = c;
        }

        public ArrayList<Page> doInBackground(String... params) {
            MangaLibrary download = new MangaLibrary(params[0]);
            ArrayList<Page> arr;
            try {
                arr = download.GetPages();
                if (stop)
                    throw new Exception("Interrupted");
                return arr;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        public void onPostExecute(ArrayList<Page> result) {
            if (result != null) {
                DownloadAsync task = new DownloadAsync(mangaName, chapterName, isNotificationEnabled);
                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, result);
            } else {
                numberOfDownload--;
                if (numberOfDownload == 0 && list.size() == 0) {
                    stopSelf();
                } else if (list.size() > 0) {
                    getChapterToDownload();
                }
            }

        }
    }

    class DownloadAsync extends AsyncTask<ArrayList<Page>, Integer, Boolean> {
        private String mangaName;
        private String chapterName;
        private boolean enabledNotification;
        private int id = NotificationUtils.getID();
        private NotificationManager mNotifyManager;
        private NotificationCompat.Builder mBuilder;
        private PendingIntent pendingIntent;

        public DownloadAsync(String m, String c, boolean isEnabled) {
            mangaName = m;
            chapterName = c;
            enabledNotification = isEnabled;
        }

        @Override
        public void onPreExecute() {
            if (enabledNotification) {
                mNotifyManager = (NotificationManager) DownloadService.this
                        .getSystemService(Context.NOTIFICATION_SERVICE);
                mBuilder = new NotificationCompat.Builder(DownloadService.this);
                mBuilder.setContentTitle(mangaName)
                        .setContentText(getResources().getString(R.string.downloading) + " " + chapterName)
                        .setSmallIcon(android.R.drawable.stat_sys_download).setAutoCancel(false);
                mBuilder.setProgress(100, 0, false);
                mNotifyManager.notify(id, mBuilder.build());
            }
        }

        public Boolean doInBackground(ArrayList<Page>... page) {

            ArrayList<Page> pages = page[0];

            try {

                FileDownloader downloader = new FileDownloader(mangaName, chapterName);

                if (!fileUtils.hasPoster(mangaName))
                    downloader.downloadPoster(image);

                String fileExtension = pages.get(0).getUrl().substring(pages.get(0).getUrl().lastIndexOf("."));

                for (int i = 0; i < pages.size(); i++) {
                    if (stop)
                        throw new Exception("Interrupted");
                    String fileName;
                    if (i < 10)
                        fileName = "000" + i + fileExtension;
                    else if (i >= 10 && i < 100)
                        fileName = "00" + i + fileExtension;
                    else if (i >= 100 && i < 1000)
                        fileName = "0" + i + fileExtension;
                    else
                        fileName = i + fileExtension;
                    downloader.downloadAndRename(pages.get(i).getUrl(), fileName);
                    publishProgress((int) ((i * 100) / pages.size()));
                }
            } catch (final Exception e) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                    }
                });
                return false;
            }

            if (enabledNotification) {
                Intent intent = new Intent(DownloadService.this, DownloadedReadActivity.class);
                intent.putExtra("manga_name", mangaName);
                intent.putExtra("chapter_name", chapterName);
                if (fileUtils.isChapterDownloaded(mangaName, chapterName)) {
                    intent.putStringArrayListExtra("image_path", fileUtils.getFilePaths());
                }
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                pendingIntent = PendingIntent.getActivity(DownloadService.this, id, intent, 0);
            }

            return true;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // Update progress
            if (enabledNotification) {
                mBuilder.setProgress(100, values[0], false);
                mNotifyManager.notify(id, mBuilder.build());
                super.onProgressUpdate(values);
            }
        }

        @Override
        public void onPostExecute(Boolean result) {
            if (enabledNotification) {
                if (result) {
                    mBuilder.setContentText(
                            getResources().getString(R.string.download_completed) + " " + chapterName);
                    mBuilder.setProgress(0, 0, false);
                    mBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
                    mBuilder.setAutoCancel(true);
                    mBuilder.setContentIntent(pendingIntent);
                    mNotifyManager.notify(id, mBuilder.build());
                } else {
                    System.out.println(fileUtils.deleteChapter(mangaName, chapterName));
                    mBuilder.setContentText(getResources().getString(R.string.download_failed) + " " + chapterName);
                    mBuilder.setProgress(0, 0, false);
                    mBuilder.setAutoCancel(true);
                    mBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
                    mNotifyManager.notify(id, mBuilder.build());
                }
            }
            if (result)
                numberOfCompleted++;
            else
                numberOfFailed++;
            numberOfDownload--;
            if (numberOfDownload == 0 && list.size() == 0) {
                notificationManager = (NotificationManager) DownloadService.this
                        .getSystemService(Context.NOTIFICATION_SERVICE);
                builder = new NotificationCompat.Builder(DownloadService.this);
                builder.setContentTitle("Jet Reader").setSmallIcon(R.drawable.ic_stat_notification)
                        .setAutoCancel(true)
                        .setContentText(getResources().getString(R.string.completed) + " " + numberOfCompleted
                                + "\n" + getResources().getString(R.string.failed) + " " + numberOfFailed);
                Notification note = builder.build();
                note.defaults |= Notification.DEFAULT_VIBRATE;
                note.defaults |= Notification.DEFAULT_SOUND;
                note.defaults |= Notification.DEFAULT_LIGHTS;

                notificationManager.notify(2304, builder.build());
                stopSelf();
            } else if (list.size() > 0) {
                getChapterToDownload();
            }
        }
    }
}