cw.kop.autobackground.files.DownloadThread.java Source code

Java tutorial

Introduction

Here is the source code for cw.kop.autobackground.files.DownloadThread.java

Source

/*
 * Copyright (C) Winson Chiu
 *
 * 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 cw.kop.autobackground.files;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Build;
import android.os.Looper;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.util.Patterns;
import android.widget.Toast;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cw.kop.autobackground.BuildConfig;
import cw.kop.autobackground.LiveWallpaperService;
import cw.kop.autobackground.R;
import cw.kop.autobackground.settings.ApiKeys;
import cw.kop.autobackground.settings.AppSettings;
import cw.kop.autobackground.sources.Source;

/**
 * Created by TheKeeperOfPie on 8/6/2014.
 */
public class DownloadThread extends Thread {

    private static final int NOTIFICATION_ID = 1;
    private static final String TAG = DownloadThread.class.getCanonicalName();
    private Context appContext;
    private String imageDetails = "";
    private NotificationManager notificationManager = null;
    private Notification.Builder notifyProgress;
    private int progressMax = 0;
    private int totalDownloaded = 0;
    private int totalTarget = 0;
    private HashSet<String> usedLinks;
    private List<File> downloadedFiles;

    public DownloadThread(Context context) {
        appContext = context;
    }

    @Override
    public void run() {
        super.run();

        Looper.prepare();

        if (AppSettings.useDownloadNotification()) {
            PendingIntent pendingStopIntent = PendingIntent.getBroadcast(appContext, 0,
                    new Intent(LiveWallpaperService.STOP_DOWNLOAD), 0);

            notificationManager = (NotificationManager) appContext.getSystemService(Context.NOTIFICATION_SERVICE);
            notifyProgress = new Notification.Builder(appContext).setContentTitle("AutoBackground")
                    .setContentText("Downloading images...").setSmallIcon(R.drawable.ic_photo_white_24dp);

            if (Build.VERSION.SDK_INT >= 16) {
                notifyProgress.setPriority(Notification.PRIORITY_MIN);
                notifyProgress.addAction(R.drawable.ic_cancel_white_24dp, "Stop Download", pendingStopIntent);
            }

            updateNotification(0);
        }

        String downloadCacheDir = AppSettings.getDownloadPath();

        File cache = new File(downloadCacheDir);

        if (!cache.exists() || !cache.isDirectory()) {
            cache.mkdir();
        }

        List<Integer> indexes = new ArrayList<>();
        for (int index = 0; index < AppSettings.getNumberSources(); index++) {

            Source source = AppSettings.getSource(index);

            if (!source.getType().equals(AppSettings.FOLDER) && source.isUse()) {
                indexes.add(index);
                progressMax += source.getNum();
            }
        }

        usedLinks = new HashSet<>();

        if (AppSettings.checkDuplicates()) {
            Set<String> rawLinks = AppSettings.getUsedLinks();
            for (String link : rawLinks) {
                if (link.lastIndexOf("Time:") > 0) {
                    link = link.substring(0, link.lastIndexOf("Time:"));
                }
                usedLinks.add(link);
            }
        }

        downloadedFiles = new ArrayList<>();

        for (int index : indexes) {

            Source source = AppSettings.getSource(index);

            if (isInterrupted()) {
                cancel();
                return;
            }

            try {

                if (AppSettings.deleteOldImages()) {
                    FileHandler.deleteBitmaps(appContext, source);
                }

                String title = source.getTitle();
                File file = new File(downloadCacheDir + "/" + title + " " + AppSettings.getImagePrefix());

                if (!file.exists() || !file.isDirectory()) {
                    file.mkdir();
                }

                String sourceType = source.getType();
                String sourceData = source.getData();

                switch (sourceType) {
                case AppSettings.WEBSITE:
                    downloadWebsite(sourceData, source);
                    break;
                case AppSettings.IMGUR_SUBREDDIT:
                    downloadImgurSubreddit(sourceData, source);
                    break;
                case AppSettings.IMGUR_ALBUM:
                    downloadImgurAlbum(sourceData, source);
                    break;
                case AppSettings.GOOGLE_ALBUM:
                    downloadPicasa(sourceData, source);
                    break;
                case AppSettings.TUMBLR_BLOG:
                    downloadTumblrBlog(sourceData, source);
                    break;
                case AppSettings.TUMBLR_TAG:
                    downloadTumblrTag(sourceData, source);
                    break;
                case AppSettings.REDDIT_SUBREDDIT:
                    downloadRedditSubreddit(sourceData, source);
                    break;
                }

                totalTarget += source.getNum();

                updateNotification(totalTarget);

            } catch (IOException | IllegalArgumentException e) {
                sendToast("Invalid URL: " + source.getData());
                Log.i(TAG, "Invalid URL");
            }
        }
        finish();
    }

