【移动应用开发技术】用AsyncTask实现断点续传_第1页
【移动应用开发技术】用AsyncTask实现断点续传_第2页
【移动应用开发技术】用AsyncTask实现断点续传_第3页
【移动应用开发技术】用AsyncTask实现断点续传_第4页
【移动应用开发技术】用AsyncTask实现断点续传_第5页
已阅读5页,还剩10页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】用AsyncTask实现断点续传

在学习四大组件之一的service时,正好可以利用asyncTask和OKhttp来进行断点续传,并在手机的前台显示下载进度。

尝试下载的是Oracle官网上的jdk1.7

在AS中使用OKhttp,只需要简单的在app/build.gradle里加入一句就可以了,如下代码,就最后一行加入即可dependencies

{

compile

fileTree(dir:

'libs',

include:

['*.jar'])

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',

{

exclude

group:

'com.android.support',

module:

'support-annotations'

})

compile

'com.android.support:appcompat-v7:25.3.1'

compile

'com.android.support.constraint:constraint-layout:1.0.2'

testCompile

'junit:junit:4.12'

compile

'com.squareup.okhttp3:okhttp:3.8.1'

}1、DownloadTask.java

在该类里主要进行了文件是否存在,存在的话是否已经下载完成等判断,还有利用OKhttp进行文件下载,最经典是是在文件写入RandomAccessFile里时,判断的当前状态,如果是isPaused是true,表示点了暂停键,那么就要暂停下载等等判断;还有使用asyncTask的方法,传递进度给前置通知显示下载进度。package

com.yuanlp.servicebestproject;

import

android.os.AsyncTask;

import

android.os.Environment;

import

java.io.File;

import

java.io.IOException;

import

java.io.InputStream;

import

java.io.RandomAccessFile;

import

okhttp3.OkHttpClient;

import

okhttp3.Request;

import

okhttp3.Response;

/**

*

Created

by

原立鹏

on

2017/7/1.

*/

public

class

DownloadTask

extends

AsyncTask<String,Integer,Integer>

{

private

static

final

String

TAG

=

"DownloadTask";

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_CANCELD=3;

private

DownLoadListener

listener;

private

boolean

isCanceld=false;

private

boolean

isPaused=false;

private

int

lastProgress;

public

DownloadTask(DownLoadListener

downloadListener){

this.listener=downloadListener;

}

@Override

protected

Integer

doInBackground(String...

params)

{

InputStream

is=null;

RandomAccessFile

savedFile=null;

//RandomAccessFile

用来访问指定的文件的

File

file=null;

try{

long

downloadLength=0;

//记录已经下载的文件中长度

String

downloadUrl=params[0];

String

fileName=downloadUrl.substring(downloadUrl.lastIndexOf("/"));

//获取文件名

String

directory=

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();

//获取文件保存路径

file=new

File(directory+fileName);

//创建文件

//如果文件存在

if

(file.exists()){

downloadLength=file.length();

//获取已经存在的文件大小

}

long

contentLength=getContentLength(downloadUrl);

//获取文件总大小

if

(contentLength==0){

return

TYPE_FAILED;

//已下载的文件异常,返回失败

}else

if

(downloadLength==contentLength){

return

TYPE_SUCCESS;

//说明下载的文件和总长度一样,返回成功

}

OkHttpClient

client=new

OkHttpClient();

Request

request=new

Request.Builder()

.header("RANGE","bytes="+downloadLength+"-")

//从下载之后的地方开始

.url(downloadUrl)

.build();

Response

response=client.newCall(request).execute();

if

(response!=null){

is=response.body().byteStream();

//获取response中的输入流

savedFile=new

RandomAccessFile(file,"rw");

//开始访问指定的文件

savedFile.seek(downloadLength);

//跳过已经下载的文件长度

byte[]

b=new

byte[1024];

long

total=0;

int

len;

while

((len=is.read(b))!=-1){

//这个时候说明还没有读取到输入流的最后

if

(isCanceld){

//说明取消了下载

return

TYPE_FAILED;

}else

if

(isPaused){

return

TYPE_PAUSED;

}else{

total+=len;

savedFile.write(b,0,len);

int

progress=

(int)

((total+downloadLength)*100/contentLength);

//计算下载的百分比

publishProgress(progress);

//调用onProgressUpdate()更新下载进度

}

}

response.body().close();

//关闭reponse

return

TYPE_SUCCESS;

//返回下载成功

}

}catch

(Exception

e){

e.printStackTrace();

}finally

{

try{

if

(is!=null){

is.close();

//关闭输入流

}

if

(savedFile!=null){

savedFile.close();

//关闭查看文件

}

if

(isCanceld&&file!=null){

file.delete();

//如果点击取消下载并且已经下载的文件存在,就删除文件

}

}catch(Exception

e){

e.printStackTrace();

}

}

return

TYPE_FAILED;

}

/**

*

在doInBackground

里调用ublishProgress时调用此方法,更新UI进度

*

@param

values

*/

public

void

onProgressUpdate(Integer...

values){

int

progress=values[0];

//获取传过来的百分比值

if

(progress>lastProgress){

listener.onProgress(progress);

}

}

/**

*

当doInBackground

执行完成时,调用此方法

*

@param

status

*/

public

void

onPostExecute(Integer

status){

switch

(status){

case

TYPE_SUCCESS:

listener.onSuccess();

break;

case

TYPE_FAILED:

listener.onFailed();

break;

case

TYPE_PAUSED:

listener.onPause();

break;

case

TYPE_CANCELD:

listener.onCancled();

break;

default:

break;

}

}

/**

*

按下暂停键时调用,暂停下载

*/

public

void

pausedDownload(){

isPaused=true;

}

public

void

canceledDownload(){

isCanceld=true;

}

/**

*

根据传入的rul地址,获取文件总长度

*

@param

url

*

@return

*/

public

long

getContentLength(String

url)

throws

IOException

{

OkHttpClient

client=new

OkHttpClient();

Request

request=new

Request.Builder()

.url(url)

.build();

Response

reponse=client.newCall(request).execute();

if

(reponse!=null&&reponse.isSuccessful()){

//成功返回reponse

long

contentLength=reponse.body().contentLength();

//获取文件中长度

return

contentLength;

}

return

0;

}

}2、DownloadService.java

