package de.luhmer.owncloudnewsreader.services; import android.app.DownloadManager; import android.app.IntentService; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.support.v4.app.NotificationCompat; import android.widget.Toast; import org.greenrobot.eventbus.EventBus; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.net.URL; import java.net.URLConnection; import java.security.MessageDigest; import de.luhmer.owncloudnewsreader.NewsReaderListActivity; import de.luhmer.owncloudnewsreader.R; import de.luhmer.owncloudnewsreader.helper.FileUtils; import de.luhmer.owncloudnewsreader.model.PodcastItem; /** * An {@link IntentService} subclass for handling asynchronous task requests in * a service on a separate handler thread. * <p> * helper methods. */ public class PodcastDownloadService extends IntentService { @SuppressWarnings("unused") private static final String TAG = PodcastDownloadService.class.getCanonicalName(); // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS private static final String ACTION_DOWNLOAD = "de.luhmer.owncloudnewsreader.services.action.DOWNLOAD"; private static final String EXTRA_RECEIVER = "de.luhmer.owncloudnewsreader.services.extra.RECEIVER"; private static final String EXTRA_URL = "de.luhmer.owncloudnewsreader.services.extra.URL"; private EventBus eventBus; /** * Starts this service to download a podcast. If * the service is already performing a task this action will be queued. * * @see IntentService */ public static void startPodcastDownload(Context context, PodcastItem podcastItem/*, ResultReceiver receiver*/) { Intent intent = new Intent(context, PodcastDownloadService.class); intent.setAction(ACTION_DOWNLOAD); intent.putExtra(EXTRA_URL, podcastItem); //intent.putExtra(EXTRA_RECEIVER, receiver); context.startService(intent); } public PodcastDownloadService() { super("PodcastDownloadService"); eventBus = EventBus.getDefault(); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_DOWNLOAD.equals(action)) { //ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER); PodcastItem podcast = (PodcastItem) intent.getSerializableExtra(EXTRA_URL); downloadPodcast(podcast, this); } } } /** * Handle action Foo in the provided background thread with the provided * parameters. */ private void handleActionDownload(PodcastItem podcast) { Uri uri = Uri.parse(podcast.link); DownloadManager.Request request = new DownloadManager.Request(uri); request.setDescription(podcast.mimeType); request.setTitle(podcast.title); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); String path = "file://" + getUrlToPodcastFile(this, podcast.link, true); request.setDestinationUri(Uri.parse(path)); //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "bla.txt"); // get download service and enqueue file DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); } public static String getUrlToPodcastFile(Context context, String WEB_URL_TO_FILE, boolean createDir) { File file = new File(WEB_URL_TO_FILE); String path = FileUtils.getPathPodcasts(context) + "/" + getHashOfString(WEB_URL_TO_FILE) + "/"; if(createDir) new File(path).mkdirs(); return path + file.getName(); } public static String getHashOfString(String WEB_URL_TO_FILE) { try { MessageDigest m = MessageDigest.getInstance("MD5"); m.reset(); m.update(WEB_URL_TO_FILE.trim().getBytes()); byte[] digest = m.digest(); BigInteger bigInt = new BigInteger(1,digest); return bigInt.toString(16); } catch (Exception e) { e.printStackTrace(); } return WEB_URL_TO_FILE; } private void downloadPodcast(PodcastItem podcast, Context context) { Intent intentNewsReader = new Intent(this, NewsReaderListActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intentNewsReader, 0); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder mNotificationDownloadPodcast = new NotificationCompat.Builder(this) .setContentTitle(getResources().getString(R.string.app_name)) .setContentText("Downloading podcast") .setSmallIcon(R.drawable.ic_notification) .setContentIntent(pIntent) .setOngoing(true); Notification notify = mNotificationDownloadPodcast.build(); //Hide the notification after its selected notify.flags |= Notification.FLAG_AUTO_CANCEL; notify.flags |= Notification.FLAG_NO_CLEAR; int NOTIFICATION_ID = 543226; notificationManager.notify(NOTIFICATION_ID, notify); try { String urlTemp = podcast.link; String path = getUrlToPodcastFile(this, urlTemp, true); URL url = new URL(urlTemp); URLConnection connection = url.openConnection(); connection.connect(); connection.setConnectTimeout(10000); connection.setReadTimeout(120000);//2min // this will be useful so that you can show a typical 0-100% progress bar int fileLength = connection.getContentLength(); // download the file InputStream input = new BufferedInputStream(url.openStream()); String pathCache = path + ".download"; OutputStream output = new FileOutputStream(pathCache); byte data[] = new byte[1024]; long total = 0; int count; int lastProgress = -1; while ((count = input.read(data)) != -1) { total += count; podcast.downloadProgress = (int) (total * 100 / fileLength); //Only update the ui/notification if the progress changed (e.g. from 1% to 2%) if(lastProgress != podcast.downloadProgress) { lastProgress = podcast.downloadProgress; eventBus.post(new DownloadProgressUpdate(podcast)); mNotificationDownloadPodcast.setProgress(100, podcast.downloadProgress, false); notificationManager.notify(NOTIFICATION_ID, mNotificationDownloadPodcast.build()); } output.write(data, 0, count); } output.flush(); output.close(); input.close(); new File(pathCache).renameTo(new File(path)); } catch (IOException e) { e.printStackTrace(); Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } podcast.downloadProgress = 100; eventBus.post(new DownloadProgressUpdate(podcast)); notificationManager.cancel(NOTIFICATION_ID); /* Bundle resultData = new Bundle(); resultData.putInt("progress" ,100); receiver.send(UPDATE_PROGRESS, resultData); */ } //public static final int UPDATE_PROGRESS = 5555; public class DownloadProgressUpdate { public DownloadProgressUpdate(PodcastItem podcast) { this.podcast = podcast; } public PodcastItem podcast; } public static boolean PodcastAlreadyCached(Context context, String podcastUrl) { File file = new File(PodcastDownloadService.getUrlToPodcastFile(context, podcastUrl, false)); return file.exists(); } }