diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9c4de58
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..c78db89
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+homework5-master
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..bd4202c
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..fbb6828
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..aa89085
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..aef896b
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generateDebugAndroidTestSources
+ generateDebugSources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 34fb554..5e9ae22 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,7 +11,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
-
+
@@ -20,4 +20,4 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/java/ru/ifmo/android_2015/homework5/DownloadService.java b/app/src/main/java/ru/ifmo/android_2015/homework5/DownloadService.java
new file mode 100644
index 0000000..692ce31
--- /dev/null
+++ b/app/src/main/java/ru/ifmo/android_2015/homework5/DownloadService.java
@@ -0,0 +1,50 @@
+package ru.ifmo.android_2015.homework5;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.util.Log;
+
+import java.io.IOException;
+
+public class DownloadService extends IntentService {
+
+
+ public DownloadService(String name) {
+ super(name);
+ }
+
+ public DownloadService() {
+ super("DownloadService");
+ }
+
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ if (intent != null) {
+ final String action = intent.getAction();
+ if (action.equals("DOWNLOAD")) {
+ try {
+ InitSplashActivity.downloadFile(this, new ProgressCallback() {
+ @Override
+ public void onProgressChanged(int progress) {
+ sendProgress(InitSplashActivity.DownloadState.DOWNLOADING, progress);
+ }
+ });
+ } catch (Exception e) {
+ sendProgress(InitSplashActivity.DownloadState.ERROR, 100);
+ return;
+ }
+ sendProgress(InitSplashActivity.DownloadState.DONE, 100);
+ }
+ }
+ }
+
+ private void sendProgress(InitSplashActivity.DownloadState downloadState, int progress) {
+ Intent intent = new Intent(String.valueOf(R.string.action));
+ intent.putExtra("download_state", downloadState);
+ intent.putExtra("progress", progress);
+
+ sendBroadcast(intent);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/ifmo/android_2015/homework5/InitSplashActivity.java b/app/src/main/java/ru/ifmo/android_2015/homework5/InitSplashActivity.java
index 8810d30..266e9a4 100644
--- a/app/src/main/java/ru/ifmo/android_2015/homework5/InitSplashActivity.java
+++ b/app/src/main/java/ru/ifmo/android_2015/homework5/InitSplashActivity.java
@@ -1,8 +1,10 @@
package ru.ifmo.android_2015.homework5;
import android.app.Activity;
+import android.content.BroadcastReceiver;
import android.content.Context;
-import android.os.AsyncTask;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.ProgressBar;
@@ -11,24 +13,16 @@
import java.io.File;
import java.io.IOException;
-/**
- * Экран, выполняющий инициализацию при первом запуске приложения. В процессе инициализации
- * скачивается файл с данными, нужными для работы приложения. Пока идет инициализация, показывается
- * сплэш-скрин с индикатором прогресса.
- */
+
public class InitSplashActivity extends Activity {
- // Урл для скачивания файла с данными, нужными для инициализации приложения при первом запуске.
- // GZIP-архив, содержащий список городов в формате JSON.
private static final String CITIES_GZ_URL =
"https://www.dropbox.com/s/d99ky6aac6upc73/city_array.json.gz?dl=1";
- // Индикатор прогресса
private ProgressBar progressBarView;
- // Заголовок
+ private DownloadState downloadState;
private TextView titleTextView;
- // Выполняющийся таск загрузки файла
- private DownloadFileTask downloadTask;
+ private BroadcastReceiver broadcastReceiver;
@Override
@SuppressWarnings("deprecation")
@@ -42,38 +36,79 @@ protected void onCreate(Bundle savedInstanceState) {
progressBarView.setMax(100);
+
+ if (savedInstanceState == null) {
+ downloadState = DownloadState.DOWNLOADING;
+ startReceiver();
+ Intent intent = new Intent(this, DownloadService.class);
+ intent.setAction("DOWNLOAD");
+ startService(intent);
+ }
+ }
+ @Override
+ protected void onDestroy() {
+ Log.d(TAG, "onDestroy");
+ super.onDestroy();
+ }
+
+ protected void onSaveInstanceState(Bundle outState) {
+ Log.d(TAG, "onRestore");
+ outState.putSerializable("download_state", downloadState);
+ outState.putInt("progress", progressBarView.getProgress());
+ super.onSaveInstanceState(outState);
+ }
+
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ Log.d(TAG, "onRestore");
+ super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
- // Пытаемся получить ранее запущенный таск
- downloadTask = (DownloadFileTask) getLastNonConfigurationInstance();
+ downloadState = (DownloadState) savedInstanceState.getSerializable("download_state");
+ updateView(downloadState, savedInstanceState.getInt("progress"));
+ startReceiver();
}
- if (downloadTask == null) {
- // Создаем новый таск, только если не было ранее запущенного таска
- downloadTask = new DownloadFileTask(this);
- downloadTask.execute();
+ }
+
+ private void startReceiver() {
+ if (downloadState == DownloadState.DOWNLOADING ) {
+ broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ downloadState = (DownloadState) intent.getSerializableExtra("download_state");
+ int progress = intent.getIntExtra("progress", 0);
+ if (downloadState == DownloadState.DONE || downloadState == DownloadState.ERROR) {
+ unregisterReceiver(broadcastReceiver);
+ }
+ updateView(downloadState, progress);
+ }
+ };
+
+ IntentFilter intFilt = new IntentFilter(String.valueOf(R.string.action));
+ registerReceiver(broadcastReceiver, intFilt);
+ }
+ }
+
+ void updateView(DownloadState state, int progress) {
+ if (state.titleResId == R.string.downloading) {
+ titleTextView.setText("Загрузка..." + " " + progress + "%");
} else {
- // Передаем в ранее запущенный таск текущий объект Activity
- downloadTask.attachActivity(this);
+ titleTextView.setText(state.titleResId);
}
+ progressBarView.setProgress(progress);
}
+
@Override
@SuppressWarnings("deprecation")
public Object onRetainNonConfigurationInstance() {
- // Этот метод вызывается при смене конфигурации, когда текущий объект
- // Activity уничтожается. Объект, который мы вернем, не будет уничтожен,
- // и его можно будет использовать в новом объекте Activity
- return downloadTask;
+ return broadcastReceiver;
}
- /**
- * Состояние загрузки в DownloadFileTask
- */
+
enum DownloadState {
DOWNLOADING(R.string.downloading),
DONE(R.string.done),
ERROR(R.string.error);
- // ID строкового ресурса для заголовка окна прогресса
final int titleResId;
DownloadState(int titleResId) {
@@ -81,106 +116,6 @@ enum DownloadState {
}
}
- /**
- * Таск, выполняющий скачивание файла в фоновом потоке.
- */
- static class DownloadFileTask extends AsyncTask
- implements ProgressCallback {
-
- // Context приложения (Не Activity!) для доступа к файлам
- private Context appContext;
- // Текущий объект Activity, храним для обновления отображения
- private InitSplashActivity activity;
-
- // Текущее состояние загрузки
- private DownloadState state = DownloadState.DOWNLOADING;
- // Прогресс загрузки от 0 до 100
- private int progress;
-
- DownloadFileTask(InitSplashActivity activity) {
- this.appContext = activity.getApplicationContext();
- this.activity = activity;
- }
-
- /**
- * Этот метод вызывается, когда новый объект Activity подключается к
- * данному таску после смены конфигурации.
- *
- * @param activity новый объект Activity
- */
- void attachActivity(InitSplashActivity activity) {
- this.activity = activity;
- updateView();
- }
-
- /**
- * Вызываем на UI потоке для обновления отображения прогресса и
- * состояния в текущей активности.
- */
- void updateView() {
- if (activity != null) {
- activity.titleTextView.setText(state.titleResId);
- activity.progressBarView.setProgress(progress);
- }
- }
-
- /**
- * Вызывается в UI потоке из execute() до начала выполнения таска.
- */
- @Override
- protected void onPreExecute() {
- updateView();
- }
-
- /**
- * Скачивание файла в фоновом потоке. Возвращает результат:
- * 0 -- если файл успешно скачался
- * 1 -- если произошла ошибка
- */
- @Override
- protected DownloadState doInBackground(Void... ignore) {
- try {
- downloadFile(appContext, this /*progressCallback*/);
- state = DownloadState.DONE;
-
- } catch (Exception e) {
- Log.e(TAG, "Error downloading file: " + e, e);
- state = DownloadState.ERROR;
- }
- return state;
- }
-
- // Метод ProgressCallback, вызывается в фоновом потоке из downloadFile
- @Override
- public void onProgressChanged(int progress) {
- publishProgress(progress);
- }
-
- // Метод AsyncTask, вызывается в UI потоке в результате вызова publishProgress
- @Override
- protected void onProgressUpdate(Integer... values) {
- if (values.length > 0) {
- int progress = values[values.length - 1];
- this.progress = progress;
- updateView();
- }
- }
-
- @Override
- protected void onPostExecute(DownloadState state) {
- // Проверяем код, который вернул doInBackground и показываем текст в зависимости
- // от результата
- this.state = state;
- if (state == DownloadState.DONE) {
- progress = 100;
- }
- updateView();
- }
- }
-
- /**
- * Скачивает список городов во временный файл.
- */
static void downloadFile(Context context,
ProgressCallback progressCallback) throws IOException {
File destFile = FileUtils.createTempExternalFile(context, "gz");
@@ -188,4 +123,4 @@ static void downloadFile(Context context,
}
private static final String TAG = "InitSplash";
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/ifmo/android_2015/homework5/ProgressCallback.java b/app/src/main/java/ru/ifmo/android_2015/homework5/ProgressCallback.java
index 0d26c5c..bbf6092 100644
--- a/app/src/main/java/ru/ifmo/android_2015/homework5/ProgressCallback.java
+++ b/app/src/main/java/ru/ifmo/android_2015/homework5/ProgressCallback.java
@@ -1,7 +1,7 @@
package ru.ifmo.android_2015.homework5;
/**
- * Callback интерфейс для получения уведомления о прогрессе.
+ * ProgressCallback интерфейс для получения уведомления о прогрессе.
*/
public interface ProgressCallback {
@@ -10,4 +10,5 @@ public interface ProgressCallback {
* @param progress новое значение прогресса от 0 до 100.
*/
void onProgressChanged(int progress);
+
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f501861..f6cebfe 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,6 +1,8 @@
- Example 2.4
+ Downloading
Загрузка…
Ошибка
Готово
+ ru.ifmo.android_2015.homework5
+
diff --git a/homework5-master.iml b/homework5-master.iml
new file mode 100644
index 0000000..7a5b5ba
--- /dev/null
+++ b/homework5-master.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file