




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】用AsyncTask實(shí)現(xiàn)斷點(diǎn)續(xù)傳
在學(xué)習(xí)四大組件之一的service時(shí),正好可以利用asyncTask和OKhttp來進(jìn)行斷點(diǎn)續(xù)傳,并在手機(jī)的前臺(tái)顯示下載進(jìn)度。
嘗試下載的是Oracle官網(wǎng)上的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
在該類里主要進(jìn)行了文件是否存在,存在的話是否已經(jīng)下載完成等判斷,還有利用OKhttp進(jìn)行文件下載,最經(jīng)典是是在文件寫入RandomAccessFile里時(shí),判斷的當(dāng)前狀態(tài),如果是isPaused是true,表示點(diǎn)了暫停鍵,那么就要暫停下載等等判斷;還有使用asyncTask的方法,傳遞進(jìn)度給前置通知顯示下載進(jìn)度。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;
//記錄已經(jīng)下載的文件中長度
String
downloadUrl=params[0];
String
fileName=downloadUrl.substring(downloadUrl.lastIndexOf("/"));
//獲取文件名
String
directory=
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
//獲取文件保存路徑
file=new
File(directory+fileName);
//創(chuàng)建文件
//如果文件存在
if
(file.exists()){
downloadLength=file.length();
//獲取已經(jīng)存在的文件大小
}
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);
//跳過已經(jīng)下載的文件長度
byte[]
b=new
byte[1024];
long
total=0;
int
len;
while
((len=is.read(b))!=-1){
//這個(gè)時(shí)候說明還沒有讀取到輸入流的最后
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);
//計(jì)算下載的百分比
publishProgress(progress);
//調(diào)用onProgressUpdate()更新下載進(jìn)度
}
}
response.body().close();
//關(guān)閉reponse
return
TYPE_SUCCESS;
//返回下載成功
}
}catch
(Exception
e){
e.printStackTrace();
}finally
{
try{
if
(is!=null){
is.close();
//關(guān)閉輸入流
}
if
(savedFile!=null){
savedFile.close();
//關(guān)閉查看文件
}
if
(isCanceld&&file!=null){
file.delete();
//如果點(diǎn)擊取消下載并且已經(jīng)下載的文件存在,就刪除文件
}
}catch(Exception
e){
e.printStackTrace();
}
}
return
TYPE_FAILED;
}
/**
*
在doInBackground
里調(diào)用ublishProgress時(shí)調(diào)用此方法,更新UI進(jìn)度
*
@param
values
*/
public
void
onProgressUpdate(Integer...
values){
int
progress=values[0];
//獲取傳過來的百分比值
if
(progress>lastProgress){
listener.onProgress(progress);
}
}
/**
*
當(dāng)doInBackground
執(zhí)行完成時(shí),調(diào)用此方法
*
@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;
}
}
/**
*
按下暫停鍵時(shí)調(diào)用,暫停下載
*/
public
void
pausedDownload(){
isPaused=true;
}
public
void
canceledDownload(){
isCanceld=true;
}
/**
*
根據(jù)傳入的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
在這個(gè)里面,主要是根據(jù)Mainactivity里的指令,進(jìn)行調(diào)用downloadTask類里的方法,以及調(diào)用前置通知,顯示進(jìn)度。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;
//下載成功后,將前臺(tái)通知關(guān)閉,并創(chuàng)建一個(gè)下載成功的通告
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
主要是進(jìn)行了開啟服務(wù)和綁定服務(wù),對應(yīng)按鈕的操作,以及運(yùn)行時(shí)權(quán)限申請。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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生物降解塑料-深度研究
- 數(shù)字動(dòng)畫制作技術(shù)的創(chuàng)新路徑-深度研究
- YY/T 0107-2024眼科A型超聲測量儀
- 四川大學(xué)錦江學(xué)院《建筑冷熱源A》2023-2024學(xué)年第二學(xué)期期末試卷
- 秦皇島工業(yè)職業(yè)技術(shù)學(xué)院《世界上古史》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖南工程職業(yè)技術(shù)學(xué)院《學(xué)前兒童科學(xué)活動(dòng)設(shè)計(jì)與指導(dǎo)》2023-2024學(xué)年第二學(xué)期期末試卷
- 唐山科技職業(yè)技術(shù)學(xué)院《乒乓球俱樂部(初級(jí))》2023-2024學(xué)年第二學(xué)期期末試卷
- 新鄉(xiāng)醫(yī)學(xué)院三全學(xué)院《醫(yī)學(xué)遺傳與優(yōu)生》2023-2024學(xué)年第二學(xué)期期末試卷
- 肉雞養(yǎng)殖購銷合同樣本
- 建筑外墻清洗服務(wù)合同范本
- 電梯整機(jī)功能檢驗(yàn)記錄
- 醫(yī)治與釋放-課件
- (外研社版)小學(xué)英語語法大全
- 急危重癥護(hù)理學(xué)4課件
- 新疆民族發(fā)展史(精簡)
- 華為機(jī)器視覺好望系列產(chǎn)品介紹
- 多重耐藥護(hù)理查房
- 《旅游經(jīng)濟(jì)學(xué)》全書PPT課件
- 中國醫(yī)院質(zhì)量安全管理 第3-5部分:醫(yī)療保障 消毒供應(yīng) T∕CHAS 10-3-5-2019
- 安全評價(jià)理論與方法第五章-事故樹分析評價(jià)法
- 幼兒園一日活動(dòng)流程表
評論
0/150
提交評論