diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7619236
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
+### Android template
+# Files for the Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Created by .ignore support plugin (hsz.mobi)
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..c833642
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+homework5
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..9a8b7e5
--- /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..8d2df47
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/appcompat_v7_23_0_1.xml b/.idea/libraries/appcompat_v7_23_0_1.xml
new file mode 100644
index 0000000..7898213
--- /dev/null
+++ b/.idea/libraries/appcompat_v7_23_0_1.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/support_annotations_23_0_1.xml b/.idea/libraries/support_annotations_23_0_1.xml
new file mode 100644
index 0000000..4b8b4ab
--- /dev/null
+++ b/.idea/libraries/support_annotations_23_0_1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/support_v4_23_0_1.xml b/.idea/libraries/support_v4_23_0_1.xml
new file mode 100644
index 0000000..f35583b
--- /dev/null
+++ b/.idea/libraries/support_v4_23_0_1.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..95f0f03
--- /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..384adf8
--- /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..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..231bdf9
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,2002 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ localhost
+ 5050
+
+
+
+
+
+
+ 1451251915537
+
+ 1451251915537
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..63a8c51
--- /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..2ae00ab 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,6 +18,9 @@
+
+
diff --git a/app/src/main/java/ru/ifmo/android_2015/homework5/Downloader.java b/app/src/main/java/ru/ifmo/android_2015/homework5/Downloader.java
new file mode 100644
index 0000000..c9479a9
--- /dev/null
+++ b/app/src/main/java/ru/ifmo/android_2015/homework5/Downloader.java
@@ -0,0 +1,79 @@
+package ru.ifmo.android_2015.homework5;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.support.v4.content.LocalBroadcastManager;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Created by anton on 28/12/15.
+ */
+public class Downloader extends IntentService implements ProgressCallback {
+
+ public static final String ACTION_DOWNLOAD = "ru.ifmo.android_2015.homework5.action.DOWNLOAD";
+ public static final String BROADCAST_ACTION = "ru.ifmo.android_2015.homework5.action.BROADCAST";
+ public static final String PARAM_URL = "ru.ifmo.android_2015.homework5.extra.URL";
+ public static final String PARAM_TITLE = "ru.ifmo.android_2015.homework5.extra.TITLE";
+ public static final String PARAM_PROGRESS = "ru.ifmo.android_2015.homework5.extra.PROGRESS";
+
+ private int progress;
+ private DownloadState downloadState;
+
+ public Downloader() {
+ super("Downloader");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ if (intent == null) {
+ return;
+ }
+
+ final String action = intent.getAction();
+ if(action.equals(ACTION_DOWNLOAD)) {
+ final String paramURL = intent.getStringExtra(PARAM_URL);
+ this.downloadState = DownloadState.DOWNLOADING;
+ progress = 0;
+ broadcastProgress();
+ try {
+ File destination = FileUtils.createTempExternalFile(this, ".gz");
+ DownloadUtils.downloadFile(paramURL, destination, this);
+ } catch (IOException e) {
+ this.downloadState = DownloadState.FAILED;
+ broadcastProgress();
+ return;
+ }
+ this.downloadState = DownloadState.COMPLETED;
+ this.progress = 100;
+ broadcastProgress();
+ }
+ }
+
+ @Override
+ public void onProgressChanged(int progress) {
+ this.progress = progress;
+ broadcastProgress();
+ }
+
+ private void broadcastProgress() {
+ Intent intent = new Intent(BROADCAST_ACTION);
+ intent.putExtra(PARAM_TITLE, this.downloadState.titleResID);
+ intent.putExtra(PARAM_PROGRESS, this.progress);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+
+ enum DownloadState {
+ DOWNLOADING(R.string.downloading),
+ COMPLETED(R.string.done),
+ FAILED(R.string.error);
+
+ final int titleResID;
+
+ DownloadState(int titleResID) {
+ this.titleResID = titleResID;
+ }
+
+ }
+}
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..2b48c9d 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,9 +1,14 @@
package ru.ifmo.android_2015.homework5;
import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -23,12 +28,12 @@ public class InitSplashActivity extends Activity {
private static final String CITIES_GZ_URL =
"https://www.dropbox.com/s/d99ky6aac6upc73/city_array.json.gz?dl=1";
+ private static final String TITLE = "TITLE";
// Индикатор прогресса
private ProgressBar progressBarView;
// Заголовок
private TextView titleTextView;
- // Выполняющийся таск загрузки файла
- private DownloadFileTask downloadTask;
+ private BroadcastReceiver receiver;
@Override
@SuppressWarnings("deprecation")
@@ -43,149 +48,68 @@ protected void onCreate(Bundle savedInstanceState) {
progressBarView.setMax(100);
if (savedInstanceState != null) {
- // Пытаемся получить ранее запущенный таск
- downloadTask = (DownloadFileTask) getLastNonConfigurationInstance();
+ Log.d(TAG, "Service has started");
}
- if (downloadTask == null) {
- // Создаем новый таск, только если не было ранее запущенного таска
- downloadTask = new DownloadFileTask(this);
- downloadTask.execute();
- } else {
- // Передаем в ранее запущенный таск текущий объект Activity
- downloadTask.attachActivity(this);
+ else if (!isRunning(Downloader.class)) {
+ Log.d(TAG, "Download started");
+ Intent intent = new Intent(this, Downloader.class);
+ intent.setAction(Downloader.ACTION_DOWNLOAD);
+ intent.putExtra(Downloader.PARAM_URL, CITIES_GZ_URL);
+ startService(intent);
}
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public Object onRetainNonConfigurationInstance() {
- // Этот метод вызывается при смене конфигурации, когда текущий объект
- // Activity уничтожается. Объект, который мы вернем, не будет уничтожен,
- // и его можно будет использовать в новом объекте Activity
- return downloadTask;
- }
-
- /**
- * Состояние загрузки в DownloadFileTask
- */
- enum DownloadState {
- DOWNLOADING(R.string.downloading),
- DONE(R.string.done),
- ERROR(R.string.error);
-
- // ID строкового ресурса для заголовка окна прогресса
- final int titleResId;
-
- DownloadState(int titleResId) {
- this.titleResId = titleResId;
- }
- }
-
- /**
- * Таск, выполняющий скачивание файла в фоновом потоке.
- */
- 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;
+ else {
+ Log.d(TAG, "Waiting for runnig service to finish");
}
-
- /**
- * Этот метод вызывается, когда новый объект 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);
+ receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateView(intent);
}
- }
+ };
+ IntentFilter filter = new IntentFilter(Downloader.BROADCAST_ACTION);
+ LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
+ }
- /**
- * Вызывается в UI потоке из execute() до начала выполнения таска.
- */
- @Override
- protected void onPreExecute() {
- updateView();
+ private void updateView(Intent intent) {
+ if (intent == null) {
+ return;
}
+ final int titleID = intent.getIntExtra(Downloader.PARAM_TITLE, 0);
+ final int progress = intent.getIntExtra(Downloader.PARAM_PROGRESS, 0);
+ titleTextView.setText(titleID);
+ progressBarView.setProgress(progress);
+ }
- /**
- * Скачивание файла в фоновом потоке. Возвращает результат:
- * 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;
- }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString(TITLE, titleTextView.getText().toString());
+ super.onSaveInstanceState(outState);
+ }
- // Метод ProgressCallback, вызывается в фоновом потоке из downloadFile
- @Override
- public void onProgressChanged(int progress) {
- publishProgress(progress);
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ if (savedInstanceState != null) {
+ String s = savedInstanceState.getString(TITLE);
+ titleTextView.setText(s);
}
+ }
- // Метод 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 onDestroy() {
+ Log.d(TAG, "Destroy");
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
+ super.onDestroy();
+ }
- @Override
- protected void onPostExecute(DownloadState state) {
- // Проверяем код, который вернул doInBackground и показываем текст в зависимости
- // от результата
- this.state = state;
- if (state == DownloadState.DONE) {
- progress = 100;
+ private boolean isRunning(Class> service) {
+ ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+ for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
+ if (service.getName().equals(serviceInfo.service.getClassName())) {
+ return true;
}
- updateView();
}
+ return false;
}
-
- /**
- * Скачивает список городов во временный файл.
- */
- static void downloadFile(Context context,
- ProgressCallback progressCallback) throws IOException {
- File destFile = FileUtils.createTempExternalFile(context, "gz");
- DownloadUtils.downloadFile(CITIES_GZ_URL, destFile, progressCallback);
- }
-
private static final String TAG = "InitSplash";
}
diff --git a/homework5.iml b/homework5.iml
new file mode 100644
index 0000000..ca2428e
--- /dev/null
+++ b/homework5.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file