在这个里面,主要是根据Mainactivity里的指令,进行调用downloadTask类里的方法,以及调用前置通知,显示进度。package

com.yuanlp.servicebestproject;

import

android.app.Notification;

import

android.app.NotificationManager;

import

android.app.PendingIntent;

import

android.app.Service;

import

android.content.Intent;

import

android.graphics.BitmapFactory;

import

android.os.Binder;

import

android.os.Environment;

import

android.os.IBinder;

import

android.support.v4.app.NotificationCompat;

import

android.widget.Toast;

import

java.io.File;

public

class

DownloadService

extends

Service

{

private

static

final

String

TAG

=

"DownloadService";

private

DownloadTask

downloadTask;

private

String

downloadUrl;

public

DownloadService()

{

}

@Override

public

IBinder

onBind(Intent

intent)

{

return

mBinder;

}

private

DownLoadListener

listener=new

DownLoadListener()

{

@Override

public

void

onProgress(int

progress)

{

getNotifactionManager().notify(1,getNotification("Downloading",progress));

}

@Override

public

void

onSuccess()

{

downloadTask=null;

//下载成功后,将前台通知关闭,并创建一个下载成功的通告

stopForeground(true);

getNotifactionManager().notify(1,getNotification("Download

Success",-1));

Toast.makeText(DownloadService.this,"Download

Success",Toast.LENGTH_SHORT).show();

}

@Override

public

void

onFailed()

{

downloadTask=null;

stopForeground(true);

getNotifactionManager().notify(1,getNotification("Down

Failed",-1));

Toast.makeText(DownloadService.this,"Down

Failed",Toast.LENGTH_SHORT).show();

}

@Override

public

void

onPause()

{

downloadTask=null;

Toast.makeText(DownloadService.this,"Paused",Toast.LENGTH_SHORT).show();

}

@Override

public

void

onCancled()

{

downloadTask=null;

Toast.makeText(DownloadService.this,"Canceled",Toast.LENGTH_SHORT).show();

}

};

private

DownloadBinder

mBinder=new

DownloadBinder();

class

DownloadBinder

extends

Binder{

public

void

startDownload(String

url){

if

(downloadTask==null){

downloadUrl=url;

downloadTask=new

DownloadTask(listener);

Toast.makeText(DownloadService.this,

"Downloading",

Toast.LENGTH_SHORT).show();

downloadTask.execute(downloadUrl);

startForeground(1,getNotification("Downloading...",0));

}

}

public

void

pauseDownload(){

if

(downloadTask==null){

downloadTask.pausedDownload();

}

}

public

void

cancelDownload(){

if

(downloadTask==null){

downloadTask.canceledDownload();

}else{

if

(downloadUrl!=null){

String

filename=downloadUrl.substring(downloadUrl.lastIndexOf("/"));

String

directory=

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();

File

file=new

File(directory);

if

(file.exists()){

file.delete();

}

getNotifactionManager().cancel(1);

stopForeground(true);

Toast.makeText(DownloadService.this,"Canceled",Toast.LENGTH_SHORT).show();

}

}

}

}

private

NotificationManager

getNotifactionManager(){

return

(NotificationManager)

getSystemService(NOTIFICATION_SERVICE);

}

private

Notification

getNotification(String

title,int

progress){

Intent

intent

=new

Intent(this,MainActivity.class);

PendingIntent

pi=PendingIntent.getActivity(this,0,intent,0);

NotificationCompat.Builder

builder=new

NotificationCompat.Builder(this);

builder.setSmallIcon(R.mipmap.ic_launcher);

builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));

builder.setContentIntent(pi);

builder.setContentTitle(title);

if

(progress>=0){

builder.setContentText(progress+"%");

builder.setProgress(100,progress,false);

}

return

builder.build();

}

}3、MainActivity.java

主要是进行了开启服务和绑定服务,对应按钮的操作,以及运行时权限申请。package

com.yuanlp.servicebestproject;

import

android.Manifest;

import

android.content.ComponentName;

import

android.content.Intent;

import

android.content.ServiceConnection;

import

android.content.pm.PackageManager;

import

android.os.Bundle;

import

android.os.IBinder;

import

android.support.v4.app.ActivityCompat;

import

android.support.v4.content.ContextCompat;

import

android.support.v7.app.AppCompatActivity;

import

android.view.View;

import

android.widget.Toast;

public

class

MainActivity

extends

AppCompatActivity

{

private

static

final

String

TAG

=

"MainActivity";

private

DownloadService.DownloadBinder

mDownloadBinder;

@Override

protected

void

onCreate(Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Intent

intent=new

Intent(this,DownloadService.class);

startService(intent);

bindService(intent,conn,BIND_AUTO_CREATE);

if

(ContextCompat.checkSelfPermission(MainActivity.this,

Manifest.permission.WRITE_EXTERNAL_STORAGE)!=

PackageManager.PERMISSION_GRANTED);

ActivityCompat.requestPermissions(MainActivity.this,new

String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);

}

private

ServiceConnection

conn=new

ServiceConnection()

{

@Override

public

void

onServiceConnected(ComponentName

name,

IBinder

service)

{

mDownloadBinder=

(DownloadServ

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论