我下面的代码下载文件工作正常时没有实现resume
,在阅读了更多解决方案来实现并解决问题我知道我必须检查Last-Modified
标头并设置它用于连接,
但我无法做到这一点,因为我收到android Cannot set request property after connection is made
或null
的{{1}}错误,
我正在使用此reference
httpURLConnection
heaser返回:
getHeaderField
现在我如何设置恢复下载文件?
{
null=[HTTP/1.1 200 OK],
Cache-Control=[public],
Connection=[keep-alive],
Content-Length=[8037404],
Content-Md5=[VEqXHCc/Off7a6D0gRFpiQ==],
Content-Type=[image/jpeg],
Date=[Tue, 19 Jan 2016 07:24:36 GMT],
Etag=["544a971c273f39f7fb6ba0f481116989"],
Expires=[Sat, 29 Jul 2017 10:07:00 GMT],
Last-Modified=[Thu, 18 Dec 2014 08:44:34 GMT],
Server=[bws],
X-Android-Received-Millis=[1501063623576],
X-Android-Response-Source=[NETWORK 200],
X-Android-Selected-Protocol=[http/1.1],
X-Android-Sent-Millis=[1501063623532]
}
我还得到public void run() {
final URL url;
HttpURLConnection httpURLConnection = null;
try {
try {
url = new URL(mUrl);
String lastModified = httpURLConnection.getHeaderField("Last-Modified");
if (!lastModified.isEmpty()) {
httpURLConnection.setRequestProperty("If-Range", lastModified);
}
httpURLConnection = (HttpURLConnection) url.openConnection();
if (mFile.exists()) {
downloadedLength = mFile.length();
Log.e("downloadedLength ", downloadedLength + "");
httpURLConnection.setRequestProperty("Range", "bytes=" + downloadedLength + "-");
fileOutputStream = new FileOutputStream(mFile, true);
} else {
fileOutputStream = new FileOutputStream(mFile);
}
httpURLConnection.setConnectTimeout(30000);
httpURLConnection.setReadTimeout(30000);
httpURLConnection.setRequestMethod("GET");
} catch (IOException e) {
}
final int responseCode;
final int total;
try {
responseCode = httpURLConnection.getResponseCode();
total = httpURLConnection.getContentLength();
} catch (IOException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
if (responseCode == 200) {
try {
inputStream = httpURLConnection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
Log.e("IOException ", e.getMessage());
}
final byte[] buffer = new byte[4 * 1024];
int length = -1;
int finished = 0;
long start = System.currentTimeMillis();
try {
while ((length = inputStream.read(buffer)) != -1) {
if (!isDownloading()) {
throw new CanceledException("canceled");
}
fileOutputStream.write(buffer, 0, length);
finished += length;
if (System.currentTimeMillis() - start > 1000) {
onDownloadProgressing(finished, total);
start = System.currentTimeMillis();
}
}
onDownloadCompleted();
} catch (IOException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
} else {
Log.e("responseCode ", responseCode + "");
}
} catch (DownloadException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
} catch (CanceledException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
}
响应代码,而不是206
答案 0 :(得分:5)
1- httpURLConnection为空,因为您在初始化之前尝试调用它,
即,这一行
httpURLConnection = (HttpURLConnection) url.openConnection();
应该在这一行之前:
String lastModified = httpURLConnection.getHeaderField("Last-Modified");
2-您可以在connect()
上致电httpURLConnection
之前设置标头
所以你需要设置你想要的任何东西,然后连接()。这样你不应该得到错误(android连接后无法设置请求属性)
3- 206 为perfectly right,这是Range
使用httpURLConnection.setRequestProperty("If-Range", lastModified);
时的含义,表示部分内容成功< / strong>以及您正在做的事情,您正在获取部分内容,如果您获得完整内容,您将获得 200 。
总而言之,您的代码可能如下所示: 注意:按照// ***查看所需的更改。
编辑:这一切都来到了这一行
public void run() {
myLastModified = getLastModified(mFile.getName()); // get last stored value for this file (use file name or other key)
int total =0;
final URL url;
HttpURLConnection httpURLConnection = null;
try {
try {
url = new URL(mUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(30000);
httpURLConnection.setReadTimeout(30000);
httpURLConnection.setRequestMethod("GET");
//*** new way to handle download process
total = httpURLConnection.getContentLength();
if(mFile.exists()){
if(mFile.length() == total){
//we are done, return.
return;
}else{
//file was not completly donwloaded, now check lastModified:
long lastModified = httpURLConnection.getLastModified();//this gets the header "Last-Modified" and convert to long
if (lastModified == myLastModified) { //myLastModified should be retrived on each download and stored locally on ur system
downloadedLength = mFile.length();
Log.e("downloadedLength ", downloadedLength + "");
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(30000);
httpURLConnection.setReadTimeout(30000);
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Range", "bytes=" + downloadedLength + "-"+ total); //add + total (TO)
//append mode
fileOutputStream = new FileOutputStream(mFile, true);
}else{
//file was modified after 1st uncompleted-download:
storeLastModified(lastModified, mFile.getName()); // use file name as key. can store in db or file ...
//don't set ant Range ... we want full download, with a fresh file
fileOutputStream = new FileOutputStream(mFile);
}//last mod IF
}//Length check
}else{
//file not exist at all, create new file, set no Range we want full download...
mFile.createNewFile();
fileOutputStream = new FileOutputStream(mFile);
}//file exists.
} catch (IOException e) {
e.printStackTrace();
}
final int responseCode;
try {
responseCode = httpURLConnection.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
//*****
if (responseCode == 200 || responseCode == 206) {
try {
inputStream = httpURLConnection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
Log.e("IOException ", e.getMessage());
}
final byte[] buffer = new byte[4 * 1024];
int length = -1;
int finished = 0;
long start = System.currentTimeMillis();
try {
while ((length = inputStream.read(buffer)) != -1) {
if (!isDownloading()) {
throw new CanceledException("canceled");
}
fileOutputStream.write(buffer, 0, length);
finished += length;
if (System.currentTimeMillis() - start > 1000) {
onDownloadProgressing(finished, total);
start = System.currentTimeMillis();
}
}
onDownloadCompleted();
} catch (IOException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
} else {
Log.e("responseCode ", responseCode + "");
}
} catch (DownloadException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
} catch (CanceledException e) {
e.printStackTrace();
Log.e("ER UPDATE ", e.getMessage());
}
}
设置该属性时会抛出错误,
无论如何,当你看到这个,它没有意义时,你会问最后修改是否等于你从连接中得到的值! 如果你想这样做,你需要在你的系统中存储 lastModified , 然后将它与您从URLConn获得的那个进行比较,并将其与您的文件长度(已下载)进行比较 然后继续完整下载或继续下载。
在下面找到新代码:
for ($i=0; $i <2 ; $i++) { //two sheet create excel workbook
$newsheet = $objPHPExcel->createSheet();//sheet create
$newsheet->setTitle("week". $i); //sheet name use looping
}
答案 1 :(得分:1)
查看this的POMATu回答。
但无论如何,如果您通过HTTP
协议下载文件,您可以使用DownloadManager
- 系统服务(自API级别9),以便在后台长时间运行下载。它处理HTTP
连接,连接更改,重新启动,并确保每次下载成功完成。它已经支持恢复并且还会提前通知。
您可以找到许多教程,例如this或that等示例,以及stackoverflow标记android-download-manager上的许多解决方案。