Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F13272623
D225.1777378743.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
43 KB
Referenced Files
None
Subscribers
None
D225.1777378743.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/ActivityIntro.kt b/app/src/main/java/it/reyboz/bustorino/ActivityIntro.kt
--- a/app/src/main/java/it/reyboz/bustorino/ActivityIntro.kt
+++ b/app/src/main/java/it/reyboz/bustorino/ActivityIntro.kt
@@ -14,6 +14,7 @@
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
+import it.reyboz.bustorino.data.DBUpdateCheckWorker
import it.reyboz.bustorino.data.PreferencesHolder
import it.reyboz.bustorino.fragments.IntroFragment
import it.reyboz.bustorino.middleware.GeneralActivity
@@ -31,7 +32,8 @@
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_intro)
-
+ //check default settings and apply them
+ checkApplyDefaultSettingsValues()
viewPager = findViewById(R.id.viewPager)
btnBackward = findViewById(R.id.btnPrevious)
btnForward = findViewById(R.id.btnNext)
@@ -104,6 +106,9 @@
findViewById<View>(R.id.theConstraintLayout),
this.applyBottomAndBordersInsetsListener
)
+ // Start the DB Update now
+ DBUpdateCheckWorker.schedulePeriodicCheck(this, true)
+
}
diff --git a/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java b/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java
--- a/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java
+++ b/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java
@@ -29,6 +29,7 @@
import android.view.*;
import android.widget.Toast;
+import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
@@ -41,19 +42,15 @@
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceManager;
import androidx.work.WorkInfo;
-import androidx.work.WorkManager;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
import it.reyboz.bustorino.backend.Stop;
-import it.reyboz.bustorino.backend.utils;
+import it.reyboz.bustorino.data.DBUpdateCheckWorker;
import it.reyboz.bustorino.data.DBUpdateWorker;
-import it.reyboz.bustorino.data.DatabaseUpdate;
import it.reyboz.bustorino.data.PreferencesHolder;
import it.reyboz.bustorino.data.gtfs.GtfsDatabase;
import it.reyboz.bustorino.fragments.*;
@@ -74,6 +71,13 @@
private boolean showingMainFragmentFromOther = false;
private boolean onCreateComplete = false;
+ private final OnBackPressedCallback callback = new OnBackPressedCallback(false) {
+ @Override
+ public void handleOnBackPressed() {
+ activityCustomBackPressed();
+ }
+ };
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -84,6 +88,10 @@
getWindow().setNavigationBarContrastEnforced(false);
}
*/
+
+ //onBackPressed solution required from Android 16
+ callback.setEnabled(true);
+ this.getOnBackPressedDispatcher().addCallback( callback);
boolean showingArrivalsFromIntent = false;
final Toolbar mToolbar = findViewById(R.id.default_toolbar);
@@ -184,31 +192,15 @@
showingArrivalsFromIntent = true;
}
//database check
- GtfsDatabase gtfsDB = GtfsDatabase.Companion.getGtfsDatabase(this);
-
- final int db_version = gtfsDB.getOpenHelper().getReadableDatabase().getVersion();
- boolean dataUpdateRequested = false;
- final SharedPreferences theShPr = getMainSharedPreferences();
-
- final int old_version = PreferencesHolder.getGtfsDBVersion(theShPr);
- Log.d(DEBUG_TAG, "GTFS Database: old version is "+old_version+ ", new version is "+db_version);
- if (old_version < db_version){
- //decide update conditions in the future
- if(old_version < 2 && db_version >= 2) {
- dataUpdateRequested = true;
- DatabaseUpdate.requestDBUpdateWithWork(this, true, true);
- }
- PreferencesHolder.setGtfsDBVersion(theShPr, db_version);
- }
- //Try (hopefully) database update
+ // THIS CHECK IS DUPLICATED, TODO: REMOVE
+ final boolean dataUpdateRequested = checkIfNeedSpecialUpgradeDB();
if(!dataUpdateRequested)
- DatabaseUpdate.requestDBUpdateWithWork(this, false, false);
-
+ // DatabaseUpdate.requestDBUpdateWithWork(this, false, false);
+ DBUpdateCheckWorker.Companion.schedulePeriodicCheck(this,false);
/*
Watch for database update
*/
- final WorkManager workManager = WorkManager.getInstance(this);
- workManager.getWorkInfosForUniqueWorkLiveData(DBUpdateWorker.DEBUG_TAG)
+ DBUpdateWorker.getWorkInfoLiveData(this)
.observe(this, workInfoList -> {
// If there are no matching work info, do nothing
if (workInfoList == null || workInfoList.isEmpty()) {
@@ -223,7 +215,6 @@
break;
}
}
-
if (showProgress) {
createDefaultSnackbar();
} else {
@@ -258,7 +249,7 @@
onCreateComplete = true;
//last but not least, set the good default values
- setDefaultSettingsValuesWhenMissing();
+ checkApplyDefaultSettingsValues();
// handle the device "insets"
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.rootRelativeLayout), (v, windowInsets) -> {
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
@@ -308,7 +299,10 @@
}
+
+
//check if first run activity (IntroActivity) has been started once or not
+ final SharedPreferences theShPr = getMainSharedPreferences();
boolean hasIntroRun = theShPr.getBoolean(PreferencesHolder.PREF_INTRO_ACTIVITY_RUN,false);
if(!hasIntroRun){
startIntroductionActivity();
@@ -321,6 +315,27 @@
}
+ private boolean checkIfNeedSpecialUpgradeDB(){
+ final GtfsDatabase gtfsDB = GtfsDatabase.Companion.getGtfsDatabase(this);
+
+ final int db_version = gtfsDB.getOpenHelper().getReadableDatabase().getVersion();
+ boolean dataUpdateRequested = false;
+ final SharedPreferences theShPr = getMainSharedPreferences();
+
+ final int old_version = PreferencesHolder.getGtfsDBVersion(theShPr);
+ Log.d(DEBUG_TAG, "GTFS Database: old version is "+old_version+ ", new version is "+db_version);
+ if (old_version < db_version){
+ //decide update conditions in the future
+ if(old_version < 2 && db_version >= 2) {
+ dataUpdateRequested = true;
+ DBUpdateWorker.requestDBUpdateUniqueWork(this, true);
+ }
+ PreferencesHolder.setGtfsDBVersion(theShPr, db_version);
+ }
+
+ return dataUpdateRequested;
+ }
+
/**
* Setup drawer actions
* @param navigationView the navigation view on which to set the callbacks
@@ -450,9 +465,16 @@
}
- @Override
+ /*@Override
public void onBackPressed() {
- boolean foundFragment = false;
+ if (!activityCustomBackPressed())
+ super.onBackPressed();
+ }
+
+ */
+
+ private boolean activityCustomBackPressed(){
+ boolean resolved = true;
Fragment shownFrag = getSupportFragmentManager().findFragmentById(R.id.mainActContentFrame);
if (mDrawer.isDrawerOpen(GravityCompat.START))
mDrawer.closeDrawer(GravityCompat.START);
@@ -472,12 +494,15 @@
getSupportFragmentManager().popBackStack();
Log.d(DEBUG_TAG, "Popping main frame backstack for fragments");
}
- else
- super.onBackPressed();
+ else{
+ resolved = false;
+ }
+ return resolved;
}
/**
* Create and show the SnackBar with the message
+ * The fragment shown points to which view to attach the snackbar
*/
private void createDefaultSnackbar() {
@@ -821,45 +846,4 @@
}
}
- /**
- * Adjust setting to match the default ones
- */
- private void setDefaultSettingsValuesWhenMissing(){
- SharedPreferences mainSharedPref = PreferenceManager.getDefaultSharedPreferences(this);
- SharedPreferences.Editor editor = mainSharedPref.edit();
- //Main fragment to show
- String screen = mainSharedPref.getString(SettingsFragment.PREF_KEY_STARTUP_SCREEN, "");
- boolean edit = false;
- if (screen.isEmpty()){
- editor.putString(SettingsFragment.PREF_KEY_STARTUP_SCREEN, "arrivals");
- edit=true;
- }
- //Fetchers
- final Set<String> setSelected = mainSharedPref.getStringSet(SettingsFragment.KEY_ARRIVALS_FETCHERS_USE, new HashSet<>());
- if (setSelected.isEmpty()){
- String[] defaultVals = getResources().getStringArray(R.array.arrivals_sources_values_default);
- editor.putStringSet(SettingsFragment.KEY_ARRIVALS_FETCHERS_USE, utils.convertArrayToSet(defaultVals));
- edit=true;
- }
- //Live bus positions
- final String keySourcePositions=getString(R.string.pref_positions_source);
- final String positionsSource = mainSharedPref.getString(keySourcePositions, "");
- if(positionsSource.isEmpty()){
- String[] defaultVals = getResources().getStringArray(R.array.positions_source_values);
- editor.putString(keySourcePositions, defaultVals[0]);
- edit=true;
- }
- //Map style
- final String mapStylePref = mainSharedPref.getString(SettingsFragment.LIBREMAP_STYLE_PREF_KEY, "");
- if(mapStylePref.isEmpty()){
- final String[] defaultVals = getResources().getStringArray(R.array.map_style_pref_values);
- editor.putString(SettingsFragment.LIBREMAP_STYLE_PREF_KEY, defaultVals[0]);
- edit=true;
- }
- if (edit){
- editor.commit();
- }
-
-
- }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java b/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
@@ -93,7 +93,7 @@
manager.cancel(notificationID);
}
- public static void createDBNotificationChannel(Context context){
+ public static void createDBNotificationChannelIfNeeded(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
Notifications.DB_UPDATE_CHANNELS_ID,
diff --git a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateCheckWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateCheckWorker.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateCheckWorker.kt
@@ -0,0 +1,78 @@
+/*
+ BusTO - Data components
+ Copyright (C) 2021-2026 Fabio Mazza
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package it.reyboz.bustorino.data
+
+import android.content.Context
+import android.util.Log
+import androidx.work.*
+import java.util.concurrent.TimeUnit
+
+/**
+ * Lightweight periodic worker that checks local state and enqueues [DBUpdateWorker]
+ * only when an update is actually needed, without making any network calls itself.
+ */
+class DBUpdateCheckWorker(context: Context, workerParams: WorkerParameters)
+ : CoroutineWorker(context, workerParams) {
+
+ override suspend fun doWork(): Result {
+ val con = applicationContext
+ val sharedPrefs = PreferencesHolder.getMainSharedPreferences(con)
+
+ val currentDBVersion = sharedPrefs.getInt(PreferencesHolder.DB_GTT_VERSION_KEY, -10)
+ val lastDBUpdateTime = sharedPrefs.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, 0L)
+ val currentTime = System.currentTimeMillis() / 1000
+
+ val neverUpdated = currentDBVersion < 0 || lastDBUpdateTime <= 0
+ val timeElapsed = currentTime > lastDBUpdateTime + UPDATE_MIN_DELAY
+
+ if (neverUpdated || timeElapsed) {
+ Log.d(DEBUG_TAG, "Scheduling DBUpdateWorker")
+ DBUpdateWorker.requestDBUpdateUniqueWork(con, forced = true)
+ } else {
+ Log.d(DEBUG_TAG, "No update needed")
+ }
+
+ return Result.success()
+ }
+
+ companion object {
+ const val DEBUG_TAG = "BusTO-DBUpdateScheduler"
+ const val WORK_NAME = "DBUpdateChecker"
+
+ private const val UPDATE_MIN_DELAY = (3 * 24 * 3600L) //
+
+ fun schedulePeriodicCheck(context: Context, restart: Boolean = false) {
+ val workRequest = PeriodicWorkRequest.Builder(
+ DBUpdateCheckWorker::class.java, 1, TimeUnit.DAYS
+ )
+ .setConstraints(
+ Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .build()
+ )
+ .build()
+
+ val policy = if (restart) ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE
+ else ExistingPeriodicWorkPolicy.KEEP
+
+ WorkManager.getInstance(context)
+ .enqueueUniquePeriodicWork(WORK_NAME, policy, workRequest)
+ }
+
+ }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java
deleted file mode 100644
--- a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- BusTO - Data components
- Copyright (C) 2021 Fabio Mazza
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-package it.reyboz.bustorino.data;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationManagerCompat;
-import androidx.work.*;
-import it.reyboz.bustorino.R;
-import it.reyboz.bustorino.backend.Fetcher;
-import it.reyboz.bustorino.backend.Notifications;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static android.content.Context.MODE_PRIVATE;
-
-//TODO: Move to code to Kotlin
-public class DBUpdateWorker extends Worker{
-
-
- public static final String ERROR_CODE_KEY ="Error_Code";
- public static final String ERROR_REASON_KEY = "ERROR_REASON";
- public static final int ERROR_FETCHING_VERSION = 4;
- public static final int ERROR_DOWNLOADING_STOPS = 5;
- public static final int ERROR_DOWNLOADING_LINES = 6;
- public static final int ERROR_CODE_DB_CLOSED=-2;
-
- public static final String SUCCESS_REASON_KEY = "SUCCESS_REASON";
- public static final int SUCCESS_NO_ACTION_NEEDED = 9;
- public static final int SUCCESS_UPDATE_DONE = 1;
-
- private final static int NOTIFIC_ID =32198;
-
- public static final String FORCED_UPDATE = "FORCED-UPDATE";
-
- public static final String DEBUG_TAG = "Busto-UpdateWorker";
-
- private static final long UPDATE_MIN_DELAY= 9*24*3600; //9 days
-
-
- public DBUpdateWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
- super(context, workerParams);
- }
-
- @SuppressLint("RestrictedApi")
- @NonNull
- @Override
- public Result doWork() {
- //register Notification channel
- final Context con = getApplicationContext();
- //Notifications.createDefaultNotificationChannel(con);
- //Use the new notification channels
- Notifications.createNotificationChannel(con,con.getString(R.string.database_notification_channel),
- con.getString(R.string.database_notification_channel_desc), NotificationManagerCompat.IMPORTANCE_LOW,
- Notifications.DB_UPDATE_CHANNELS_ID
- );
- final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
- final int notification_ID = 32198;
- final SharedPreferences shPr = con.getSharedPreferences(con.getString(R.string.mainSharedPreferences),MODE_PRIVATE);
- final int current_DB_version = shPr.getInt(PreferencesHolder.DB_GTT_VERSION_KEY,-10);
-
- final int new_DB_version = DatabaseUpdate.getNewVersion();
-
- final boolean isUpdateCompulsory = getInputData().getBoolean(FORCED_UPDATE,false);
-
- final long lastDBUpdateTime = shPr.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, 0);
- long currentTime = System.currentTimeMillis()/1000;
-
- //showNotification(notificationManager, notification_ID);
- final NotificationCompat.Builder builder = new NotificationCompat.Builder(con,
- Notifications.DB_UPDATE_CHANNELS_ID)
- .setContentTitle(con.getString(R.string.database_update_msg_notif))
- .setProgress(0,0,true)
- .setPriority(NotificationCompat.PRIORITY_LOW);
- builder.setSmallIcon(R.drawable.ic_bus_stilized);
-
-
- notificationManager.notify(notification_ID,builder.build());
-
- Log.d(DEBUG_TAG, "Have previous version: "+current_DB_version +" and new version "+new_DB_version);
- Log.d(DEBUG_TAG, "Update compulsory: "+isUpdateCompulsory);
- /*
- SKIP CHECK (Reason: The Old API might fail at any moment)
- if (new_DB_version < 0){
- //there has been an error
- final Data out = new Data.Builder().putInt(ERROR_REASON_KEY, ERROR_FETCHING_VERSION)
- .putInt(ERROR_CODE_KEY,new_DB_version).build();
- cancelNotification(notificationID);
- return ListenableWorker.Result.failure(out);
- }
- */
-
- //we got a good version
- if (!(current_DB_version < new_DB_version || currentTime > lastDBUpdateTime + UPDATE_MIN_DELAY )
- && !isUpdateCompulsory) {
- //don't need to update
- cancelNotification(notification_ID);
- return ListenableWorker.Result.success(new Data.Builder().
- putInt(SUCCESS_REASON_KEY, SUCCESS_NO_ACTION_NEEDED).build());
- }
- //start the real update
- AtomicReference<Fetcher.Result> resultAtomicReference = new AtomicReference<>();
- DatabaseUpdate.setDBUpdatingFlag(con, shPr,true);
- final DatabaseUpdate.Result resultUpdate = DatabaseUpdate.performDBUpdate(con,resultAtomicReference);
- DatabaseUpdate.setDBUpdatingFlag(con, shPr,false);
-
- if (resultUpdate != DatabaseUpdate.Result.DONE){
- //Fetcher.Result result = resultAtomicReference.get();
- final Data.Builder dataBuilder = new Data.Builder();
- switch (resultUpdate){
- case ERROR_STOPS_DOWNLOAD:
- dataBuilder.put(ERROR_REASON_KEY, ERROR_DOWNLOADING_STOPS);
- break;
- case ERROR_LINES_DOWNLOAD:
- dataBuilder.put(ERROR_REASON_KEY, ERROR_DOWNLOADING_LINES);
- break;
- case DB_CLOSED:
- dataBuilder.put(ERROR_REASON_KEY, ERROR_CODE_DB_CLOSED);
- break;
- }
- cancelNotification(notification_ID);
- return ListenableWorker.Result.failure(dataBuilder.build());
- }
- Log.d(DEBUG_TAG, "Update finished successfully!");
- //update the version in the shared preference
- final SharedPreferences.Editor editor = shPr.edit();
- editor.putInt(PreferencesHolder.DB_GTT_VERSION_KEY, new_DB_version);
- currentTime = System.currentTimeMillis()/1000;
- editor.putLong(PreferencesHolder.DB_LAST_UPDATE_KEY, currentTime);
- editor.apply();
- cancelNotification(notification_ID);
-
- return ListenableWorker.Result.success(new Data.Builder().putInt(SUCCESS_REASON_KEY, SUCCESS_UPDATE_DONE).build());
- }
-
- public static Constraints getWorkConstraints(){
- return new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
- .setRequiresCharging(false).build();
- }
-
- public static WorkRequest newFirstTimeWorkRequest(){
- return new OneTimeWorkRequest.Builder(DBUpdateWorker.class)
- .setBackoffCriteria(BackoffPolicy.LINEAR, 15, TimeUnit.SECONDS)
- //.setInputData(new Data.Builder().putBoolean())
- .build();
- }
-
- /*
- private int showNotification(@NonNull final NotificationManagerCompat notificManager, final int notification_ID,
- final String channel_ID){
- final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), channel_ID)
- .setContentTitle("Libre BusTO - Updating Database")
- .setProgress(0,0,true)
- .setPriority(NotificationCompat.PRIORITY_LOW);
- builder.setSmallIcon(R.drawable.ic_bus_orange);
-
-
- notificManager.notify(notification_ID,builder.build());
-
- return notification_ID;
- }
- */
-
- private void cancelNotification(int notificationID){
- final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
-
- notificationManager.cancel(notificationID);
- }
-}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.kt
@@ -0,0 +1,205 @@
+/*
+ BusTO - Data components
+ Copyright (C) 2021-2026 Fabio Mazza
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package it.reyboz.bustorino.data
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.pm.ServiceInfo
+import android.os.Build
+import android.util.Log
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.lifecycle.LiveData
+import androidx.work.*
+import androidx.work.WorkManager.Companion.getInstance
+import it.reyboz.bustorino.R
+import it.reyboz.bustorino.backend.Fetcher
+import it.reyboz.bustorino.backend.Notifications
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * Worker class that runs the DB update, without checking if it is needed or not
+ */
+class DBUpdateWorker(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) {
+
+ @SuppressLint("RestrictedApi")
+ override suspend fun doWork(): Result {
+ val con = applicationContext
+ val sharedPrefs = con.getSharedPreferences(con.getString(R.string.mainSharedPreferences), Context.MODE_PRIVATE)
+ val newDBVersion = DatabaseUpdate.getNewVersion()
+
+ /*val currentDBVersion = sharedPrefs.getInt(PreferencesHolder.DB_GTT_VERSION_KEY, -10)
+
+ val isUpdateCompulsory = inputData.getBoolean(FORCED_UPDATE, false)
+
+ val lastDBUpdateTime = sharedPrefs.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, 0)
+ var currentTime = System.currentTimeMillis() / 1000
+
+ // ---- RECREATE NOTIFICATION HERE IF YOU WANT TO SHOW IT TO THE USER ----
+ // ---- create notification channel first
+ Log.d(DEBUG_TAG, "Have previous version: $currentDBVersion and new version $newDBVersion")
+ Log.d(DEBUG_TAG, "Update compulsory: $isUpdateCompulsory")
+
+
+ //we got a good version
+ if (!(currentDBVersion < newDBVersion || currentTime > lastDBUpdateTime + UPDATE_MIN_DELAY)
+ && !isUpdateCompulsory
+ ) {
+ //don't need to update
+ //cancelNotification(NOTIFICATION_ID)
+ return Result.success(
+ Data.Builder().putInt
+ (SUCCESS_REASON_KEY, SUCCESS_NO_ACTION_NEEDED).build()
+ )
+ }
+
+ */
+ //start the real update
+ val resultAtomicReference = AtomicReference<Fetcher.Result?>()
+
+ DatabaseUpdate.setDBUpdatingFlag(con, sharedPrefs, true)
+ val resultUpdate = DatabaseUpdate.performDBUpdate(con, resultAtomicReference)
+ DatabaseUpdate.setDBUpdatingFlag(con, sharedPrefs, false)
+
+ if (resultUpdate != DatabaseUpdate.Result.DONE) {
+ //Fetcher.Result result = resultAtomicReference.get();
+ val dataBuilder = Data.Builder()
+ when (resultUpdate) {
+ DatabaseUpdate.Result.ERROR_STOPS_DOWNLOAD -> dataBuilder.put(ERROR_REASON_KEY, ERROR_DOWNLOADING_STOPS)
+ DatabaseUpdate.Result.ERROR_LINES_DOWNLOAD -> dataBuilder.put(ERROR_REASON_KEY, ERROR_DOWNLOADING_LINES)
+ DatabaseUpdate.Result.DB_CLOSED -> dataBuilder.put(ERROR_REASON_KEY, ERROR_CODE_DB_CLOSED)
+ DatabaseUpdate.Result.DONE -> {}
+ }
+ //cancelNotification(NOTIFICATION_ID)
+ return Result.failure(dataBuilder.build())
+ }
+ Log.d(DEBUG_TAG, "Update finished successfully!")
+ //update the version in the shared preference
+ val editor = sharedPrefs.edit()
+ editor.putInt(PreferencesHolder.DB_GTT_VERSION_KEY, newDBVersion)
+ val currentTime = System.currentTimeMillis() / 1000
+ editor.putLong(PreferencesHolder.DB_LAST_UPDATE_KEY, currentTime)
+ editor.apply()
+ //cancelNotification(NOTIFICATION_ID)
+
+ return Result.success(Data.Builder().putInt(SUCCESS_REASON_KEY, SUCCESS_UPDATE_DONE).build())
+ }
+
+ override suspend fun getForegroundInfo(): ForegroundInfo {
+ //val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ val context = applicationContext
+ Notifications.createDBNotificationChannelIfNeeded(context)
+
+ val builder = NotificationCompat.Builder(
+ context,
+ Notifications.DB_UPDATE_CHANNELS_ID
+ )
+ .setContentTitle(context.getString(R.string.database_update_msg_notif))
+ .setProgress(0, 0, true)
+ .setPriority(NotificationCompat.PRIORITY_LOW)
+ builder.setSmallIcon(R.drawable.ic_bus_stilized)
+
+ /*val typeInt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+ } else 0
+
+ */
+
+ return ForegroundInfo(NOTIFICATION_ID, builder.build())
+ }
+
+ /*
+ private int showNotification(@NonNull final NotificationManagerCompat notificManager, final int notification_ID,
+ final String channel_ID){
+ final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), channel_ID)
+ .setContentTitle("Libre BusTO - Updating Database")
+ .setProgress(0,0,true)
+ .setPriority(NotificationCompat.PRIORITY_LOW);
+ builder.setSmallIcon(R.drawable.ic_bus_orange);
+
+
+ notificManager.notify(notification_ID,builder.build());
+
+ return notification_ID;
+ }
+ */
+ private fun cancelNotification(notificationID: Int) {
+ val notificationManager = NotificationManagerCompat.from(getApplicationContext())
+
+ notificationManager.cancel(notificationID)
+ }
+
+ companion object {
+ const val ERROR_CODE_KEY: String = "Error_Code"
+ const val ERROR_REASON_KEY: String = "ERROR_REASON"
+ const val ERROR_FETCHING_VERSION: Int = 4
+ const val ERROR_DOWNLOADING_STOPS: Int = 5
+ const val ERROR_DOWNLOADING_LINES: Int = 6
+ val ERROR_CODE_DB_CLOSED: Int = -2
+
+ const val SUCCESS_REASON_KEY: String = "SUCCESS_REASON"
+ const val SUCCESS_NO_ACTION_NEEDED: Int = 9
+ const val SUCCESS_UPDATE_DONE: Int = 1
+
+ const val FORCED_UPDATE: String = "FORCED-UPDATE"
+
+ private const val DEBUG_TAG: String = "BusTO-UpdateWorker"
+ const val STATUS_UPDATE: String = "STATUS_UPDATE"
+ const val WORK_NAME = "BusTO-UpdateWorker"
+ private const val NOTIFICATION_ID = 32198
+
+
+ private const val UPDATE_MIN_DELAY = (9 * 24 * 3600 //9 days
+ ).toLong()
+
+
+ val workConstraints: Constraints
+ get() = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
+ .setRequiresCharging(false).build()
+
+ /**
+ * Run the database update immediately
+ */
+ @JvmStatic
+ fun requestDBUpdateUniqueWork(con: Context, forced: Boolean) {
+
+ val workManager = getInstance(con)
+ val reqData = Data.Builder()
+ .putBoolean(FORCED_UPDATE, forced).build()
+
+ val wr = OneTimeWorkRequest.Builder(DBUpdateWorker::class.java)
+ .setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.MINUTES)
+ .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .setConstraints(
+ Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
+ .build()
+ )
+ .setInputData(reqData)
+ .build()
+
+ workManager.enqueueUniqueWork(WORK_NAME, ExistingWorkPolicy.REPLACE, wr)
+ }
+
+ @JvmStatic
+ fun getWorkInfoLiveData(context: Context): LiveData<List<WorkInfo>> {
+ val workManager = WorkManager.getInstance(context)
+ return workManager.getWorkInfosForUniqueWorkLiveData(WORK_NAME)
+ }
+ }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
--- a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
+++ b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
@@ -45,7 +45,6 @@
import org.json.JSONObject;
import java.util.*;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import static android.content.Context.MODE_PRIVATE;
@@ -60,7 +59,7 @@
- enum Result {
+ public enum Result {
DONE, ERROR_STOPS_DOWNLOAD, ERROR_LINES_DOWNLOAD, DB_CLOSED
}
@@ -287,18 +286,17 @@
return editor.commit();
}
- /**
+ /*
* Request update using workmanager framework
* @param con the context to use
* @param forced if you want to force the request to go now
- */
public static void requestDBUpdateWithWork(Context con,boolean restart, boolean forced){
final SharedPreferences theShPr = PreferencesHolder.getMainSharedPreferences(con);
final WorkManager workManager = WorkManager.getInstance(con);
final Data reqData = new Data.Builder()
.putBoolean(DBUpdateWorker.FORCED_UPDATE, forced).build();
- PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 7, TimeUnit.DAYS)
+ PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 2, TimeUnit.DAYS)
.setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.MINUTES)
.setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
.build())
@@ -307,11 +305,12 @@
final int version = theShPr.getInt(PreferencesHolder.DB_GTT_VERSION_KEY, -10);
final long lastDBUpdateTime = theShPr.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, -10);
if ((version >= 0 || lastDBUpdateTime >=0) && !restart)
- workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+ workManager.enqueueUniquePeriodicWork(DBUpdateWorker.WORK_NAME,
ExistingPeriodicWorkPolicy.KEEP, wr);
- else workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+ else workManager.enqueueUniquePeriodicWork(DBUpdateWorker.WORK_NAME,
ExistingPeriodicWorkPolicy.REPLACE, wr);
}
+ */
/*
public static boolean isDBUpdating(){
return false;
@@ -321,8 +320,7 @@
public static void watchUpdateWorkStatus(Context context, @NonNull LifecycleOwner lifecycleOwner,
@NonNull Observer<? super List<WorkInfo>> observer) {
- WorkManager workManager = WorkManager.getInstance(context);
- workManager.getWorkInfosForUniqueWorkLiveData(DBUpdateWorker.DEBUG_TAG).observe(
+ DBUpdateWorker.getWorkInfoLiveData(context).observe(
lifecycleOwner, observer
);
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/GtfsMaintenanceWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/GtfsMaintenanceWorker.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/GtfsMaintenanceWorker.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/GtfsMaintenanceWorker.kt
@@ -1,10 +1,6 @@
package it.reyboz.bustorino.data
-import android.app.NotificationChannel
-import android.app.NotificationManager
import android.content.Context
-import android.os.Build
-import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.work.*
import it.reyboz.bustorino.R
@@ -30,17 +26,9 @@
return Result.success()
}
override suspend fun getForegroundInfo(): ForegroundInfo {
- val notificationManager =
- applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+
val context = applicationContext
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val channel = NotificationChannel(
- Notifications.DB_UPDATE_CHANNELS_ID,
- context.getString(R.string.database_notification_channel),
- NotificationManager.IMPORTANCE_MIN
- )
- notificationManager.createNotificationChannel(channel)
- }
+ Notifications.createDBNotificationChannelIfNeeded(context)
val notification = NotificationCompat.Builder(context, Notifications.DB_UPDATE_CHANNELS_ID)
//.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), Constants.PENDING_INTENT_FLAG_IMMUTABLE))
diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt
@@ -58,7 +58,7 @@
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val context = applicationContext
- Notifications.createDBNotificationChannel(context)
+ Notifications.createDBNotificationChannelIfNeeded(context)
return ForegroundInfo(NOTIFICATION_ID, Notifications.makeMatoDownloadNotification(context))
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
@@ -21,7 +21,6 @@
import android.content.Context
import android.util.Log
import androidx.work.*
-import com.android.volley.toolbox.ClearCacheRequest
import it.reyboz.bustorino.backend.Notifications
import it.reyboz.bustorino.data.gtfs.GtfsTrip
import java.util.concurrent.CountDownLatch
@@ -119,7 +118,7 @@
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val context = applicationContext
- Notifications.createDBNotificationChannel(context)
+ Notifications.createDBNotificationChannelIfNeeded(context)
return ForegroundInfo(NOTIFICATION_ID, Notifications.makeMatoDownloadNotification(context))
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java b/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
--- a/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
+++ b/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
@@ -139,7 +139,8 @@
db.execSQL(SQL_CREATE_BRANCH_TABLE);
db.execSQL(SQL_CREATE_CONNECTIONS_TABLE);
- DatabaseUpdate.requestDBUpdateWithWork(appContext, true, true);
+ //DatabaseUpdate.requestDBUpdateWithWork(appContext, true, true);
+ DBUpdateWorker.requestDBUpdateUniqueWork(appContext, true);
}
if(oldVersion < 3 && newVersion == 3){
Log.d("BusTO-Database", "Running upgrades for version 3");
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
@@ -16,7 +16,6 @@
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import androidx.work.WorkInfo
-import androidx.work.WorkManager
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
@@ -200,7 +199,7 @@
arrows[k]?.setOnClickListener { openLinesAndCloseOthersIfNeeded(k) }
}
// watch for the db update
- WorkManager.getInstance(requireContext()).getWorkInfosForUniqueWorkLiveData(DBUpdateWorker.DEBUG_TAG).observe(viewLifecycleOwner){
+ DBUpdateWorker.getWorkInfoLiveData(requireContext()).observe(viewLifecycleOwner){
workInfoList ->
if (workInfoList == null || workInfoList.isEmpty()) {
return@observe
@@ -438,8 +437,4 @@
return rotate
}
}
-
- override fun showSnackbarOnDBUpdate(): Boolean {
- return false
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
@@ -36,7 +36,7 @@
import androidx.work.WorkManager;
import it.reyboz.bustorino.ActivityBackup;
import it.reyboz.bustorino.R;
-import it.reyboz.bustorino.data.DatabaseUpdate;
+import it.reyboz.bustorino.data.DBUpdateWorker;
import it.reyboz.bustorino.data.GtfsMaintenanceWorker;
import org.jetbrains.annotations.NotNull;
@@ -94,9 +94,9 @@
if (dbUpdateNow!=null)
dbUpdateNow.setOnPreferenceClickListener(
preference -> {
- //trigger update
+ //force update
if(getContext()!=null) {
- DatabaseUpdate.requestDBUpdateWithWork(getContext().getApplicationContext(), true, true);
+ DBUpdateWorker.requestDBUpdateUniqueWork(requireContext(), true);
Toast.makeText(getContext(),R.string.requesting_db_update,Toast.LENGTH_SHORT).show();
return true;
}
diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/GeneralActivity.java b/app/src/main/java/it/reyboz/bustorino/middleware/GeneralActivity.java
--- a/app/src/main/java/it/reyboz/bustorino/middleware/GeneralActivity.java
+++ b/app/src/main/java/it/reyboz/bustorino/middleware/GeneralActivity.java
@@ -29,6 +29,7 @@
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
+import androidx.preference.PreferenceManager;
import com.google.android.material.snackbar.Snackbar;
import androidx.annotation.Nullable;
@@ -42,10 +43,13 @@
import android.widget.Toast;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.utils;
import it.reyboz.bustorino.data.PreferencesHolder;
+import it.reyboz.bustorino.fragments.SettingsFragment;
/**
* Activity class that contains all the generally useful methods
@@ -227,4 +231,44 @@
return WindowInsetsCompat.CONSUMED;
};
+ /**
+ * Adjust setting to match the default ones
+ */
+ protected void checkApplyDefaultSettingsValues(){
+ SharedPreferences mainSharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = mainSharedPref.edit();
+ //Main fragment to show
+ String screen = mainSharedPref.getString(SettingsFragment.PREF_KEY_STARTUP_SCREEN, "");
+ boolean edit = false;
+ if (screen.isEmpty()){
+ editor.putString(SettingsFragment.PREF_KEY_STARTUP_SCREEN, "arrivals");
+ edit=true;
+ }
+ //Fetchers
+ final Set<String> setSelected = mainSharedPref.getStringSet(SettingsFragment.KEY_ARRIVALS_FETCHERS_USE, new HashSet<>());
+ if (setSelected.isEmpty()){
+ String[] defaultVals = getResources().getStringArray(R.array.arrivals_sources_values_default);
+ editor.putStringSet(SettingsFragment.KEY_ARRIVALS_FETCHERS_USE, utils.convertArrayToSet(defaultVals));
+ edit=true;
+ }
+ //Live bus positions
+ final String keySourcePositions=getString(R.string.pref_positions_source);
+ final String positionsSource = mainSharedPref.getString(keySourcePositions, "");
+ if(positionsSource.isEmpty()){
+ String[] defaultVals = getResources().getStringArray(R.array.positions_source_values);
+ editor.putString(keySourcePositions, defaultVals[0]);
+ edit=true;
+ }
+ //Map style
+ final String mapStylePref = mainSharedPref.getString(SettingsFragment.LIBREMAP_STYLE_PREF_KEY, "");
+ if(mapStylePref.isEmpty()){
+ final String[] defaultVals = getResources().getStringArray(R.array.map_style_pref_values);
+ editor.putString(SettingsFragment.LIBREMAP_STYLE_PREF_KEY, defaultVals[0]);
+ edit=true;
+ }
+ if (edit){
+ editor.commit();
+ }
+
+ }
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 28, 14:19 (22 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1877426
Default Alt Text
D225.1777378743.diff (43 KB)
Attached To
Mode
D225: Re-arrange workers for the database update
Attached
Detach File
Event Timeline
Log In to Comment