Java中的部分下载噩梦

时间:2013-08-20 09:11:49

标签: java android download http-headers httpurlconnection

以下是我在Android应用中从互联网上下载文件的完整代码。我们的想法是在应用程序重新启动/恢复时从中断处继续下载。

package com.example.simpledownloader.task;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.atomic.AtomicLong;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.util.Log;

import com.example.simpledownloader.sharable.NetworkOptions;
import com.example.simpledownloader.sharable.Sharable;

public class Task extends Thread {

    private String url = null;
    private String name = null;
    private AtomicLong contentLength = null;
    private AtomicLong bytesWritten = null;

    private boolean isReady = true;
    private String errCode = new String("OK");

//------------------------------------------------------------------------------
    public Task(String name, String url, long contentLength, long bytesWritten){
        // Instantiate the variables
        // The values here depend on whether the Task was created by TaskDAO
        // or by clicking the download button
        this.name = name;
        this.url = url;
        this.contentLength = new AtomicLong(contentLength);
        this.bytesWritten = new AtomicLong(bytesWritten);
    }
//------------------------------------------------------------------------------
    @Override
    public void run() {
        File f = null;
        RandomAccessFile rFile = null;
        setReadiness(false);
        Sharable.setShouldLook(false);
        try {
            String[] names = name.split("/");
            if(names.length == 0){
                // nothing
            }else{
                name = names[names.length-1];
            }
            Log.v("TASKPATH", "/sdcard/" + name);
            f = new File("/sdcard/",name);
            rFile = new RandomAccessFile(f, "rw");
            writeToFile(rFile);
        } catch (FileNotFoundException e) {
            Log.v("TASK", e.getLocalizedMessage());
            if(contentLength.get() == 0){ // new download will have content length set to zero
                try {
                    f.createNewFile(); // make a new file
                    writeToFile(rFile);// start downloading
                }catch (IOException e1) {
                    errCode = e1.getMessage(); // Unable to create file;
                    Log.v("TASK", "FILE DELETED");
                    Sharable.setShouldLook(true);
                    return;
                }
            }else{
                errCode = "Created file has been deleted"; // File was previously created but now is not found.
                Log.v("TASK", "FILE DELETED");
                Sharable.setShouldLook(true);
                return;
            }
        } catch (IOException e) {
            errCode = e.getLocalizedMessage();
            Sharable.setShouldLook(true);
            Log.v("TASK", e.getLocalizedMessage());
        }
    }
//------------------------------------------------------------------------------
    private void writeToFile(RandomAccessFile file){

        NetworkInfo wifi = Sharable.connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        NetworkInfo mobile = Sharable.connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        URL u;
        HttpURLConnection httpCon = null;

            try {
                byte[] buffer = new byte[2 * 1024]; // 2 MB buffer
                long bytesWritten = 0;

                if(contentLength.get() == 0){ // new file ?
                    u = new URL(url); // make a URL
                    httpCon = (HttpURLConnection) u.openConnection(); // Get ready to make a connection via HTTP
                    httpCon.setDoInput(true); // this connection will download data
                    httpCon.connect(); // make a connection
                    BufferedInputStream buf = new BufferedInputStream(httpCon.getInputStream()); // get a stream
                    contentLength.addAndGet(httpCon.getContentLength()); // set content length
                    while((bytesWritten = buf.read(buffer)) != -1 ){
                        if(Sharable.networkOption == NetworkOptions.WIFI_ONLY){
                            if(!wifi.isConnected()){ // check WiFi connectivity
                                setReadiness(false);
                                Sharable.setShouldLook(true);
                                break;
                            }
                        }
                        Log.v("TASK", "Writing at location " + this.bytesWritten.get());
                        file.write(buffer);
                        this.bytesWritten.addAndGet(bytesWritten);
                        String update = "UPDATE tasks SET byteswritten=" + this.bytesWritten.get() + 
                                " ,contentlength=" + this.contentLength.get() + 
                                " WHERE url='" + url + "'";
                        Sharable.db.execSQL(update); // write data to database
                        Sharable.handler.post(new Runnable(){
                            @Override
                            public void run() {
                                Sharable.adapter.notifyDataSetChanged(); // update the display  
                            }
                        });
                        if(isInterrupted()){
                            setReadiness(true);
                            Sharable.setShouldLook(true);
                            break;
                        }
                    }
                }else{ // not a new file
                    file.seek(this.bytesWritten.get()); // seek to proper position
                    u = new URL(url); // make a URL
                    httpCon = (HttpURLConnection) u.openConnection(); // Get ready to make a connection via HTTP
                    httpCon.setDoInput(true); // this connection will download data
                    httpCon.setRequestProperty("Range:", "bytes="+this.bytesWritten.get()+"-");
                    httpCon.connect(); // make a connection
                    if(httpCon.getResponseCode() != HttpURLConnection.HTTP_PARTIAL){ // check if partial download supported
                        errCode = "206 Not Supported";
                        setReadiness(false);
                        Sharable.setShouldLook(true);
                        return;
                    }
                    BufferedInputStream buf = new BufferedInputStream(httpCon.getInputStream()); // get a stream
                    while((bytesWritten = buf.read(buffer)) != -1 ){ // start downlading
                        if(Sharable.networkOption == NetworkOptions.WIFI_ONLY){
                            if(!wifi.isConnected()){ // check WiFi connectivity
                                setReadiness(false);
                                Sharable.setShouldLook(true);
                                if(httpCon != null){
                                    httpCon.disconnect();
                                }
                                break;
                            }   
                        }
                        Log.v("TASK", "Writing at location " + this.bytesWritten.get());
                        file.write(buffer);
                        this.bytesWritten.addAndGet(bytesWritten);
                        String update = "UPDATE tasks SET byteswritten=" + this.bytesWritten.get() + 
                                " ,contentlength=" + this.contentLength.get() + 
                                " WHERE url='" + url + "'";
                        Sharable.db.execSQL(update); // write data to database
                        Sharable.handler.post(new Runnable(){
                            @Override
                            public void run() {
                                Sharable.adapter.notifyDataSetChanged(); // update the display  
                            }
                        });
                        if(isInterrupted()){ // check for thread interruption
                            setReadiness(true);
                            Sharable.setShouldLook(true);
                            break;
                        }
                    }
                }
            } catch (MalformedURLException e) {
                errCode = e.getMessage();
                Log.v("TASK", e.getLocalizedMessage());
            } catch (IOException e) {
                errCode = e.getLocalizedMessage();
                Log.v("TASK", e.getLocalizedMessage());
            }catch(Exception e){
                errCode = e.getLocalizedMessage();
                Log.v("TASK", e.getLocalizedMessage());
            }
    }
//------------------------------------------------------------------------------
    public synchronized float getProgress(){
        if(contentLength.get() != -1 && contentLength.get() != 0){
            return (bytesWritten.get()*100)/contentLength.get();
        }else{
            return -1;
        }
    }
//------------------------------------------------------------------------------
    public synchronized boolean getReadiness(){
        return isReady;
    }
//------------------------------------------------------------------------------
    public synchronized void setReadiness(boolean ready){
        isReady = ready;
    }
//------------------------------------------------------------------------------
    public synchronized String getStatus(){
        return errCode;
    }
//------------------------------------------------------------------------------
    public synchronized String getTaskName(){
        return name;
    }
//------------------------------------------------------------------------------
    @Override
    public String toString(){
        return name;
    }
//------------------------------------------------------------------------------
}  

然而,问题是部分下载永远不会开始......我不知道为什么。我通常最终没有任何活动或206 Not Supported错误 您可能感兴趣的其他类是包含单例实例的Sharable
Sharable.javaScheduler.java

如何恢复部分下载?

0 个答案:

没有答案