在android下面的斷點續傳和java下面沒有太大的衝突,就是在配置檔案裡面加上一些特定的訪問許可權就可以了

如下式在AndroidManifest.xml加入的許可權

 

<!–  訪問internet許可權 –>

       <uses-permission android:name=”android.permission.INTERNET” />

       <!–  SDCard中建立與刪除檔案許可權–>

       <uses-permission android:name=”android.permission.MOUNT_UNMOUNT_FILESYSTEMS” />

       <!–  SDCard寫入資料許可權–>

       <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

這個準備工作做好了就可以直接編碼了

第一步建立multiThreaddownload.java

 

package com.cn.download;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.URL;

import java.net.URLConnection;

 

import com.cn.coocaa.download.FileDownloadThread;

 

public class MultiThreadDownload extends Thread {

        //定義的一些常量變數,看名字就知道什麼意思了

private static final int BUFFER_SIZE = 1024;

private int blockSize;

private int threadNum = 5;

private int fileSize;

private int downloadedSize;

String urlStr, threadNo, fileName;

private String savePath;

private int downloadPercent = 0 , downloadSpeed = 0, usedTime=0;

private long startTime,curTime;

private boolean completed = false;

        //用URL,儲存路徑,儲存名稱來構造。

public MultiThreadDownload(String URL, String savePath, String fileName) {

this.urlStr = URL;

this.savePath = savePath;

this.fileName = fileName;

}

 

@Override

public void run() {

FileDownloadThread[] fds = new FileDownloadThread[threadNum];

try {

URL url = new URL(urlStr);

URLConnection conn = url.openConnection();

fileSize = conn.getContentLength();

blockSize = fileSize / threadNum;

File file[] = new File[threadNum];

                        //根據預設的執行緒數,或者自己修改設定的執行緒數來分塊,建立分塊後的檔案塊

for (int i = 0; i < threadNum; i++) {

file[i] = new File(savePath + fileName + “.part”

+ String.valueOf(i));

                                //將分塊的檔案交給每個執行緒處理,最後一塊應該大於等於平均塊,因為可能有餘數

FileDownloadThread fdt = new FileDownloadThread(url, file[i], i

* blockSize, (i + 1) != threadNum ? ((i + 1)

* blockSize – 1) : fileSize);

fdt.setName(“Thread” + i);

fdt.start();

fds[i] = fdt;

}

startTime = System.currentTimeMillis();

                        //獲取起始下載的時間,用次來計算速度。

boolean finished = false;

while (!finished) {

downloadedSize = 0;

finished = true;

for (int i = 0; i < fds.length; i++) {

downloadedSize += fds[i].getDownloadSize();

if (!fds[i].isFinished()) {

finished = false;

}

}

                                //計算下載的百分比

downloadPercent = (downloadedSize*100)/fileSize;

                                //獲取當前時間,計算平均下載速度

curTime = System.currentTimeMillis();

usedTime =(int)((curTime-startTime)/1000);

if(usedTime==0)

usedTime =1;

downloadSpeed = (downloadedSize/usedTime)/1024;

sleep(1000);

}

                       //這個是分塊下載完成的標誌

completed = true;

                        //進行模組整合

RandomAccessFile raf = new RandomAccessFile(savePath + fileName,

“rw”);

byte[] tempbytes = new byte[BUFFER_SIZE];

InputStream in = null;

int byteread = 0;

for (int i = 0; i < threadNum; i++) {

in = new FileInputStream(file[i]);

while ((byteread = in.read(tempbytes)) != -1)

{

raf.write(tempbytes, 0, byteread);

}

                                //每次整合完一塊就刪除一塊。

in.close();

file[i].delete();

}

raf.close();

 

} catch (Exception e) {

// TODO: handle exception

}

}

       //獲取下載百分比

public int getDownloadPercent(){

return this.downloadPercent;

}

       //獲取下載速度

public int getDownloadSpeed(){

return this.downloadSpeed;

}

       //修改預設執行緒數

public void setThreadNum(int threadNum){

this.threadNum = threadNum;

}

        //分塊下載完成的標誌

public boolean isCompleted(){

return this.completed;

}

}

第二步 建立filedownloadthread.java
package com.cn.download;
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
 
public class FileDownloadThread extends Thread {
private static final int BUFFER_SIZE = 1024;
private URL url;
private File file;
private int startPosition;
private int endPosition;
private int curPosition;
private boolean finished = false;
private int downloadSize = 0;
       //分塊建構函式
public FileDownloadThread(URL url, File file, int startPosition,
int endPosition) {
this.url = url;
this.file = file;
this.startPosition = startPosition;
this.curPosition = startPosition;
this.endPosition = endPosition;
}
 
public void run() {
 
 
BufferedInputStream bis = null;
RandomAccessFile fos = null;
byte[] buf = new byte[BUFFER_SIZE];
URLConnection con = null;
try {
                       //開啟URL連線
con = url.openConnection();
con.setAllowUserInteraction(true);
                       //判斷是否該檔案存在,如果存在且下載完成,直接返回。
if ((file.length() + startPosition) == endPosition) {
this.finished = true;
}
                        //檔案未下載完成,獲取到當前指標位置,繼續下載。
                         else {
con.setRequestProperty(“Range”, “bytes=”
+ (startPosition + file.length()) + “-” + endPosition);
fos = new RandomAccessFile(file, “rw”);
fos.seek(file.length());
bis = new BufferedInputStream(con.getInputStream());
while (curPosition < endPosition) {
int len = bis.read(buf, 0, BUFFER_SIZE);
if (len == -1) {
break;
}
fos.write(buf, 0, len);
curPosition = curPosition + len;
if (curPosition > endPosition) {
downloadSize += len – (curPosition – endPosition) + 1;
} else {
downloadSize += len;
}
}
this.finished = true;
bis.close();
fos.close();
}
} catch (IOException e) {
System.out.println(getName() + ” Error:” + e.getMessage());
}
}
 
public boolean isFinished() {
return finished;
}
 
public int getDownloadSize() {
return downloadSize;
}
}
上述兩個檔案就完成了多執行緒斷點續傳。
 
 
 
無需使用任何配置檔案或者資料庫,就可以接上次的斷點進行續傳操作。
 
原理流程:
         1、獲取檔案大小
         2、將檔案按照所設定的執行緒數進行分塊請求。
         3、檢查是否存在斷點情況,如果有斷點情況則進行斷點查詢,然後再請求。
         4、分塊下載。
         5、下載完成後檔案整合,將分塊檔案刪除掉。
         6、好了,你需要下載的檔案就可以完成了。
 
 
總之了,在這裡也是一種實現無需配置檔案的方式吧,我提供的只是一個外部呼叫包,所以這個配置檔案或者資料庫記錄的東西有很大的侷限性,所以就切割了,
 
如果有什麼更好的想法,希望能相互交流交流。