Скачать в Android большие файлы - PullRequest
2 голосов
/ 06 марта 2011

Когда я пробую этот код, он начинает загрузку, но затем застревает с предупреждением «принудительное закрытие» что я должен делать? Использовать какую-то фоновую нить?

try {
    long startTime = System.currentTimeMillis();

    URL u = new URL("http://file.podfm.ru/3/33/332/3322/mp3/24785.mp3");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();

    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("/sdcard/","logo.mp3"));

    InputStream in = c.getInputStream();

    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ( (len1 = in.read(buffer)) != -1 ) {
        f.write(buffer,0, len1);
    }
    f.close();

    Log.d("ImageManager", "download ready in" +
        ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
    Log.d("ImageManager", "Error" +
        ((System.currentTimeMillis()) / 1000) + e + " sec");
}

Ответы [ 2 ]

10 голосов
/ 06 марта 2011

Я имел дело с подобной проблемой на прошлой неделе и в итоге использовал AsyncTask с отображением индикатора выполнения, поскольку загрузка файла могла занять некоторое время.Один из способов сделать это - поместить вложенный класс ниже в ваш Activity и просто вызывать его там, где вам нужно просто так:

new DownloadManager().execute("here be URL", "here be filename");

Или, если класс не находится внутри действия и вызывается издействие ..

new DownloadManager(this).execute("URL", "filename");

Это действие проходит, поэтому у нас есть доступ к методу getSystemService ();

Вот фактический код, выполняющий всю грязную работу.Возможно, вам придется изменить его для своих нужд.

private class DownloadManager extends AsyncTask<String, Integer, Drawable>
{

    private Drawable d;
    private HttpURLConnection conn;
    private InputStream stream; //to read
    private ByteArrayOutputStream out; //to write
    private Context mCtx;

    private double fileSize;
    private double downloaded; // number of bytes downloaded
    private int status = DOWNLOADING; //status of current process

    private ProgressDialog progressDialog;

    private static final int MAX_BUFFER_SIZE = 1024; //1kb
    private static final int DOWNLOADING = 0;
    private static final int COMPLETE = 1;

    public DownloadManager(Context ctx)
    {
        d          = null;
        conn       = null;
        fileSize   = 0;
        downloaded = 0;
        status     = DOWNLOADING;
        mCtx       = ctx;
    }

    public boolean isOnline()
    {
        try
        {
            ConnectivityManager cm = (ConnectivityManager)mCtx.getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getActiveNetworkInfo().isConnectedOrConnecting(); 
        }
        catch (Exception e)
        {
            return false;
        }
    }

    @Override
    protected Drawable doInBackground(String... url)
    {
        try
        {
            String filename = url[1];
            if (isOnline())
            {
                conn     = (HttpURLConnection) new URL(url[0]).openConnection();
                fileSize = conn.getContentLength();
                out      = new ByteArrayOutputStream((int)fileSize);
                conn.connect();

                stream = conn.getInputStream();
                // loop with step
                while (status == DOWNLOADING)
                {
                    byte buffer[];

                    if (fileSize - downloaded > MAX_BUFFER_SIZE)
                    {
                        buffer = new byte[MAX_BUFFER_SIZE];
                    }
                    else
                    {
                        buffer = new byte[(int) (fileSize - downloaded)];
                    }
                    int read = stream.read(buffer);

                    if (read == -1)
                    {
                        publishProgress(100);
                        break;
                    }
                    // writing to buffer
                    out.write(buffer, 0, read);
                    downloaded += read;
                    // update progress bar
                    publishProgress((int) ((downloaded / fileSize) * 100));
                } // end of while

                if (status == DOWNLOADING)
                {
                    status = COMPLETE;
                }
                try
                {
                    FileOutputStream fos = new FileOutputStream(filename);
                    fos.write(out.toByteArray());
                    fos.close();
                }
                catch ( IOException e )
                {
                    e.printStackTrace();
                    return null;
                }

                d = Drawable.createFromStream((InputStream) new ByteArrayInputStream(out.toByteArray()), "filename");
                return d;
            } // end of if isOnline
            else
            {
                return null;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }// end of catch
    } // end of class DownloadManager()

    @Override
    protected void onProgressUpdate(Integer... changed)
    {
        progressDialog.setProgress(changed[0]);
    }

    @Override
    protected void onPreExecute()
    {
        progressDialog = new ProgressDialog(/*ShowContent.this*/); // your activity
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMessage("Downloading ...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected void onPostExecute(Drawable result)
    {
        progressDialog.dismiss();
        // do something
    }
}
2 голосов
/ 06 марта 2011

Вы должны попробовать использовать AsyncTask .Вы получаете диалоговое окно принудительного выхода, потому что вы пытаетесь выполнить слишком много работы в потоке пользовательского интерфейса, и Android считает, что ваше приложение перестало отвечать.

Ответы на на этот вопрос имеют некоторуюссылки.

Было бы неплохо начать что-то вроде следующего:

private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void> {
     private final ProgressDialog dialog;

     public DownloadLargeFileTask(ProgressDialog dialog) {
          this.dialog = dialog;
     }

     protected void onPreExecute() {
         dialog.show();
     }

     protected void doInBackground(Void... unused) {
         downloadLargeFile();
     }

     protected void onPostExecute(Void unused) {
         dialog.dismiss();
     }
 }

и затем выполнить задачу с помощью:

ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Loading. Please Wait...");
new DownloadLargeFileTask(dialog).execute();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...