    private Set<String> compileImageLinks(Document doc, String tag, String attr) {

        Elements downloadLinks = doc.select(tag);
        Set<String> links = new HashSet<>();

        for (Element link : downloadLinks) {
            String url = link.attr(attr);
            if (!url.contains("http")) {
                url = "http:" + url;
            }
            if (link.attr("width") != null && !link.attr("width").equals("")) {
                try {
                    if (Integer.parseInt(link.attr("width")) < AppSettings.getImageWidth()
                            || Integer.parseInt(link.attr("height")) < AppSettings.getImageHeight()) {
                        continue;
                    }
                } catch (NumberFormatException e) {
                }
            }
            if (url.contains(".png") || url.contains(".jpg") || url.contains(".jpeg")) {
                links.add(url);
            } else if (AppSettings.forceDownload() && url.length() > 5
                    && (url.contains(".com") || url.contains(".org") || url.contains(".net"))) {
                links.add(url + ".png");
                links.add(url + ".jpg");
                links.add(url);
            }
        }
        return links;
    }

    private void startDownload(List<String> links, List<String> data, Source source) {
        String dir = AppSettings.getDownloadPath();
        String title = source.getTitle();
        int targetNum = source.getNum();
        int numDownloaded = 0;

        Set<File> downloadedFiles = new HashSet<>();

        for (int count = 0; numDownloaded < targetNum && count < links.size(); count++) {
            if (isInterrupted()) {
                break;
            }

            String randLink = links.get(count);

            boolean newLink = usedLinks.add(randLink);

            if (newLink) {

                Bitmap bitmap = getImage(randLink);

                if (bitmap != null) {
                    long time = System.currentTimeMillis();
                    File file = new File(dir + "/" + title + " " + AppSettings.getImagePrefix() + "/" + title + " "
                            + AppSettings.getImagePrefix() + " " + time + ".png");

                    if (AppSettings.useImageHistory()) {
                        AppSettings.addUsedLink(randLink, time);
                        if (AppSettings.cacheThumbnails()) {
                            writeToFileWithThumbnail(bitmap, data.get(count), dir, file, time);
                        } else {
                            writeToFile(bitmap, data.get(count), file);
                        }
                    } else {
                        writeToFile(bitmap, data.get(count), file);
                    }
                    downloadedFiles.add(file);
                    numDownloaded++;
                    updateNotification(++totalTarget);
                }
            }
        }

        removeExtras(dir, title, targetNum, downloadedFiles);
        imageDetails += title + ": " + numDownloaded + " images" + AppSettings.DATA_SPLITTER;
        if (numDownloaded == 0) {
            sendToast("No images downloaded from " + title);
        }
        if (!isInterrupted() && numDownloaded < targetNum) {
            sendToast("Not enough photos from " + source.getData() + " "
                    + "Try lowering the resolution or changing sources. "
                    + "There may also have been too many duplicates.");
        }

        totalDownloaded += numDownloaded;
    }

    private void removeExtras(String dir, String title, int targetNum, Set<File> downloadedFiles) {

        File mainDir = new File(dir + "/" + title + " " + AppSettings.getImagePrefix());
        FilenameFilter filenameFilter = FileHandler.getImageFileNameFilter();

        List<File> files = new ArrayList<>(Arrays.asList(mainDir.listFiles(filenameFilter)));
        files.removeAll(downloadedFiles);

        if (!AppSettings.keepImages()) {
            int extra = mainDir.list(filenameFilter).length - targetNum;
            while (extra > 0 && files.size() > 0) {
                File file = files.get(0);
                AppSettings.clearUrl(file.getName());
                file.delete();
                files.remove(file);
                extra--;
            }
        }
    }

