Background
我希望使用DownloadManager将多个文件下载到设备,并且还能够显示活动的进度,并提供比通知上显示的更多详细信息。
我知道之前有人问过这个问题(在这里发布),但他们使用带有后台线程的轮询,而且我不确定我能从中获得什么样的数据。
问题
是否可以在不轮询的情况下显示进度详细信息? 也许通过监听器/广播接收器?
这是不可能的。下载管理器只有 3 个广播:
ACTION_DOWNLOAD_COMPLETE(完成)ACTION_NOTIFICATION_CLICKED(点击其通知)ACTION_VIEW_DOWNLOADS(查看文件下载)
因此,我认为民意调查对于监控进度是必要的。
我的下载服务:
package com.codebrew.govideodownloader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class DownloadService extends IntentService {
String urlD, name, sole;
Context conte;
static int q = -1, counter = -1;
int progress = 0, nin;
double tmp = 0;
int oldP = 0;
File file;
public static final String NOTIFICATION = "com.codebrewlabs.vidbox.ShowDownloadsActivity";
SharedPreferences pre;
NotificationManager notificationManager;
NotificationCompat.Builder mBuilder;
public DownloadService(String name) {
super("Downloading");
}
public DownloadService() {
super("Downloading");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
q = q + 1;
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
conte = this;
}
@Override
protected void onHandleIntent(Intent intent) {
try {
notificationManager = (NotificationManager) conte
.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(conte)
.setSmallIcon(R.drawable.vidbox_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
pre = getSharedPreferences("VidBoxPref", 0);
urlD = intent.getExtras().getString("url");
name = intent.getExtras().getString("name");
nin = intent.getExtras().getInt("nin");
progress = 0;
sole = name;
} catch (Exception e) {
e.printStackTrace();
}
try {
double size = 0;
final int TIMEOUT_CONNECTION = 30000;// 30sec
final int TIMEOUT_SOCKET = 30000;// 30sec
String imageURL = urlD;
URL url = new URL(imageURL);
long startTime = System.currentTimeMillis();
Log.e("Note: ", "image download beginning: " + imageURL);
// Open a connection to that URL.
URLConnection ucon = url.openConnection();
// this timeout affects how long it takes for the app to realize
// there's a connection problem
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);
// Define InputStreams to read from the URLConnection.
// uses 3KB download buffer
InputStream is = ucon.getInputStream();
size = ucon.getContentLength();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory()
+ "/Video/GoVideoDownloader");
wallpaperDirectory.mkdirs();
// sole = sole.replace("?", "_");
// sole = sole.replace("|", "_");
// sole = sole.replace("/", "_");
// sole = sole.replace(":", "_");
// sole = sole.replace("$", "_");
file = new File(wallpaperDirectory + File.separator + sole);
if (file.exists()) {
file.delete();
}
file.createNewFile();
pre.edit().putBoolean("inDownload", true).commit();
publishP();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
// Read bytes (and store them) until there is nothing more to
// read(-1)
int len;
tmp = 0;
while ((len = inStream.read(buff)) != -1) {
if (pre.getBoolean("cont", false)) {
pre.edit().putBoolean("cont", false).commit();
pre.edit().putBoolean("inDownload", false).commit();
q--;
pre.edit().putInt("progress", progress).commit();
sendNotification(7, nin, sole);
Intent in2 = new Intent(NOTIFICATION);
in2.putExtra("progress", progress);
in2.putExtra("running", 0);
in2.putExtra("name", sole);
in2.putExtra("resume", "0");
sendBroadcast(in2);
progress = 0;
outStream.close();
stopSelf();
return;
}
tmp = tmp + len;
progress = (int) (((double) tmp / size) * 100);
pre.edit().putInt("progress", progress).commit();
if (progress < 0)
progress = -1 * progress;
outStream.write(buff, 0, len);
if (progress != oldP)
publishP();
oldP = progress;
}
tmp = size;
progress = 100;
q = q + 1;
publishP();
// clean up
outStream.flush();
outStream.close();
inStream.close();
Log.e("Note: ",
"Download completed in "
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " secs.");
} catch (Exception e) {
if (file != null) {
if (file.exists()) {
file.delete();
}
}
pre.edit().putBoolean("inDownload", false).commit();
int innn;
if (e.toString()
.equals("java.io.IOException: open failed: EACCES (Permission denied)")) {
innn = 5;
} else {
innn = 1;
}
if (!e.toString().equals(
"java.io.IOException: close failed: EIO (I/O error)")) {
sendNotification(innn, nin, sole);
}
Intent in2 = new Intent(NOTIFICATION);
in2.putExtra("progress", progress);
in2.putExtra("running", 0);
in2.putExtra("name", sole);
q--;
in2.putExtra("resume", "0");
sendBroadcast(in2);
progress = 0;
Log.e("Error: ", "Error is:" + e.toString());
}
}
protected void publishP() {
try {
pre.edit().putInt("progress", progress).commit();
sendNotification(0, nin, sole);
Intent in2 = new Intent(NOTIFICATION);
if (progress == 100) {
q--;
pre.edit().putBoolean("inDownload", false).commit();
}
in2.putExtra("progress", progress);
in2.putExtra("resume", "0");
in2.putExtra("running", 1);
in2.putExtra("name", sole);
in2.putExtra("queue", q);
pre.edit().putInt("progress", progress).commit();
pre.edit().putInt("running", 1).commit();
pre.edit().putString("currName", sole).commit();
pre.edit().putInt("nowQueue", q).commit();
sendBroadcast(in2);
} catch (Exception e) {
Log.e("Shit", e.toString());
}
}
@Override
public boolean stopService(Intent name) {
return super.stopService(name);
}
public void sendNotification(int tmout, int nin, String name) {
if (tmout == 0) {
// notificationManager.notify(nin, mBuilder.build());
if (progress >= 100) {
// notificationManager.cancel(nin);
mBuilder.setSmallIcon(R.drawable.vidbox_icon)
.setContentTitle("Completed").setContentText(name)
.setAutoCancel(true).setOngoing(false);
Uri ttt = Uri.parse(Environment.getExternalStorageDirectory()
+ File.separator + "Video/GoVideoDownloader/" + name);
Uri uri = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(uri);
pre.edit().putInt("retry", 1).commit();
Intent inten = new Intent(Intent.ACTION_VIEW, ttt);
String arr[] = name.split("\.");
inten.setDataAndType(ttt, "video/" + arr[arr.length - 1]);
PendingIntent i = PendingIntent.getActivity(conte, 0, inten, 0);
mBuilder.setContentIntent(i);
notificationManager.notify(nin, mBuilder.build());
} else {
mBuilder.setContentTitle("Downloading: " + name)
.setContentText(progress + " %")
.setSmallIcon(R.drawable.vidbox_icon)
.setAutoCancel(false).setOngoing(true);
mBuilder.setProgress(100, progress, false);
notificationManager.notify(nin, mBuilder.build());
}
} else {
if (tmout == 1) {
mBuilder.setSmallIcon(R.drawable.vidbox_icon)
.setContentTitle("Failed").setContentText(name)
.setContentText(progress + " %").setAutoCancel(true)
.setProgress(100, progress, false).setOngoing(false);
Uri uri = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(uri);
Intent intnt = new Intent(NOTIFICATION);
intnt.putExtra("resume", "1");
intnt.putExtra("url", urlD);
intnt.putExtra("name", name);
intnt.putExtra("nin", nin);
// PendingIntent i = PendingIntent
// .getBroadcast(conte, 0, intnt, 0);
// mBuilder.setContentIntent(i);
} else if (tmout == 7) {
mBuilder.setSmallIcon(R.drawable.vidbox_icon)
.setContentTitle("Cancelled").setContentText(name)
.setAutoCancel(true).setProgress(100, progress, false)
.setOngoing(false);
Intent intnt = new Intent(NOTIFICATION);
intnt.putExtra("resume", "1");
intnt.putExtra("url", urlD);
intnt.putExtra("name", name);
intnt.putExtra("nin", nin);
// PendingIntent i = PendingIntent
// .getBroadcast(conte, 0, intnt, 0);
// mBuilder.setContentIntent(i);
Uri uri = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(uri);
} else {
mBuilder.setSmallIcon(R.drawable.vidbox_icon)
.setContentTitle("Interrupted").setContentText(name)
.setContentText("No storage found").setAutoCancel(true)
.setOngoing(false);
Uri uri = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(uri);
}
notificationManager.notify(nin, mBuilder.build());
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
try {
notificationManager.cancel(nin);
pre.edit().putBoolean("inDownload", false).commit();
} catch (Exception e) {
}
}
}
我正在使用循环下载文件的字节数,并为下载的每个字节发送广播和通知(或每当进度增加时)。希望有帮助:3