Android 使用改装库处理带有通知的多个下载
我跟在后面 我的应用程序的UI有几个不同的按钮,它们使用上述方法下载不同的文件。问题是,当某人在按下第一个按钮后按下另一个按钮时,它将排队,并在第一个按钮完成后启动。我希望它立即同时启动 以下是下载服务的代码:Android 使用改装库处理带有通知的多个下载,android,service,download,Android,Service,Download,我跟在后面 我的应用程序的UI有几个不同的按钮,它们使用上述方法下载不同的文件。问题是,当某人在按下第一个按钮后按下另一个按钮时,它将排队,并在第一个按钮完成后启动。我希望它立即同时启动 以下是下载服务的代码: public class DownloadService extends IntentService { public DownloadService() { super("Download Service"); } private int t
public class DownloadService extends IntentService {
public DownloadService() {
super("Download Service");
}
private int totalFileSize;
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
@Override
protected void onHandleIntent(Intent intent) {
MyApp x = (MyApp)getApplicationContext();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
.setContentTitle("Downloading")
.setContentText("Please wait...")
.setAutoCancel(true);
notificationManager.notify(x.ID, notificationBuilder.build());
Log.i("Paras", "onHandleIntent: " + x.filename + x.url);
initDownload(x.filename,x.url,x.ID);
}
private void initDownload(String filename, String url, int id) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://dl.dropboxusercontent.com/")
.build();
RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);
Call<ResponseBody> request = retrofitInterface.downloadFile(url);
try {
downloadFile(request.execute().body(),filename,id);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void downloadFile(ResponseBody body, String filename,int id) throws IOException {
int count;
byte data[] = new byte[1024 * 4];
long fileSize = body.contentLength();
InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
OutputStream output = new FileOutputStream(outputFile);
long total = 0;
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = bis.read(data)) != -1) {
total += count;
totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
double current = Math.round(total / (Math.pow(1, 2))) / 1000;
int progress = (int) ((total * 100) / fileSize);
long currentTime = System.currentTimeMillis() - startTime;
Download download = new Download();
download.setTotalFileSize(totalFileSize);
if (currentTime > 1000 * timeCount) {
download.setCurrentFileSize((int) current);
download.setProgress(progress);
sendNotification(download,id);
timeCount++;
}
output.write(data, 0, count);
}
onDownloadComplete(filename,id);
output.flush();
output.close();
bis.close();
}
private void sendNotification(Download download, int id) {
sendIntent(download);
notificationBuilder.setProgress(100, download.getProgress(), false);
notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
notificationManager.notify(id, notificationBuilder.build());
}
private void sendIntent(Download download) {
Intent intent = new Intent(subject.MESSAGE_PROGRESS);
intent.putExtra("download", download);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
private void onDownloadComplete(String filename,int id) {
try {
Download download = new Download();
download.setProgress(100);
sendIntent(download);
notificationManager.cancel(id);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText("Tap to open");
notificationManager.notify(id, notificationBuilder.build());
String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;
File file = new File(path1);
Uri uri_path = Uri.fromFile(file);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
(MimeTypeMap.getFileExtensionFromUrl(path1));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setType(mimeType);
intent.setDataAndType(uri_path, mimeType);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
String string = filename;
notificationBuilder
.setContentIntent(pIntent)
.setAutoCancel(true)
.setContentTitle(string + " Downloaded");
Log.i("Paras", "onDownloadComplete: " + string);
notificationManager.notify(id, notificationBuilder.build());
} catch (Exception ex) {
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
}
}
但它不起作用。有什么线索告诉我该怎么做吗?如果需要,我准备提供更多细节
编辑1:DownloadService在“startDownload”功能上运行,该功能由各种按钮执行。正如您在第二段代码中看到的,类扩展了服务。有一个线程处理所有这些按钮点击。若你们查看评论,建议我应该使用服务和不同的线程来完成所有这些点击。现在,我如何以编程方式生成这么多线程。几乎有40个按钮使用下载服务。多亏了@Lxu,我才让它工作起来。因此,
IntentService
意味着一次只能执行一项任务,不能同时执行多个任务。我们应该使用服务
。它允许同时执行多个任务。我们可以在服务
中创建多个线程,这些线程将同时执行。通过将onCreate()
的所有代码放到onStartCommand()
中,我的问题得到了解决。第一次调用服务时,将调用onCreate()
,之后,无论调用多少次服务,都不再调用该服务。在每次服务调用时,都会执行onStartCommand()
,每次都会创建新线程。就这样
以下是完整的代码:
public class DownloadService extends Service {
public DownloadService() {
super();
}
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
int id1;
int id2;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
MyApp x = (MyApp)getApplicationContext();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
.setContentTitle("Downloading")
.setContentText("Please wait...")
.setAutoCancel(true);
notificationManager.notify(x.ID, notificationBuilder.build());
Log.i("Paras", "onHandleIntent: " + x.filename + x.url + " " + x.ID);
initDownload(x.filename,x.url,x.ID);
}
}
@Override
public void onCreate() {
// Get the HandlerThread's Looper and use it for our Handler
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
MyApp x = (MyApp)getApplicationContext();
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private int totalFileSize;
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
private void initDownload(String filename, String url, int id) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://dl.dropboxusercontent.com/")
.build();
RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);
Call<ResponseBody> request = retrofitInterface.downloadFile(url);
try {
downloadFile(request.execute().body(),filename,id);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void downloadFile(ResponseBody body, String filename,int id) throws IOException {
int count;
byte data[] = new byte[1024 * 4];
long fileSize = body.contentLength();
InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
OutputStream output = new FileOutputStream(outputFile);
long total = 0;
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = bis.read(data)) != -1) {
total += count;
totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
double current = Math.round(total / (Math.pow(1, 2))) / 1000;
int progress = (int) ((total * 100) / fileSize);
long currentTime = System.currentTimeMillis() - startTime;
Download download = new Download();
download.setTotalFileSize(totalFileSize);
if (currentTime > 1000 * timeCount) {
download.setCurrentFileSize((int) current);
download.setProgress(progress);
sendNotification(download,id);
timeCount++;
}
output.write(data, 0, count);
}
onDownloadComplete(filename,id);
output.flush();
output.close();
bis.close();
}
private void sendNotification(Download download, int id) {
sendIntent(download,id);
notificationBuilder.setProgress(100, download.getProgress(), false)
.setContentTitle("Downloading");
notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
notificationManager.notify(id, notificationBuilder.build());
}
private void sendIntent(Download download, int id) {
Intent intent = new Intent(subject.MESSAGE_PROGRESS);
intent.putExtra("download", download);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
private void onDownloadComplete(String filename,int id) {
try {
Download download = new Download();
download.setProgress(100);
sendIntent(download,id);
notificationManager.cancel(id);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText("Tap to open");
notificationManager.notify(id, notificationBuilder.build());
String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;
File file = new File(path1);
Uri uri_path = Uri.fromFile(file);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
(MimeTypeMap.getFileExtensionFromUrl(path1));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setType(mimeType);
intent.setDataAndType(uri_path, mimeType);
PendingIntent pIntent = PendingIntent.getActivity(this,(int) System.currentTimeMillis(), intent, 0);
String string = filename;
notificationBuilder
.setContentIntent(pIntent)
.setAutoCancel(true)
.setContentTitle(string + " Downloaded");
Log.i("Paras", "onDownloadComplete: " + string);
notificationManager.notify(id, notificationBuilder.build());
}catch (Exception ex){
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
}
}
公共类下载服务扩展服务{
公共下载服务(){
超级();
}
专用活套;
私有服务处理程序mServiceHandler;
INTID1;
INTID2;
私有最终类ServiceHandler扩展处理程序{
公共服务处理程序(活套-活套){
超级(活套);
}
@凌驾
公共无效handleMessage(消息消息消息){
MyApp x=(MyApp)getApplicationContext();
notificationManager=(notificationManager)getSystemService(Context.NOTIFICATION\u服务);
notificationBuilder=新建NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_文件_下载_deep_orange_a400_18dp)
.setContentTitle(“下载”)
.setContentText(“请稍候…”)
.setAutoCancel(真);
notificationManager.notify(x.ID,notificationBuilder.build());
Log.i(“段落”,“OnHandleContent:”+x.filename+x.url+”+x.ID);
initDownload(x.filename,x.url,x.ID);
}
}
@凌驾
public void onCreate(){
//获取HandlerThread的活套并将其用于我们的处理程序
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
//对于每个启动请求,发送消息以启动作业并交付
//启动ID,以便在完成作业时知道要停止的请求
HandlerThread线程=新的HandlerThread(“ServiceStartArguments”,Process.thread\u PRIORITY\u BACKGROUND);
thread.start();
mServiceLooper=thread.getLooper();
MSServiceHandler=新的ServiceHandler(MSServiceLooper);
MyApp x=(MyApp)getApplicationContext();
Message msg=mServiceHandler.obtainMessage();
msg.arg1=startId;
mServiceHandler.sendMessage(msg);
//如果我们被杀了,从这里回来后,重新开始
返回开始时间;
}
@可空
@凌驾
公共IBinder onBind(意向){
返回null;
}
私有整数文件大小;
私人通知建筑商通知建筑商;
私人通知经理通知经理;
私有void initDownload(字符串文件名、字符串url、int id){
改装改装=新改装.Builder()
.baseUrl(“https://dl.dropboxusercontent.com/")
.build();
RequestInterface.RefundationInterface=Refundation.create(RequestInterface.RefundationInterface.class);
调用请求=interface.downloadFile(url);
试一试{
下载文件(request.execute().body(),文件名,id);
}捕获(IOE异常){
e、 printStackTrace();
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
私有void下载文件(ResponseBody主体、字符串文件名、int-id)引发IOException{
整数计数;
字节数据[]=新字节[1024*4];
long fileSize=body.contentLength();
InputStream bis=新的BufferedInputStream(body.ByTestStream(),1024*8);
File outputFile=新文件(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY\u下载),文件名);
OutputStream output=新文件OutputStream(outputFile);
长总计=0;
long startTime=System.currentTimeMillis();
int timeCount=1;
而((计数=二读(数据))!=-1){
总数+=计数;
totalFileSize=(int)(fileSize/(Math.pow(1,2))/1000;
双电流=数学圆整(总/(数学功率(1,2))/1000;
int进度=(int)((总计*100)/文件大小);
长currentTime=System.currentTimeMillis()-startTime;
下载=新下载();
下载.setTotalFileSize(totalFileSize);
如果(当前时间>1000*时间计数){
下载.setCurrentFileSize((int)current);
下载.setProgress(progress);
发送通知(下载,id);
timeCount++;
}
输出.写入(数据,0,计数);
}
昂敦
public class DownloadService extends Service {
public DownloadService() {
super();
}
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
int id1;
int id2;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
MyApp x = (MyApp)getApplicationContext();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
.setContentTitle("Downloading")
.setContentText("Please wait...")
.setAutoCancel(true);
notificationManager.notify(x.ID, notificationBuilder.build());
Log.i("Paras", "onHandleIntent: " + x.filename + x.url + " " + x.ID);
initDownload(x.filename,x.url,x.ID);
}
}
@Override
public void onCreate() {
// Get the HandlerThread's Looper and use it for our Handler
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
MyApp x = (MyApp)getApplicationContext();
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private int totalFileSize;
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
private void initDownload(String filename, String url, int id) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://dl.dropboxusercontent.com/")
.build();
RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);
Call<ResponseBody> request = retrofitInterface.downloadFile(url);
try {
downloadFile(request.execute().body(),filename,id);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void downloadFile(ResponseBody body, String filename,int id) throws IOException {
int count;
byte data[] = new byte[1024 * 4];
long fileSize = body.contentLength();
InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
OutputStream output = new FileOutputStream(outputFile);
long total = 0;
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = bis.read(data)) != -1) {
total += count;
totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
double current = Math.round(total / (Math.pow(1, 2))) / 1000;
int progress = (int) ((total * 100) / fileSize);
long currentTime = System.currentTimeMillis() - startTime;
Download download = new Download();
download.setTotalFileSize(totalFileSize);
if (currentTime > 1000 * timeCount) {
download.setCurrentFileSize((int) current);
download.setProgress(progress);
sendNotification(download,id);
timeCount++;
}
output.write(data, 0, count);
}
onDownloadComplete(filename,id);
output.flush();
output.close();
bis.close();
}
private void sendNotification(Download download, int id) {
sendIntent(download,id);
notificationBuilder.setProgress(100, download.getProgress(), false)
.setContentTitle("Downloading");
notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
notificationManager.notify(id, notificationBuilder.build());
}
private void sendIntent(Download download, int id) {
Intent intent = new Intent(subject.MESSAGE_PROGRESS);
intent.putExtra("download", download);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
private void onDownloadComplete(String filename,int id) {
try {
Download download = new Download();
download.setProgress(100);
sendIntent(download,id);
notificationManager.cancel(id);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText("Tap to open");
notificationManager.notify(id, notificationBuilder.build());
String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;
File file = new File(path1);
Uri uri_path = Uri.fromFile(file);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
(MimeTypeMap.getFileExtensionFromUrl(path1));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setType(mimeType);
intent.setDataAndType(uri_path, mimeType);
PendingIntent pIntent = PendingIntent.getActivity(this,(int) System.currentTimeMillis(), intent, 0);
String string = filename;
notificationBuilder
.setContentIntent(pIntent)
.setAutoCancel(true)
.setContentTitle(string + " Downloaded");
Log.i("Paras", "onDownloadComplete: " + string);
notificationManager.notify(id, notificationBuilder.build());
}catch (Exception ex){
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
}
}