    private void downloadWebsite(String url, Source source) throws IOException {

        if (isInterrupted()) {
            return;
        }

        Set<String> imageLinks = new HashSet<>();
        List<String> imageList = new ArrayList<>();

        Document linkDoc = Jsoup.connect(url).get();

        imageLinks.addAll(compileImageLinks(linkDoc, "a", "href"));
        imageLinks.addAll(compileImageLinks(linkDoc, "img", "href"));
        imageLinks.addAll(compileImageLinks(linkDoc, "img", "src"));
        imageList.addAll(imageLinks);

        Log.i(TAG, "imageLinks: " + imageList.toString());

        startDownload(imageList, imageList, source);
    }

    private void downloadImgurSubreddit(String subreddit, Source source) {

        if (isInterrupted()) {
            return;
        }

        String apiUrl = "https://api.imgur.com/3/gallery/r/" + subreddit;

        Log.i(TAG, "apiUrl: " + apiUrl);

        try {
            HttpGet httpGet = new HttpGet(apiUrl);
            httpGet.setHeader("Authorization", "Client-ID " + ApiKeys.IMGUR_CLIENT_ID);
            httpGet.setHeader("Content-type", "application/json");

            String response = getResponse(httpGet);
            if (response == null) {
                return;
            }

            JSONObject jsonObject = new JSONObject(response);
            JSONArray jArray = jsonObject.getJSONArray("data");

            List<String> imageList = new ArrayList<>();
            List<String> imagePages = new ArrayList<>();

            for (int i = 0; i < jArray.length(); i++) {
                JSONObject imageObject = jArray.getJSONObject(i);

                imageList.add(imageObject.getString("link"));

                String subredditPage = imageObject.getString("reddit_comments");
                if (subredditPage != null && !subredditPage.equals("")) {
                    imagePages.add("http://reddit.com" + subredditPage);
                } else {
                    imagePages.add(imageObject.getString("link"));
                }
            }

            Log.i(TAG, "imageList size: " + imageList.size());

            startDownload(imageList, imagePages, source);

        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, "JSON parse error");
        }
    }

    private void downloadImgurAlbum(String albumId, Source source) {

        if (isInterrupted()) {
            return;
        }

        if (albumId.contains("/")) {
            albumId = albumId.substring(0, albumId.indexOf("/"));
        }
        String apiUrl = "https://api.imgur.com/3/album/" + albumId + "/images";

        Log.i(TAG, "apiUrl: " + apiUrl);

        try {
            HttpGet httpGet = new HttpGet(apiUrl);
            httpGet.setHeader("Authorization", "Client-ID " + ApiKeys.IMGUR_CLIENT_ID);
            httpGet.setHeader("Content-type", "application/json");

            String response = getResponse(httpGet);
            if (response == null) {
                return;
            }

            JSONObject jsonObject = new JSONObject(response);
            JSONArray jArray = jsonObject.getJSONArray("data");

            List<String> imageList = new ArrayList<>();

            for (int i = 0; i < jArray.length(); i++) {
                JSONObject imageObject = jArray.getJSONObject(i);

                imageList.add(imageObject.getString("link"));

            }

            Log.i(TAG, "imageList size: " + imageList.size());

            startDownload(imageList, imageList, source);

        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, "JSON parse error");
        }
    }

    private void downloadPicasa(String data, Source source) {

        if (isInterrupted()) {
            return;
        }

        if (data.contains("user/")) {
            data = data.substring(data.indexOf("user/"));
        } else {
            return;
        }

        HttpGet httpGet = new HttpGet("https://picasaweb.google.com/data/feed/api/" + data + "?imgmax=d");
        httpGet.setHeader("Authorization", "OAuth " + AppSettings.getGoogleAccountToken());
        httpGet.setHeader("X-GData-Client", ApiKeys.PICASA_CLIENT_ID);
        httpGet.setHeader("GData-Version", "2");

        String response = getResponse(httpGet);
        if (response == null) {
            return;
        }

        Document linkDoc = Jsoup.parse(response);

        List<String> imageList = new ArrayList<>();

        for (Element link : linkDoc.select("media|group")) {
            imageList.add(link.select("media|content").attr("url"));
        }

        startDownload(imageList, imageList, source);

    }

    private void downloadTumblrBlog(String data, Source source) {

        if (isInterrupted()) {
            return;
        }

        try {
            HttpGet httpGet = new HttpGet("http://api.tumblr.com/v2/blog/" + data
                    + ".tumblr.com/posts/photo?api_key=" + ApiKeys.TUMBLR_CLIENT_ID);

            String response = getResponse(httpGet);
            if (response == null) {
                return;
            }

            JSONObject jsonObject = new JSONObject(response);
            JSONArray jArray = jsonObject.getJSONObject("response").getJSONArray("posts");

            List<String> imageList = new ArrayList<>();
            List<String> imagePages = new ArrayList<>();

            for (int i = 0; i < jArray.length(); i++) {
                JSONObject postObject = jArray.getJSONObject(i);

                String postUrl = postObject.getString("post_url");

                JSONArray imageArray = postObject.getJSONArray("photos");

                for (int imageIndex = 0; imageIndex < imageArray.length(); imageIndex++) {
                    imageList.add(
                            imageArray.getJSONObject(imageIndex).getJSONObject("original_size").getString("url"));
                    imagePages.add(postUrl);
                }

            }

            Log.i(TAG, "imageList size: " + imageList.size());

            startDownload(imageList, imagePages, source);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void downloadTumblrTag(String tag, Source source) {

        try {
            HttpGet httpGet = new HttpGet(
                    "http://api.tumblr.com/v2/tagged?tag=" + tag + "&api_key=" + ApiKeys.TUMBLR_CLIENT_ID);

            String response = getResponse(httpGet);
            if (response == null) {
                return;
            }

            JSONObject jsonObject = new JSONObject(response);
            JSONArray jArray = jsonObject.getJSONArray("response");

            List<String> imageList = new ArrayList<>();
            List<String> imagePages = new ArrayList<>();

            for (int i = 0; i < jArray.length(); i++) {
                try {
                    JSONObject postObject = jArray.getJSONObject(i);

                    String postUrl = postObject.getString("post_url");

                    JSONArray imageArray = postObject.getJSONArray("photos");

                    for (int imageIndex = 0; imageIndex < imageArray.length(); imageIndex++) {
                        imageList.add(imageArray.getJSONObject(imageIndex).getJSONObject("original_size")
                                .getString("url"));
                        imagePages.add(postUrl);
                    }
                } catch (JSONException e) {
                }

            }

            Log.i(TAG, "imageList size: " + imageList.size());

            startDownload(imageList, imagePages, source);
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    private void downloadRedditSubreddit(String sourceData, Source source) {
        if (isInterrupted()) {
            return;
        }

        String apiUrl = "https://reddit.com/r/" + sourceData + "/hot/.json?limit=100";

        Log.i(TAG, "apiUrl: " + apiUrl);

        try {
            HttpGet httpGet = new HttpGet(apiUrl);
            httpGet.setHeader("User-Agent", "AutoBackground/" + BuildConfig.VERSION_NAME + " by TheKeeperOfPie");

            String response = getResponse(httpGet);
            if (response == null) {
                return;
            }

            JSONObject jsonObject = new JSONObject(response);

            Log.i(TAG, "Reddit return JSON: " + jsonObject.toString());

            JSONArray jArray = jsonObject.getJSONObject("data").getJSONArray("children");

            List<String> imageList = new ArrayList<>();
            List<String> imagePages = new ArrayList<>();

            for (int i = 0; i < jArray.length(); i++) {
                JSONObject linkObject = jArray.getJSONObject(i).getJSONObject("data");
                if (i == 0) {
                    Log.i(TAG, "First object: " + linkObject.toString());
                }
                imageList.add(linkObject.getString("url"));
                imagePages.add(linkObject.getString("permalink"));

            }

            Log.i(TAG, "imageList size: " + imageList.size());
            Log.i(TAG, "imageList " + imageList.toString());
            Log.i(TAG, "imagePages " + imagePages.toString());

            startDownload(imageList, imagePages, source);

        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, "JSON parse error");
        }
    }

    private String getResponse(HttpGet httpGet) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        InputStream inputStream = null;
        BufferedReader reader = null;
        String result = null;
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();

            inputStream = entity.getContent();
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
            StringBuilder stringBuilder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            result = stringBuilder.toString();
        } catch (IOException e) {
            return null;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    private Bitmap getImage(String url) {

        if (Patterns.WEB_URL.matcher(url).matches()) {
            try {
                int minWidth = AppSettings.getImageWidth();
                int minHeight = AppSettings.getImageHeight();
                System.gc();
                URL imageUrl = new URL(url);
                HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();
                connection.connect();
                InputStream input = connection.getInputStream();

                if (!connection.getHeaderField("Content-Type").startsWith("image/")
                        && !AppSettings.forceDownload()) {
                    Log.i(TAG, "Not an image: " + url);
                    return null;
                }

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                options.inJustDecodeBounds = true;
                if (!AppSettings.useHighQuality()) {
                    options.inPreferredConfig = Bitmap.Config.RGB_565;
                }

                BitmapFactory.decodeStream(input, null, options);

                input.close();

                int bitWidth = options.outWidth;
                int bitHeight = options.outHeight;
                options.inJustDecodeBounds = false;

                Log.i(TAG, "bitWidth: " + bitWidth + " bitHeight: " + bitHeight);

                if (bitWidth + 10 < minWidth || bitHeight + 10 < minHeight) {
                    return null;
                }

                int sampleSize = 1;

                if (!AppSettings.useFullResolution()) {

                    if (bitHeight > minHeight || bitWidth > minWidth) {

                        final int halfHeight = bitHeight / 2;
                        final int halfWidth = bitWidth / 2;
                        while ((halfHeight / sampleSize) > minHeight && (halfWidth / sampleSize) > minWidth) {
                            sampleSize *= 2;
                        }
                    }
                }

                options.inSampleSize = sampleSize;

                connection = (HttpURLConnection) imageUrl.openConnection();
                connection.setConnectTimeout(5000);
                connection.setConnectTimeout(30000);
                connection.connect();
                input = connection.getInputStream();

                Bitmap bitmap = BitmapFactory.decodeStream(input, null, options);

                if (bitmap == null) {
                    Log.i(TAG, "Null bitmap");
                    return null;
                }
                return bitmap;

            } catch (InterruptedIOException e) {
                this.interrupt();
                Log.i(TAG, "Interrupted");
            } catch (OutOfMemoryError | IOException e) {
                interrupt();
                e.printStackTrace();
            }
        }
        Log.i(TAG, "Possible malformed URL");
        return null;
    }

    private void writeToFile(Bitmap image, String saveData, File file) {

        if (file.isFile()) {
            file.delete();
        }

        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.PNG, 90, out);
            AppSettings.setUrl(file.getName(), saveData);
            Log.i(TAG, file.getName() + " " + saveData);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }

        image.recycle();
    }

    private void writeToFileWithThumbnail(Bitmap image, String saveData, String dir, File file, long time) {

        if (file.isFile()) {
            file.delete();
        }

        FileOutputStream out = null;
        FileOutputStream thumbnailOut = null;
        try {
            int bitWidth = image.getWidth();
            int bitHeight = image.getHeight();

            float thumbnailSize = (float) AppSettings.getThumbnailSize();

            Bitmap thumbnail;

            if (thumbnailSize < bitWidth && thumbnailSize < bitHeight) {
                Matrix matrix = new Matrix();
                if (bitWidth > bitHeight) {
                    matrix.postScale(thumbnailSize / bitWidth, thumbnailSize / bitWidth);
                } else {
                    matrix.postScale(thumbnailSize / bitHeight, thumbnailSize / bitHeight);
                }
                thumbnail = Bitmap.createBitmap(image, 0, 0, bitWidth, bitHeight, matrix, false);
            } else {
                thumbnail = image;
            }

            out = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.PNG, 90, out);

            File thumbnailCache = new File(dir + "/HistoryCache");

            if (!thumbnailCache.exists() || (thumbnailCache.exists() && !thumbnailCache.isDirectory())) {
                thumbnailCache.mkdir();
            }

            File thumbnailFile = new File(thumbnailCache.getAbsolutePath() + "/" + time + ".png");

            thumbnailOut = new FileOutputStream(thumbnailFile);

            thumbnail.compress(Bitmap.CompressFormat.PNG, 90, thumbnailOut);

            Log.i(TAG, "Thumbnail written: " + thumbnailFile.getAbsolutePath());

            AppSettings.setUrl(file.getName(), saveData);
            Log.i(TAG, file.getName() + " " + saveData);
            thumbnail.recycle();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (thumbnailOut != null) {
                    thumbnailOut.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        image.recycle();
    }

    private void sendToast(String message) {
        if (AppSettings.useToast()) {
            Toast.makeText(appContext, message, Toast.LENGTH_SHORT).show();
        }
    }

    private void updateNotification(int value) {

        if (notificationManager != null && notifyProgress != null) {
            if (AppSettings.useDownloadNotification()) {
                notifyProgress.setProgress(progressMax, value, false);

                if (Build.VERSION.SDK_INT >= 16) {
                    notificationManager.notify(NOTIFICATION_ID, notifyProgress.build());
                } else {
                    notificationManager.notify(NOTIFICATION_ID, notifyProgress.getNotification());
                }
            } else {
                notificationManager.cancel(NOTIFICATION_ID);
            }
        }
    }

    private void cancel() {
        if (notificationManager != null) {
            notificationManager.cancel(NOTIFICATION_ID);
        }

        Intent resetDownloadIntent = new Intent(FileHandler.DOWNLOAD_TERMINATED);
        LocalBroadcastManager.getInstance(appContext).sendBroadcast(resetDownloadIntent);

        sendToast("Download cancelled");

        AppSettings.checkUsedLinksSize();
        appContext = null;
        FileHandler.setIsDownloading(false);
    }

    private void finish() {
        if (AppSettings.useDownloadNotification()) {
            Notification.Builder notifyComplete = new Notification.Builder(appContext)
                    .setContentTitle("Download Completed")
                    .setContentText("AutoBackground downloaded " + totalDownloaded + " images")
                    .setSmallIcon(R.drawable.ic_photo_white_24dp);

            Notification notification;

            if (Build.VERSION.SDK_INT >= 16) {
                notifyComplete.setPriority(Notification.PRIORITY_LOW);
                Notification.InboxStyle inboxStyle = new Notification.InboxStyle();
                inboxStyle.setBigContentTitle("Downloaded Image Details:");

                inboxStyle.addLine("Total images enabled: " + FileHandler.getBitmapList().size());

                for (String detail : imageDetails.split(AppSettings.DATA_SPLITTER)) {
                    inboxStyle.addLine(detail);
                }

                notifyComplete.setStyle(inboxStyle);
                notification = notifyComplete.build();
            } else {
                notification = notifyComplete.getNotification();
            }

            notificationManager.cancel(NOTIFICATION_ID);
            notificationManager.notify(NOTIFICATION_ID, notification);
        }

        Intent cycleIntent = new Intent();
        cycleIntent.setAction(LiveWallpaperService.CYCLE_IMAGE);
        cycleIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
        appContext.sendBroadcast(cycleIntent);

        Intent resetDownloadIntent = new Intent(FileHandler.DOWNLOAD_TERMINATED);
        LocalBroadcastManager.getInstance(appContext).sendBroadcast(resetDownloadIntent);

        Intent intent = new Intent();
        intent.setAction(LiveWallpaperService.UPDATE_NOTIFICATION);
        intent.putExtra("use", AppSettings.useNotification());
        appContext.sendBroadcast(intent);

        AppSettings.checkUsedLinksSize();
        appContext = null;

        Log.i(TAG, "Download Finished");
        FileHandler.setIsDownloading(false);
    }
}