参考第一行代码,代码:github
写的很乱,下载完毕后的通知也没有实现。由于没有写回调处理downloaDWithResult的返回值,所以返回值用不上。
之前用asyncTask也写了一份,碰到notify通知频繁导致app很卡的问题,试着用handler来解决。
最后发现是数值设置有误,导致notification每秒刷新上百次(理论上)。
通过百度学习了以下东西:
package com.slq.r1.activity;import androID.Manifest;import androID.app.Notification;import androID.app.NotificationChannel;import androID.app.notificationmanager;import androID.app.PendingIntent;import androID.content.Componentname;import androID.content.Context;import androID.content.Intent;import androID.content.ServiceConnection;import androID.content.pm.PackageManager;import androID.os.Bundle;import androID.os.Handler;import androID.os.IBinder;import androID.os.Message;import androID.os.Messenger;import androID.os.remoteexception;import androID.util.Log;import androID.vIEw.VIEw;import androID.Widget.button;import androID.Widget.TextVIEw;import androIDx.annotation.NonNull;import androIDx.appcompat.app.AppCompatActivity;import androIDx.core.app.NotificationCompat;import com.slq.r1.R;import com.slq.r1.service.DownloaderService2;public class DownloaderActivityWithHandler extends AppCompatActivity implements VIEw.OnClickListener { final int DownloaderServiceNotificationID = 1; private final String TAG = "DownloaderActivityWithH"; public notificationmanager manager; NotificationCompat.Builder mBuilder; String channelID = "ID1"; String DOWNLOADfileURL = "https://dl.Google.com/androID/studio/plugins/androID-gradle/prevIEw/offline-android-gradle-plugin-prevIEw.zip"; button binddownloadservice, unbinddownloadservice, startdownload, stopdownload, pausedownload; TextVIEw downloadprogresstext, downloadurltext; String[] rights = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; int RIGHTREWUESTCODE = 1; Messenger serviceMessenger; Bundle bundle; private ServiceConnection connection = new ServiceConnection() { @OverrIDe public voID onServiceConnected(Componentname name, IBinder service) { serviceMessenger = new Messenger(service); Messenger messenger = new Messenger(handler); // 创建消息 Message msg = new Message(); msg.what = -1; msg.replyTo = messenger; // 使用service中的messenger发送Activity中的messenger try { serviceMessenger.send(msg); } catch (remoteexception e) { e.printstacktrace(); } } @OverrIDe public voID onServicedisconnected(Componentname name) { } }; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_downloader_with_handler); init(); } @OverrIDe protected voID onDestroy() { super.onDestroy(); Intent it = new Intent(DownloaderActivityWithHandler.this, DownloaderService2.class); stopService(it); try { unbindService(connection); } catch (IllegalArgumentException e) { e.printstacktrace(); } } private voID init() { binddownloadservice = findVIEwByID(R.ID.binddownloadservice2); binddownloadservice.setonClickListener(this); unbinddownloadservice = findVIEwByID(R.ID.unbinddownloadservice2); unbinddownloadservice.setonClickListener(this); startdownload = findVIEwByID(R.ID.startdownload2); startdownload.setonClickListener(this); stopdownload = findVIEwByID(R.ID.stopdownload2); stopdownload.setonClickListener(this); pausedownload = findVIEwByID(R.ID.pausedownload2); pausedownload.setonClickListener(this); downloadprogresstext = findVIEwByID(R.ID.downloadprogresstext2); downloadurltext = findVIEwByID(R.ID.downloadurltext2); downloadurltext.setText(DOWNLOADfileURL); manager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE); getNotificationPart1(); bundle = new Bundle(); bundle.putString("url", downloadurltext.getText().toString()); } private voID getNotificationPart1() { Intent it = new Intent(this, DownloaderActivityWithHandler.class); PendingIntent pi = PendingIntent.getActivity(this, 0, it, 0); NotificationChannel chan1 = new NotificationChannel(channelID, "name1", notificationmanager.importANCE_MAX); manager.createNotificationChannel(chan1); mBuilder = new NotificationCompat.Builder(getApplicationContext(), channelID); mBuilder.setSmallicon(R.mipmap.ic_launcher) .setContentIntent(pi) .setNotificationSilent(); } private Notification getNotificationPart2(String Title, int... params) { mBuilder.setContentTitle(Title) //设置标题 .setContentText("已下载" + params[0] + "/" + params[1]) .setProgress(params[1], params[0], false); return mBuilder.build(); } public Handler handler = new Handler() { @OverrIDe public voID handleMessage(@NonNull Message msg) { switch (msg.what) { case 1: Bundle data = msg.getData(); int[] progresses = data.getIntArray("progress"); manager.notify(DownloaderServiceNotificationID, getNotificationPart2("下载进度", progresses[0], progresses[1])); break; case 2: //stop manager.cancel(DownloaderServiceNotificationID); break; case 3: manager.cancel(DownloaderServiceNotificationID); break; default: break; } } }; @OverrIDe public voID onClick(VIEw v) { Message msg = new Message(); switch (v.getID()) { case R.ID.startdownload2: msg.what = 0; msg.setData(bundle); sendMsg(msg); break; case R.ID.stopdownload2: msg.what = 1; sendMsg(msg); break; case R.ID.pausedownload2: msg.what = 2; sendMsg(msg); break; case R.ID.binddownloadservice2: Intent it = new Intent(DownloaderActivityWithHandler.this, DownloaderService2.class); startService(it); bindService(it, connection, BIND_auto_CREATE); break; case R.ID.unbinddownloadservice2: unbindService(connection); break; default: break; } } private voID sendMsg(Message msg) { try { serviceMessenger.send(msg); } catch (remoteexception e) { e.printstacktrace(); } } @OverrIDe public voID onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == RIGHTREWUESTCODE) { if (grantResults.length > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Message msg = new Message(); msg.what = 0; msg.setData(bundle); sendMsg(msg); } } }}
package com.slq.r1.service;import androID.app.Service;import androID.content.Intent;import androID.os.Bundle;import androID.os.Environment;import androID.os.Handler;import androID.os.IBinder;import androID.os.Message;import androID.os.Messenger;import androID.os.remoteexception;import androID.util.Log;import androID.Widget.Toast;import androIDx.annotation.NonNull;import com.slq.r1.utils.DownloaderTask;import java.io.file;import java.io.IOException;import java.io.inputStream;import java.io.RandomAccessfile;import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;import okhttp3.OkhttpClIEnt;import okhttp3.Request;import okhttp3.Response;public class DownloaderService2 extends Service { private static final String TAG = "DownloaderService2"; DownloaderTask downloaderTask; Messenger activityMessenger; Thread downloadThread; String url; final public static int SUCCESS = 1, PAUSE = 2, DELETE = 3, FAIL = 0, DOING = 5; int state; String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); file file; @OverrIDe public voID onCreate() { super.onCreate(); } public Handler handler = new Handler() { @OverrIDe public voID handleMessage(@NonNull Message msg) { Message msg1 = new Message(); switch (msg.what) { case -1: activityMessenger = msg.replyTo; break; case 10: //使用Runnable url = msg.getData().getString("url"); if (downloadThread == null || !downloadThread.isAlive()) { downloadThread = new Thread(new Runnable() { @OverrIDe public voID run() { downloaDWithResult(url); } }); downloadThread.start(); } break; case 0: //使用Callable url = msg.getData().getString("url"); if (downloadThread == null || !downloadThread.isAlive()) { Callable caller = new Callable<Integer>() { @OverrIDe public Integer call() throws Exception { return downloaDWithResult(url); } }; FutureTask f = new FutureTask(caller); downloadThread = new Thread(f); try { downloadThread.start(); //Log.e(TAG, "f.get(): "+f.get() ); //放开注释f.get()会阻塞主线程,应该用回调来解决 } catch (Exception e) { e.printstacktrace(); } } break; case 1: //stop if (downloadThread != null) { downloadThread.interrupt(); file.delete(); Toast.makeText(getApplicationContext(), "你已经stop下载", Toast.LENGTH_SHORT).show(); msg1.what = 2; sendMsg(msg1); } break; case 2: //pause if (downloadThread != null) { downloadThread.interrupt(); Toast.makeText(getApplicationContext(), "你已经暂停下载", Toast.LENGTH_SHORT).show(); } break; default: break; } } }; @OverrIDe public IBinder onBind(Intent intent) { // 创建Messenger对象包含handler引用 Messenger messenger = new Messenger(handler); // 返回Messenger的binder return messenger.getBinder(); } protected Integer downloaDWithResult(String... strings) { if (strings[0] != "") url = strings[0]; state = DOING; String filename = url.substring(url.lastIndexOf("/") + 1); inputStream is = null; RandomAccessfile rw = null; Response response = null; try { file = new file(directory, filename); Log.e(TAG, "download path:" + directory + "/" + filename); if (!file.exists()) file.createNewfile(); long current = file.length(); OkhttpClIEnt clIEnt = new OkhttpClIEnt(); Request request = new Request.Builder() .addheader("range", "bytes=" + current + "-") .url(url).build(); response = clIEnt.newCall(request).execute(); if (response != null) { long fileSize = response.body().contentLength() + current; if (current == fileSize) { return SUCCESS; } is = response.body().byteStream(); rw = new RandomAccessfile(file, "rw"); rw.seek(current); byte[] b = new byte[1024]; int len, co = 0; while ((len = is.read(b)) != -1) { if (state != DOING) { return state; } rw.write(b, 0, len); current += len; if (++co % 100 == 0) { publishProgress(current, fileSize); } } return SUCCESS; } } catch (IOException e) { e.printstacktrace(); } finally { try { if (is != null) is.close(); if (rw != null) rw.close(); if (response != null) response.close(); } catch (IOException e) { e.printstacktrace(); } } return FAIL; } voID publishProgress(long... values) { try { Message msg1 = new Message(); msg1.what = 1; Bundle bundle = new Bundle(); bundle.putIntArray("progress", new int[]{(int) values[0], (int) values[1]}); msg1.setData(bundle); activityMessenger.send(msg1); } catch (remoteexception e) { e.printstacktrace(); } } private voID sendMsg(Message msg) { try { activityMessenger.send(msg); } catch (remoteexception e) { e.printstacktrace(); } }}
回调参考DownloaderTask部分onPostExecute里downloaderListener的相关 *** 作,downloaderListener是自己定义的接口。代码如下:
public class DownloaderTask extends AsyncTask<String, Long, Integer> { private static final String TAG = "DownloaderTask"; private String url; String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); file file; final public static int SUCCESS = 1, PAUSE = 2, DELETE = 3, FAIL = 0, DOING = 5; int state; DownloaderListener downloaderListener; public voID setState(int state) { this.state = state; } public voID setDownloaderListener(DownloaderListener downloaderListener) { this.downloaderListener = downloaderListener; } @OverrIDe protected voID onPreExecute() { super.onPreExecute(); } @OverrIDe protected voID onPostExecute(Integer integer) { super.onPostExecute(integer); Log.e(TAG, "下载结果:" + integer); switch (integer) { case SUCCESS: downloaderListener.onSucess(); break; case FAIL: downloaderListener.onFail(); break; case PAUSE: downloaderListener.onPause(); break; case DELETE: file.delete(); downloaderListener.onStop(); break; default: break; } } @OverrIDe protected voID onProgressUpdate(Long... values) { super.onProgressUpdate(values); downloaderListener.onProgress(values[0], values[1]); } @OverrIDe protected voID onCancelled() { super.onCancelled(); } @OverrIDe protected Integer doInBackground(String... strings) { if(strings[0]!="")url = strings[0];// if (state == DOING) {// return null;// } else {// state = DOING;// } state = DOING; String filename = url.substring(url.lastIndexOf("/") + 1); inputStream is = null; RandomAccessfile rw = null; Response response = null; try { file = new file(directory, filename); Log.e(TAG, "download path:" + directory + "/" + filename); if (!file.exists()) file.createNewfile(); long current = file.length(); OkhttpClIEnt clIEnt = new OkhttpClIEnt(); Request request = new Request.Builder() .addheader("range", "bytes=" + current + "-") .url(url).build(); response = clIEnt.newCall(request).execute(); if (response != null) { long fileSize = response.body().contentLength() + current; if (current == fileSize) { return SUCCESS; } is = response.body().byteStream(); rw = new RandomAccessfile(file, "rw"); rw.seek(current); byte[] b = new byte[1024]; int len, co = 0; while ((len = is.read(b)) != -1) { if (state != DOING) { return state; } rw.write(b, 0, len); current += len; if (++co % 100 == 0) publishProgress(current, fileSize); } return SUCCESS; } } catch (IOException e) { e.printstacktrace(); } finally { try { if (is != null) is.close(); if (rw != null) rw.close(); if (response != null) response.close(); } catch (IOException e) { e.printstacktrace(); } } return FAIL; }}
public class DownloaderService extends Service { private static final String TAG = "DownloaderService"; private DownloaderBinder binder = new DownloaderBinder(); DownloaderTask downloaderTask; DownloaderListener downloaderListener = new MyDownloadListener(); final int DownloaderServiceNotificationID = 1; notificationmanager manager; NotificationCompat.Builder mBuilder; String channelID = "ID1"; public class MyDownloadListener implements DownloaderListener { @OverrIDe public voID onSucess() { downloaderTask = null; //stopForeground(true); //todo Notification notification = getNotificationPart2("下载完毕", 1, 1); //int importance = manager.getNotificationChannel(channelID).getimportance(); //Log.e(TAG, "importance: " + importance); manager.notify(DownloaderServiceNotificationID, notification); Toast.makeText(getApplicationContext(), "下载完毕", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onPause() { downloaderTask = null; Toast.makeText(getApplicationContext(), "你已经暂停下载", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onStop() { downloaderTask = null; manager.cancel(DownloaderServiceNotificationID); //stopForeground(true); //todo Toast.makeText(getApplicationContext(), "你停止了下载", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onFail() { downloaderTask = null; Notification notification = getNotificationPart2("下载失败", 0, 0); //int importance = manager.getNotificationChannel(channelID).getimportance(); manager.notify(DownloaderServiceNotificationID, notification); //Toast.makeText(getApplicationContext(), "下载失败!!!", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onProgress(long... values) { Notification notification = getNotificationPart2("下载进度", (int) values[0], (int) values[1]); manager.notify(DownloaderServiceNotificationID, notification); //Log.e(TAG, "当前下载进度: " + values[0] + "/" + values[1]); } } private voID getNotificationPart1() { Intent it = new Intent(this, DownloaderActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 0, it, 0); NotificationChannel chan1 = new NotificationChannel(channelID, "name1", notificationmanager.importANCE_MAX); manager.createNotificationChannel(chan1); mBuilder = new NotificationCompat.Builder(getApplicationContext(), channelID); mBuilder.setSmallicon(R.mipmap.ic_launcher) //设置小图标 .setContentIntent(pi) //.setSound(null) //.setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE) .setNotificationSilent(); } private Notification getNotificationPart2(String Title, int... params) { mBuilder.setContentTitle(Title) //设置标题 .setContentText("已下载" + params[0] + "/" + params[1]) .setProgress(params[1], params[0], false); return mBuilder.build(); } @OverrIDe public voID onCreate() { super.onCreate(); manager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE); getNotificationPart1(); } public DownloaderService() { } @OverrIDe public IBinder onBind(Intent intent) { return binder; } public class DownloaderBinder extends Binder { //如果去掉if,连续点两次会开启两个task public voID startDownload(String url) { //如果没有task,或者task已经被暂停或停止,重新new task if (downloaderTask == null) { downloaderTask = new DownloaderTask(); downloaderTask.setDownloaderListener(downloaderListener); downloaderTask.execute(url); //startForeground(DownloaderServiceNotificationID,getNotificationPart2("starting",1,1)); //todo } } public voID pauseDownload() { if (downloaderTask != null) { downloaderTask.setState(DownloaderTask.PAUSE); } } //如果先暂停再停止会无效,需要对downloaderTask == null的情况进行处理 public voID stopDownload() { if (downloaderTask != null) { downloaderTask.setState(DownloaderTask.DELETE); } } }}
总结 以上是内存溢出为你收集整理的android:断点续传下载文件并实时用通知显示下载进度全部内容,希望文章能够帮你解决android:断点续传下载文件并实时用通知显示下载进度所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)