dictionary loading progress is now displayed as a notification
This commit is contained in:
parent
0126e3db64
commit
b0c7f6b67f
17 changed files with 180 additions and 69 deletions
19
res/drawable-anydpi-v24/ic_notification.xml
Normal file
19
res/drawable-anydpi-v24/ic_notification.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#FFFFFF">
|
||||
<group android:scaleX="0.12126316"
|
||||
android:scaleY="0.12126316"
|
||||
android:translateX="0.96"
|
||||
android:translateY="1.5217317">
|
||||
<group android:translateY="135.80667">
|
||||
<path android:pathData="M82.375,-85.03125Q76.609375,-90.359375,70.140625,-90.359375L50.546875,-90.359375L50.546875,-13.84375Q50.546875,-9.953125,51.40625,-6.421875Q52.28125,-2.890625,54.296875,-0L30.8125,-0Q34.28125,-6.046875,34.28125,-13.84375L34.28125,-90.359375L12.96875,-90.359375Q8.5,-90.359375,3.171875,-85.03125L3.171875,-103L82.375,-103L82.375,-85.03125Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path android:pathData="M109.1875,-71.90625Q109.1875,-66.21875,109.90625,-62.5625Q110.625,-58.90625,112.28125,-56.78125Q113.9375,-54.671875,116.453125,-53.9375Q118.984375,-53.203125,122.578125,-53.203125L166.35938,-53.203125L166.35938,-75.421875Q166.35938,-80.09375,165.48438,-83.234375Q164.625,-86.390625,162.46875,-88.28125Q160.3125,-90.1875,156.78125,-90.984375Q153.25,-91.796875,147.92188,-91.796875L124.015625,-91.796875Q119.984375,-91.796875,117.171875,-90.84375Q114.375,-89.890625,112.5625,-87.625Q110.765625,-85.359375,109.96875,-81.5625Q109.1875,-77.765625,109.1875,-71.90625ZM114.515625,-22.84375Q113.796875,-21.71875,113.578125,-20.71875Q113.359375,-19.71875,113.359375,-17.3125Q113.359375,-14.1875,116.09375,-12.6875Q118.828125,-11.203125,126.609375,-11.203125L149.35938,-11.203125Q159.15625,-11.203125,162.75,-15.03125Q166.35938,-18.875,166.35938,-27.09375L166.35938,-42L113.65625,-42Q107.3125,-42,103.421875,-42.859375Q99.53125,-43.734375,97.21875,-46.046875Q94.921875,-48.375,94.125,-52.4375Q93.34375,-56.515625,93.34375,-62.90625L93.34375,-81.078125Q93.34375,-87.90625,94.203125,-92.1875Q95.078125,-96.46875,97.65625,-98.859375Q100.25,-101.265625,105.140625,-102.125Q110.046875,-103,118.109375,-103L157.57812,-103Q165.92188,-103,170.8125,-102.28125Q175.71875,-101.5625,178.3125,-99.390625Q180.90625,-97.234375,181.625,-93.484375Q182.34375,-89.75,182.34375,-83.703125L182.34375,-19.296875Q182.34375,-13.25,181.54688,-9.5Q180.76562,-5.765625,178.09375,-3.671875Q175.4375,-1.578125,170.3125,-0.78125Q165.20312,0,156.5625,0L114.65625,0Q109.046875,0,105.375,-0.84375Q101.703125,-1.703125,99.609375,-3.34375Q97.515625,-5,96.71875,-7.5625Q95.9375,-10.140625,95.9375,-13.578125Q95.9375,-17.28125,95.5,-19.203125Q95.078125,-21.140625,93.921875,-22.84375L114.515625,-22.84375Z"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
BIN
res/drawable-hdpi/ic_notification.png
Normal file
BIN
res/drawable-hdpi/ic_notification.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 412 B |
BIN
res/drawable-mdpi/ic_notification.png
Normal file
BIN
res/drawable-mdpi/ic_notification.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 283 B |
BIN
res/drawable-xhdpi/ic_notification.png
Normal file
BIN
res/drawable-xhdpi/ic_notification.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 470 B |
BIN
res/drawable-xxhdpi/ic_notification.png
Normal file
BIN
res/drawable-xxhdpi/ic_notification.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 693 B |
|
|
@ -18,10 +18,13 @@
|
|||
<string name="pref_truncatedict">Изтрий речник</string>
|
||||
|
||||
<string name="dictionary_import_bad_char">Неуспешно зареждане. Невалидна дума \"%1$s\" на ред %2$d за език \"%3$s\".</string>
|
||||
<string name="dictionary_import_cancelled">Зареждането на речник е отменено.</string>
|
||||
<string name="dictionary_import_error">Несупешно зареждане на речник за език \"%1$s\" (%2$s).</string>
|
||||
<string name="dictionary_loaded">Готово</string>
|
||||
<string name="dictionary_loading">Зареждане на речник (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Зареждане на вашия речник…</string>
|
||||
<string name="dictionary_load_title">Зареждане на речник</string>
|
||||
<string name="dictionary_not_found">Неуспешно зареждане. Липсва речник за \"%1$s\".</string>
|
||||
<string name="dictionary_truncated">Речникът е изтрит успешно</string>
|
||||
<string name="dictionary_truncated">Речникът е изтрит успешно.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
<string name="pref_truncatedict">Supprimer le dictionaire</string>
|
||||
|
||||
<string name="dictionary_import_error">Echec du chargement de dictionnaire pour langue «%1$s» (%2$s).</string>
|
||||
<string name="dictionary_import_cancelled">Chargement du dictionnaire annulée.</string>
|
||||
<string name="dictionary_loaded">Terminé</string>
|
||||
<string name="dictionary_loading">Chargement du dictionnaire (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Chargement du dictionnaire utilisateur…</string>
|
||||
<string name="dictionary_load_title">Charger le dictionnaire</string>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
<string name="pref_loaduserdict">Carica dizionario utente</string>
|
||||
<string name="pref_truncatedict">Eliminare il dizionario</string>
|
||||
|
||||
<string name="dictionary_import_cancelled">Caricamento dizionario annullato.</string>
|
||||
<string name="dictionary_loaded">Terminato</string>
|
||||
<string name="dictionary_loading">Caricamento dizionario (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Caricamento dizionario utente…</string>
|
||||
<string name="dictionary_load_title">Caricamento dizionario</string>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<string name="pref_loaddict">Woordenboek laden</string>
|
||||
<string name="pref_loaduserdict">Gebruikerswoordenboek laden</string>
|
||||
<string name="pref_truncatedict">Woordenboek wissen</string>
|
||||
<string name="dictionary_loading">Woordenboek laden…</string>
|
||||
<string name="dictionary_loading">Woordenboek laden (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Gebruikerswoordenboek laden…</string>
|
||||
<string name="dictionary_load_title">Woordenboek laden</string>
|
||||
<string name="dictionary_not_found">Laden mislukt. Woordenboek voor %1$s niet gevonden.</string>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
<string name="pref_loaduserdict">Загрузить свой словарь</string>
|
||||
<string name="pref_truncatedict">Очистить словарь</string>
|
||||
|
||||
<string name="dictionary_import_cancelled">Загрузка словаря отменена.</string>
|
||||
<string name="dictionary_import_error">Ошибка загрузки словаря для языка «%1$s» (%2$s).</string>
|
||||
<string name="dictionary_loaded">Завершена</string>
|
||||
<string name="dictionary_loading">Загрузка словаря (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Загрузка пользовательского словаря…</string>
|
||||
<string name="dictionary_load_title">Загрузить словарь</string>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
<string name="pref_loaduserdict">Завантажити свій словник</string>
|
||||
<string name="pref_truncatedict">Очистити словник</string>
|
||||
|
||||
<string name="dictionary_import_cancelled">Завантаження словника скасовано.</string>
|
||||
<string name="dictionary_import_error">Помилка завантаження словника для мови «%1$s» (%2$s).</string>
|
||||
<string name="dictionary_loaded">Завершено</string>
|
||||
<string name="dictionary_loading">Завантаження словника (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Завантаження словника користувача…</string>
|
||||
<string name="dictionary_load_title">Завантажити словник</string>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@
|
|||
<string name="pref_truncatedict">Clear dictionary</string>
|
||||
|
||||
<string name="dictionary_import_bad_char">Loading failed. Invalid word \"%1$s\" on line %2$d of language \"%3$s\".</string>
|
||||
<string name="dictionary_import_cancelled">Dictionary import cancelled.</string>
|
||||
<string name="dictionary_import_error">Failed importing dictionary for language \"%1$s\" (%2$s).</string>
|
||||
<string name="dictionary_loaded">Done</string>
|
||||
<string name="dictionary_loading">Loading dictionary (%1$s)…</string>
|
||||
<string name="dictionary_loading_user_dict">Loading user dictionary…</string>
|
||||
<string name="dictionary_load_title">Load dictionary</string>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package io.github.sspanak.tt9.db;
|
||||
|
||||
public class DictionaryImportAlreadyRunningException extends Exception{
|
||||
public DictionaryImportAlreadyRunningException() {
|
||||
super("Dictionary import is already running.");
|
||||
}
|
||||
}
|
||||
|
|
@ -23,11 +23,12 @@ public class DictionaryLoader {
|
|||
private final AssetManager assets;
|
||||
private final T9Preferences prefs;
|
||||
|
||||
private boolean isStopped = true;
|
||||
private final Pattern containsPunctuation = Pattern.compile("\\p{Punct}(?<!-)");
|
||||
private Thread loadThread;
|
||||
|
||||
private int currentFile = 0;
|
||||
private long lastProgressUpdate = 0;
|
||||
|
||||
private final Pattern containsPunctuation = Pattern.compile("\\p{Punct}(?<!-)");
|
||||
|
||||
public DictionaryLoader(Context context) {
|
||||
assets = context.getAssets();
|
||||
|
|
@ -35,27 +36,37 @@ public class DictionaryLoader {
|
|||
}
|
||||
|
||||
|
||||
public void load(Handler handler, ArrayList<Language> languages) {
|
||||
new Thread() {
|
||||
public void load(Handler handler, ArrayList<Language> languages) throws DictionaryImportAlreadyRunningException {
|
||||
if (isRunning()) {
|
||||
throw new DictionaryImportAlreadyRunningException();
|
||||
}
|
||||
|
||||
loadThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
currentFile = 0;
|
||||
isStopped = false;
|
||||
// SQLite does not support parallel queries, so let's import them one by one
|
||||
for (Language lang : languages) {
|
||||
if (isStopped) {
|
||||
if (isInterrupted()) {
|
||||
break;
|
||||
}
|
||||
importAll(handler, lang);
|
||||
currentFile++;
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
};
|
||||
|
||||
loadThread.start();
|
||||
}
|
||||
|
||||
|
||||
public void stop() {
|
||||
isStopped = true;
|
||||
loadThread.interrupt();
|
||||
}
|
||||
|
||||
|
||||
public boolean isRunning() {
|
||||
return loadThread != null && loadThread.isAlive();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -160,9 +171,9 @@ public class DictionaryLoader {
|
|||
sendProgressMessage(handler, language, 0, 0);
|
||||
|
||||
for (String word; (word = br.readLine()) != null; line++) {
|
||||
if (isStopped) {
|
||||
if (loadThread.isInterrupted()) {
|
||||
br.close();
|
||||
sendProgressMessage(handler, language, 0, 0);
|
||||
sendProgressMessage(handler, language, -1, 0);
|
||||
throw new DictionaryImportAbortedException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public class T9Preferences {
|
|||
|
||||
/************* internal settings *************/
|
||||
|
||||
public int getDictionaryImportProgressUpdateInterval() { return 100; /* ms */ }
|
||||
public int getDictionaryImportProgressUpdateInterval() { return 250; /* ms */ }
|
||||
public int getDictionaryImportWordChunkSize() { return 1000; /* words */ }
|
||||
public int getSuggestionsMax() { return 20; }
|
||||
public int getSuggestionsMin() { return 8; }
|
||||
|
|
|
|||
92
src/io/github/sspanak/tt9/ui/DictionaryLoadingBar.java
Normal file
92
src/io/github/sspanak/tt9/ui/DictionaryLoadingBar.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package io.github.sspanak.tt9.ui;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
|
||||
public class DictionaryLoadingBar {
|
||||
private static final int NOTIFICATION_ID = 1;
|
||||
private static final String NOTIFICATION_CHANNEL_ID = "loading-notifications";
|
||||
|
||||
private final NotificationManager manager;
|
||||
private final NotificationCompat.Builder notificationBuilder;
|
||||
private final Resources resources;
|
||||
|
||||
private int maxProgress = 0;
|
||||
|
||||
|
||||
DictionaryLoadingBar(Context context) {
|
||||
resources = context.getResources();
|
||||
|
||||
manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
manager.createNotificationChannel(new NotificationChannel(
|
||||
NOTIFICATION_CHANNEL_ID,
|
||||
"Dictionary Loading Channel",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
));
|
||||
notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||
} else {
|
||||
notificationBuilder = new NotificationCompat.Builder(context);
|
||||
}
|
||||
|
||||
notificationBuilder
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
|
||||
.setOnlyAlertOnce(true);
|
||||
}
|
||||
|
||||
|
||||
private String generateTitle(int languageId) {
|
||||
Language lang = LanguageCollection.getLanguage(languageId);
|
||||
|
||||
if (lang != null) {
|
||||
return resources.getString(R.string.dictionary_loading, lang.getName());
|
||||
}
|
||||
|
||||
return resources.getString(R.string.dictionary_load_title);
|
||||
}
|
||||
|
||||
|
||||
public void show(int currentFile, int currentFileProgress, int languageId) {
|
||||
int totalProgress = 100 * currentFile + currentFileProgress;
|
||||
|
||||
if (currentFileProgress < 0) {
|
||||
hide();
|
||||
return;
|
||||
} else if (totalProgress >= maxProgress) {
|
||||
notificationBuilder
|
||||
.setContentTitle(generateTitle(-1))
|
||||
.setContentText(resources.getString(R.string.dictionary_loaded))
|
||||
.setOngoing(false)
|
||||
.setProgress(0, 0, false);
|
||||
} else {
|
||||
notificationBuilder
|
||||
.setContentTitle(generateTitle(languageId))
|
||||
.setContentText(currentFileProgress + "%")
|
||||
.setOngoing(true)
|
||||
.setProgress(maxProgress, totalProgress, false);
|
||||
}
|
||||
|
||||
manager.notify(NOTIFICATION_ID, notificationBuilder.build());
|
||||
}
|
||||
|
||||
|
||||
public void hide() {
|
||||
manager.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
|
||||
public void setFileCount(int count) {
|
||||
maxProgress = count * 100;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package io.github.sspanak.tt9.ui;
|
|||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ListActivity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
|
|
@ -21,6 +20,7 @@ import java.util.ArrayList;
|
|||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.db.DictionaryDb;
|
||||
import io.github.sspanak.tt9.db.DictionaryImportAlreadyRunningException;
|
||||
import io.github.sspanak.tt9.db.DictionaryImportException;
|
||||
import io.github.sspanak.tt9.db.DictionaryLoader;
|
||||
import io.github.sspanak.tt9.languages.InvalidLanguageCharactersException;
|
||||
|
|
@ -35,7 +35,7 @@ import io.github.sspanak.tt9.settings_legacy.SettingAdapter;
|
|||
public class TraditionalT9Settings extends ListActivity implements DialogInterface.OnCancelListener {
|
||||
|
||||
private DictionaryLoader loader;
|
||||
ProgressDialog progressDialog;
|
||||
DictionaryLoadingBar progressBar;
|
||||
|
||||
Context mContext = null;
|
||||
|
||||
|
|
@ -43,8 +43,7 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// maybe need this?
|
||||
// http://stackoverflow.com/questions/7645880/listview-with-onitemclicklistener-android
|
||||
progressBar = new DictionaryLoadingBar(this);
|
||||
|
||||
// get settings
|
||||
T9Preferences prefs = new T9Preferences(getApplicationContext());
|
||||
|
|
@ -98,18 +97,22 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
|||
}
|
||||
|
||||
private void truncateWords() {
|
||||
Handler afterTruncate = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
UI.toast(mContext, R.string.dictionary_truncated);
|
||||
}
|
||||
};
|
||||
DictionaryDb.truncateWords(afterTruncate);
|
||||
if (loader != null && loader.isRunning()) {
|
||||
loader.stop();
|
||||
}
|
||||
|
||||
Handler afterTruncate = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
UI.toast(mContext, R.string.dictionary_truncated);
|
||||
}
|
||||
};
|
||||
DictionaryDb.truncateWords(afterTruncate);
|
||||
}
|
||||
|
||||
private void loadDictionaries() {
|
||||
ArrayList<Language> languages = LanguageCollection.getAll(T9Preferences.getInstance().getEnabledLanguages());
|
||||
initProgress(100 * languages.size());
|
||||
progressBar.setFileCount(languages.size());
|
||||
|
||||
Handler loadHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
|
|
@ -117,7 +120,7 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
|||
String error = msg.getData().getString("error", null);
|
||||
|
||||
if (error != null) {
|
||||
hideProgress();
|
||||
progressBar.hide();
|
||||
handleError(
|
||||
error,
|
||||
msg.getData().getInt("languageId", -1),
|
||||
|
|
@ -125,58 +128,24 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
|||
msg.getData().getString("word", "")
|
||||
);
|
||||
} else {
|
||||
int langId = msg.getData().getInt("languageId", -1);
|
||||
Language lang = LanguageCollection.getLanguage(langId);
|
||||
String langName = lang != null ? lang.getName() : "???";
|
||||
|
||||
String title = getResources().getString(R.string.dictionary_loading, langName);
|
||||
showProgress(
|
||||
progressBar.show(
|
||||
msg.getData().getInt("currentFile", 0),
|
||||
msg.getData().getInt("progress", 0),
|
||||
title
|
||||
msg.getData().getInt("languageId", -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loader = new DictionaryLoader(this);
|
||||
loader.load(loadHandler, languages);
|
||||
}
|
||||
|
||||
|
||||
private void initProgress(int max) {
|
||||
if (progressDialog == null) {
|
||||
progressDialog = new ProgressDialog(this);
|
||||
progressDialog.setOnCancelListener(TraditionalT9Settings.this);
|
||||
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
if (loader == null) {
|
||||
loader = new DictionaryLoader(this);
|
||||
}
|
||||
|
||||
progressDialog.setMax(max);
|
||||
}
|
||||
|
||||
private void showProgress(int currentFile, int currentFileProgress, String title) {
|
||||
if (progressDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (title != null) {
|
||||
progressDialog.setMessage(title);
|
||||
}
|
||||
|
||||
int totalProgress = 100 * currentFile + currentFileProgress;
|
||||
if (totalProgress <= 0 || totalProgress >= progressDialog.getMax()) {
|
||||
progressDialog.dismiss();
|
||||
} else {
|
||||
progressDialog.setProgress(totalProgress);
|
||||
if (!progressDialog.isShowing()) {
|
||||
progressDialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideProgress() {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
try {
|
||||
loader.load(loadHandler, languages);
|
||||
} catch (DictionaryImportAlreadyRunningException e) {
|
||||
loader.stop();
|
||||
UI.toast(this, getString(R.string.dictionary_import_cancelled));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue