android:断点续传下载文件并实时用通知显示下载进度

android:断点续传下载文件并实时用通知显示下载进度,第1张

概述参考第一行代码,代码:github写的很乱,下载完毕后的通知也没有实现。由于没有写回调处理downloadWithResult的返回值,所以返回值用不上。之前用asyncTask也写了一份,碰到notify通知频繁导致app很卡的问题,试着用handler来解决。最后发现是数值设置有误,导致notification每秒刷新上

参考第一行代码,代码:github
写的很乱,下载完毕后的通知也没有实现。由于没有写回调处理downloaDWithResult的返回值,所以返回值用不上。
之前用asyncTask也写了一份,碰到notify通知频繁导致app很卡的问题,试着用handler来解决。
最后发现是数值设置有误,导致notification每秒刷新上百次(理论上)。
通过百度学习了以下东西:

activity和service通过Messenger互相获取对方的handler,并发送消息。参考利用Handler实现Activity和Service之间通信callable可以获取返回值。但本例中如果在主线程等待返回值会阻塞主线程,应该和asyncTask的代码一样通过回调来解决线程被interupt不一定马上停止,即使停止状态也不是isinterupted,应该使用isalive查看线程是否运行
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:断点续传下载文件并实时用通知显示下载进度所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1041501.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存