




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發技術】用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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 隧道機械化施工中的設備管理策略與實施計劃制定研究考核試卷
- 鉛酸電池的循環利用與環保技術考核試卷
- 貨運火車站物流企業績效管理體系構建與實施考核試卷
- 陶瓷藝術工作室運營與管理考核試卷
- 銅冶煉廠的安全管理體系構建與運行考核試卷
- 小兒常見眼部疾病診療與預防
- 食品營養與衛生
- 腦血管疾病的營養管理
- 呼吸科評分量表臨床應用與管理規范
- Glisoprenin-A-生命科學試劑-MCE
- 造紙術的課件
- 設備維修與保養培訓
- 小學生防治碘缺乏病
- 商業街區廣告牌更換施工方案
- DB21T 3806-2023 電梯檢驗檢測全程錄像工作規范
- 圖論及其應用知到智慧樹章節測試課后答案2024年秋山東大學
- 圖書選品與陳列藝術研究-洞察分析
- 【MOOC】電子技術實驗基礎一:電路分析-電子科技大學 中國大學慕課MOOC答案
- 【MOOC】經濟數學-微積分(二)-武漢理工大學 中國大學慕課MOOC答案
- DB22T 3053-2019 地理標志產品 乾安羊肉
- 《藥物代謝學》課程教學大綱
評論
0/150
提交評論