【移動應用開發技術】用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

提交評論