安卓学习之下载

Tesia ·
更新时间:2024-09-21
· 784 次阅读

首先依赖okhttp

定义一个回调接口 public interface DownloadListener { void onProgress(int progress);//用于通知当前的下载进度 void onSuccess();//用于通知下载成功事件 void onFailed();//用于通知下载失败事件 void onPaused();//用于通知下载暂停事件 void onCanceled();//用于通知下载取消事件 } 编写下载功能 /** * //这里我们把第一个泛型参数设置成String,表示在执行AsyncTask的时候传入字符串参数给后台服务 * //第二个人泛型参数指定为Integer,表示使用整型数据来作为进度显示单位 * //第二个人泛型参数指定为Integer,则表示使用整型数据来反馈执行结果 */ public class DownloadTask extends AsyncTask { public static final int TYPE_SUCCESS=0;//成功 public static final int TYPE_FAILED=1;//失败 public static final int TYPE_PAUSED=2;//暂停 public static final int TYPE_CANCELED=3;//取消 private DownloadListener listener; private boolean isCanceled=false; private boolean isPaused=false; private int lastProgress; public DownloadTask(DownloadListener listener) { this.listener = listener; } @Override protected Integer doInBackground(String... strings) { InputStream is=null; RandomAccessFile savefile=null; File file=null; try { long downloadedLength=0; String downloadUrl=strings[0]; String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")); String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); file=new File(directory+fileName); if (file.exists()){//如果文件存在就读取已下载的字节数 downloadedLength=file.length(); } long contentLength=getContentLength(downloadUrl);//调用getContentLength()来获取待下载文件的总长度 if (contentLength==0){//如果文件长度为0 return TYPE_FAILED;//下载失败 }else if (contentLength==downloadedLength){//如果文件长度等于下载长度 return TYPE_SUCCESS;//下载成功 } OkHttpClient client=new OkHttpClient(); Request request=new Request.Builder() //断点下载,指定从那个字节开始下载 .addHeader("RANGE","bytes="+downloadedLength+"-")//用于告诉服务器我们想要从那个字节开始下载 .url(downloadUrl) .build(); //读取服务器响应的数据 Response response=client.newCall(request).execute(); if (response!=null){//如果获取的数据不为空 就使用java的文件流方式,不断从网上读取数据,不断写入到本地,一直到下载完成为止 is=response.body().byteStream(); savefile=new RandomAccessFile(file,"rw"); savefile.seek(downloadedLength); byte[] b=new byte[1024]; int total=0; int len; while ((len=is.read(b))!=-1){ if (isCanceled){//如果用户点击取消则返回TYPE_CANCELED return TYPE_CANCELED; }else if (isPaused){////如果用户点击暂停则返回TYPE_PAUSED return TYPE_PAUSED; }else {//如果没有的话则实时计算当前的下载进度 total+=len; savefile.write(b,0,len); //计算已经下载的百分比 int progress=(int)((total+downloadedLength)*100/contentLength); publishProgress(progress);//调用publishProgress()方法进行通知 } } response.body().close(); return TYPE_SUCCESS; } } catch (Exception e) { e.printStackTrace(); }finally { try { if (is!=null){ is.close(); } if (savefile!=null){ savefile.close(); } if (isCanceled&&file!=null){ file.delete(); } }catch (Exception e){ e.printStackTrace(); } } return TYPE_FAILED; } @Override protected void onProgressUpdate(Integer... values) { int progress=values[0];//从参数获取到当前的下载进度 if (progress>lastProgress){//如果当前的下载进度大于上次的下载进度 listener.onProgress(progress);//调用DownloadListener的onProgress()来通知下载进度更新 lastProgress=progress; } } @Override protected void onPostExecute(Integer integer) {//根据参数中下载状态来进行回调 switch (integer){ case TYPE_SUCCESS: listener.onSuccess(); break; case TYPE_FAILED: listener.onFailed(); break; case TYPE_PAUSED: listener.onPaused(); break; case TYPE_CANCELED: listener.onCanceled(); break; default: break; } } public void pauseDownload(){ isPaused=true; } public void cancelDownload(){ isCanceled=true; } private long getContentLength(String downloadUrl) throws IOException { OkHttpClient client=new OkHttpClient(); Request request=new Request.Builder() .url(downloadUrl) .build(); Response response=client.newCall(request).execute(); if (response!=null&&response.isSuccessful()){ long contentLength=response.body().contentLength(); response.close(); return contentLength; } return 0; } } 新建service public class DownloadService extends Service { private DownloadTask downloadTask; private String DownloadUrl; private DownloadListener listener=new DownloadListener() { @Override public void onProgress(int progress) {//通知当前的下载进度 getNotificationManager().notify(1,getNotification("下载中..",progress)); } @Override public void onSuccess() {//用于通知下载成功事件 downloadTask=null; //下载成功时将前台服务通知关闭,并创建一个下载成功的通知 stopForeground(true); getNotificationManager().notify(1,getNotification("下载成功",-1)); Toast.makeText(DownloadService.this, "下载成功了", Toast.LENGTH_SHORT).show(); } @Override public void onFailed() {//用于通知下载失败事件 downloadTask=null; //下载失败时将前台服务通知关闭,并创建一个下载失败的通知 stopForeground(true); getNotificationManager().notify(1,getNotification("下载失败",-1)); Toast.makeText(DownloadService.this, "下载失败了", Toast.LENGTH_SHORT).show(); } @Override public void onPaused() {//用于通知下载暂停事件 downloadTask=null; Toast.makeText(DownloadService.this, "暂停下载", Toast.LENGTH_SHORT).show(); } @Override public void onCanceled() {//用于通知下载取消事件 downloadTask=null; //下载取消时将前台服务通知关闭 stopForeground(true); Toast.makeText(DownloadService.this, "取消下载", Toast.LENGTH_SHORT).show(); } }; DownloadBinder mybinder=new DownloadBinder(); public DownloadService() { } @Override public IBinder onBind(Intent intent) { return mybinder; } class DownloadBinder extends Binder{ public void startDownload(String url){//开始下载 if (downloadTask==null){ DownloadUrl=url; downloadTask=new DownloadTask(listener); downloadTask.execute(DownloadUrl); startForeground(1,getNotification("下载中",0)); Toast.makeText(DownloadService.this, "下载中", Toast.LENGTH_SHORT).show(); } } public void pauseDownload(){//暂停下载 if (downloadTask!=null){ downloadTask.pauseDownload(); } } public void cancelDownload(){//取消下载 if (downloadTask!=null){ downloadTask.cancelDownload(); }else { if (DownloadUrl!=null){ //取消下载时将文件删除,并将通知关闭 String fileName="我是文件名"; String directory= Environment.getExternalStorageState(); File file=new File(directory+fileName); if (file.exists()){ file.delete(); } getNotificationManager().cancel(1); Toast.makeText(DownloadService.this, "取消下载", Toast.LENGTH_SHORT).show(); } } } } private NotificationManager getNotificationManager(){ return (NotificationManager) getSystemService(NOTIFICATION_SERVICE); } private Notification getNotification(String title,int progress) { String id = "my_channel_033"; String name = "我是渠道名33"; Notification notification = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel mchannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH); getNotificationManager().createNotificationChannel(mchannel); } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, id); Intent intent = new Intent(this, MainActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0); builder.setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(title) .setContentIntent(pi);//跳转 if (progress>0){ //当progress大于等于0时才需要显示下载进度 builder.setContentText(progress+"%"); builder.setProgress(100,progress,false); } return builder.build(); } } 好了,后端的工作完成了,接下来编写前端
需要 登录 后方可回复, 如果你还没有账号请 注册新账号