@Override
        public void onReceive(Context context, Intent intent) {
          if (intent.getAction().equals(ACTION_CANCEL_DOWNLOAD)) {
            String url = intent.getStringExtra(EXTRA_DOWNLOAD_URL);
            if (url == null) {
              throw new IllegalArgumentException(
                  "ACTION_CANCEL_DOWNLOAD intent needs download url extra");
            }
            if (BuildConfig.DEBUG) Log.d(TAG, "Cancelling download with url " + url);
            Downloader d = getDownloader(url);
            if (d != null) {
              d.cancel();
            } else {
              Log.e(TAG, "Could not cancel download with url " + url);
            }

          } else if (intent.getAction().equals(ACTION_CANCEL_ALL_DOWNLOADS)) {
            for (Downloader d : downloads) {
              d.cancel();
              if (BuildConfig.DEBUG) Log.d(TAG, "Cancelled all downloads");
            }
            sendBroadcast(new Intent(ACTION_DOWNLOADS_CONTENT_CHANGED));
          }
          queryDownloads();
        }
 private Downloader getDownloader(String downloadUrl) {
   for (Downloader downloader : downloads) {
     if (downloader.getDownloadRequest().getSource().equals(downloadUrl)) {
       return downloader;
     }
   }
   return null;
 }
  /**
   * Updates the contents of the service's notifications. Should be called before
   * setupNotificationBuilders.
   */
  @SuppressLint("NewApi")
  private Notification updateNotifications() {
    String contentTitle = getString(R.string.download_notification_title);
    int numDownloads = requester.getNumberOfDownloads();
    String downloadsLeft;
    if (numDownloads > 0) {
      downloadsLeft = requester.getNumberOfDownloads() + getString(R.string.downloads_left);
    } else {
      downloadsLeft = getString(R.string.downloads_processing);
    }
    if (android.os.Build.VERSION.SDK_INT >= 16) {

      if (notificationBuilder != null) {

        StringBuilder bigText = new StringBuilder("");
        for (int i = 0; i < downloads.size(); i++) {
          Downloader downloader = downloads.get(i);
          final DownloadRequest request = downloader.getDownloadRequest();
          if (request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
            if (request.getTitle() != null) {
              if (i > 0) {
                bigText.append("\n");
              }
              bigText.append("\u2022 " + request.getTitle());
            }
          } else if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
            if (request.getTitle() != null) {
              if (i > 0) {
                bigText.append("\n");
              }
              bigText.append(
                  "\u2022 " + request.getTitle() + " (" + request.getProgressPercent() + "%)");
            }
          }
        }
        notificationBuilder.setSummaryText(downloadsLeft);
        notificationBuilder.setBigContentTitle(contentTitle);
        if (bigText != null) {
          notificationBuilder.bigText(bigText.toString());
        }
        return notificationBuilder.build();
      }
    } else {
      if (notificationCompatBuilder != null) {
        notificationCompatBuilder.setContentTitle(contentTitle);
        notificationCompatBuilder.setContentText(downloadsLeft);
        return notificationCompatBuilder.build();
      }
    }
    return null;
  }
        @Override
        public void run() {
          if (BuildConfig.DEBUG) Log.d(TAG, "downloadCompletionThread was started");
          while (!isInterrupted()) {
            try {
              Downloader downloader = downloadExecutor.take().get();
              if (BuildConfig.DEBUG) Log.d(TAG, "Received 'Download Complete' - message.");
              removeDownload(downloader);
              DownloadStatus status = downloader.getResult();
              boolean successful = status.isSuccessful();

              final int type = status.getFeedfileType();
              if (successful) {
                if (type == Feed.FEEDFILETYPE_FEED) {
                  handleCompletedFeedDownload(downloader.getDownloadRequest());
                } else if (type == FeedImage.FEEDFILETYPE_FEEDIMAGE) {
                  handleCompletedImageDownload(status, downloader.getDownloadRequest());
                } else if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
                  handleCompletedFeedMediaDownload(status, downloader.getDownloadRequest());
                }
              } else {
                numberOfDownloads.decrementAndGet();
                if (!status.isCancelled()) {
                  if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) {
                    postAuthenticationNotification(downloader.getDownloadRequest());
                  } else if (status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
                      && Integer.valueOf(status.getReasonDetailed())
                          == HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE) {

                    Log.d(TAG, "Requested invalid range, restarting download from the beginning");
                    FileUtils.deleteQuietly(
                        new File(downloader.getDownloadRequest().getDestination()));
                    DownloadRequester.getInstance()
                        .download(DownloadService.this, downloader.getDownloadRequest());
                  } else {
                    Log.e(TAG, "Download failed");
                    saveDownloadStatus(status);
                    handleFailedDownload(status, downloader.getDownloadRequest());
                  }
                }
                sendDownloadHandledIntent();
                queryDownloadsAsync();
              }
            } catch (InterruptedException e) {
              if (BuildConfig.DEBUG) Log.d(TAG, "DownloadCompletionThread was interrupted");
            } catch (ExecutionException e) {
              e.printStackTrace();
              numberOfDownloads.decrementAndGet();
            }
          }
          if (BuildConfig.DEBUG) Log.d(TAG, "End of downloadCompletionThread");
        }