import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.TextView; public class BackFLoaderActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button load = new Button(this); load.setText("Load file"); load.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { downloadFile("http://anjedi.com/api_lib/2.2_level8.jar"); } }); setContentView(load, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } private void downloadFile(String url) { final ProgressDialog progressDialog = new ProgressDialog(this); new AsyncTask<String, Integer, File>() { private Exception m_error = null; @Override protected void onPreExecute() { progressDialog.setMessage("Downloading ..."); progressDialog.setCancelable(false); progressDialog.setMax(100); progressDialog .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.show(); } @Override protected File doInBackground(String... params) { URL url; HttpURLConnection urlConnection; InputStream inputStream; int totalSize; int downloadedSize; byte[] buffer; int bufferLength; File file = null; FileOutputStream fos = null; try { url = new URL(params[0]); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoOutput(true); urlConnection.connect(); file = File.createTempFile("Mustachify", "download"); fos = new FileOutputStream(file); inputStream = urlConnection.getInputStream(); totalSize = urlConnection.getContentLength(); downloadedSize = 0; buffer = new byte[1024]; bufferLength = 0; // читаем со входа и пишем в выход, // с каждой итерацией публикуем прогресс while ((bufferLength = inputStream.read(buffer)) > 0) { fos.write(buffer, 0, bufferLength); downloadedSize += bufferLength; publishProgress(downloadedSize, totalSize); } fos.close(); inputStream.close(); return file; } catch (MalformedURLException e) { e.printStackTrace(); m_error = e; } catch (IOException e) { e.printStackTrace(); m_error = e; } return null; } // обновляем progressDialog protected void onProgressUpdate(Integer... values) { progressDialog .setProgress((int) ((values[0] / (float) values[1]) * 100)); }; @Override protected void onPostExecute(File file) { // отображаем сообщение, если возникла ошибка if (m_error != null) { m_error.printStackTrace(); return; } // закрываем прогресс и удаляем временный файл progressDialog.hide(); file.delete(); } }.execute(url); } }
В этом маленьком приложении при нажатии на кнопку запускается загрузка файла, при этом пользователь наблюдает прогресс-бар. Не забудьте добавить в манифест запрос разрешений на доступ к интернет и файловой системе.
Основой примера является метод, который я взял отсюда (и поправил пару ошибок).
Этот метод принимает url файла, который нужно загрузить, загружает файл, отображая при этом горизонатальный прогресс-бар. При этом прогресс-бар реально показывает какая часть файла в данный момент загружена. По окончании загрузки файл удаляется.
Разберём работу метода подробнее:
Главная часть метода - создание AcyncTask-а и переопределение его методов.
В методе onPreExecute мы запускаем progressDialog, установив предварительно текст сообщения и максимальное значение прогресса: 100%.
В методе doInBackground - выполняем собственно загрузку файла. Файл читаем из urlConnection порциями по 1024 байт, каждый раз прибавляя размер полученной порции к общему счётчику. Счётчик и общий размер файла передаём при каждой итерации в метод publishProgress, благодаря чему в методе onProgressUpdate мы получаем эти данные и обновляем текущий статус progressDialog-а.
И, наконец, в методе onPostExecute мы прячем диалог и удаляем временный файл.
Особенностью использования AsyncTask-a является способ, как он объявляется и как в него передаются параметры. Типы, которыми параметризуется экземпляр AsyncTask-a определяю по порядку: тип входящего значения, тип параметра, опреляющего прогресс опреации и тип результата фоновой операции (то что возвращает doInBackground и принимает onPostExecute). Кроме того конструктор и чаcть методов AsyncTask-а принимает varargs, т.е. произвольное число параметров, что весьма удобно в некоторых случаях.
new AsyncTask()
ОтветитьУдалитьна это ругается.
//="" file=""// это подчеркивает красным
пишет
Syntax error on tokens, ReferenceType expected instead
Нужно подключить android.jar
УдалитьПри наведении на ошибку появится что-то типа fix...
Нажимаете и он сам добавит
Аналогичная проблема, что делать?
ОтветитьУдалитьСпасибо за замечание, ошибка была в оригинале, исправил. Заодно выложил весь код Activity для наглядности.
ОтветитьУдалитьУ меня при изменении адреса "http://anjedi.com/api_lib/2.2_level8.jar" на любой другой вылетает ошибка FileNotFound. Но по этим же ссылкам через браузер качается. Что это может быть?
ОтветитьУдалитьПрисоединяюсь к предыдущему вопросу
ОтветитьУдалитьУ меня код получения размера файла не работает, хотя данные получаются.
ОтветитьУдалитьURL url = new URL(arg0);
HttpURLConnection uraconn = (HttpURLConnection) url.openConnection();
uraconn.setRequestMethod("GET");
uraconn.setDoOutput(true);
uraconn.connect();
Что это может значить?
Та же проблема и у меня. В чем дело? Код использую данный в статье, работаю в Thread.
ОтветитьУдалитьа файл куда сохраняется?
ОтветитьУдалитьразрешений на доступ к интернет и файловой системе.
ОтветитьУдалитьк интернету - android.permission.INTERNET
а к файловой системе не подскажите?
urlConnection.setDoInput(true);
ОтветитьУдалитьнужно добавить я так сделал и у меня заработало!
Идеально подходит для загрузки файлов (не картинок)!
ОтветитьУдалитьПодскажете по моменту связаным с тем что если заменяешь значение в загрузке string оно упорно пишет что файл не найден. Так же как и по вопросу куда таки идет закачка файла?
ОтветитьУдалитьфайл стал находится после закомменчивания вот этого
ОтветитьУдалитьurlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
Закачка ведется в темп файл, нужно заменить его на файл на сд карте, поставить пермишионс и будет щастье
slava sheff, ты мой герой! закоментил точно также и стал хотя бы размер определяться))) Будь здоров, мэн!
Удалить