diff --git a/src/it/reyboz/bustorino/backend/DBStatusManager.java b/src/it/reyboz/bustorino/backend/DBStatusManager.java
index 6eed4b5..127abc4 100644
--- a/src/it/reyboz/bustorino/backend/DBStatusManager.java
+++ b/src/it/reyboz/bustorino/backend/DBStatusManager.java
@@ -1,90 +1,90 @@
/*
BusTO - Backend components
Copyright (C) 2019 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 .
*/
package it.reyboz.bustorino.backend;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import it.reyboz.bustorino.R;
/**
* Class to handle app status modifications, e.g. database is being updated or not
*/
public class DBStatusManager {
private static String PREFERENCES_NAME;// = "it.reyboz.bustorino.statusPreferences";
private String DB_UPDATING;
private SharedPreferences preferences;
private SharedPreferences.OnSharedPreferenceChangeListener prefListener;
private OnDBUpdateStatusChangeListener dbUpdateListener;
public DBStatusManager(Context context, OnDBUpdateStatusChangeListener listener) {
Context thecon = context.getApplicationContext();
this.preferences = thecon.getSharedPreferences(context.getString(R.string.mainSharedPreferences),Context.MODE_PRIVATE);
DB_UPDATING = context.getString(R.string.databaseUpdatingPref);
PREFERENCES_NAME = context.getString(R.string.mainSharedPreferences);
dbUpdateListener = listener;
//this.prefListeners = new ArrayList<>();
prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d("BUSTO-PrefListener", "Changed key " + key + " in the sharedPref");
- if (key.equals(DB_UPDATING)) {
+ if (dbUpdateListener!=null && key.equals(DB_UPDATING)) {
dbUpdateListener.onDBStatusChanged(sharedPreferences.getBoolean(DB_UPDATING, dbUpdateListener.defaultStatusValue()));
}
}
};
}
public boolean isDBUpdating(boolean defaultvalue){
if (preferences == null) //preferences = thecon.getSharedPreferences(PREFERENCES_NAME,Context.MODE_PRIVATE);
{
//This should NOT HAPPEN
Log.e("BUSTO_Pref","Preference reference is null");
return false;
} else {
return preferences.getBoolean(DB_UPDATING,defaultvalue);
}
}
public void registerListener(){
if(prefListener!=null)
preferences.registerOnSharedPreferenceChangeListener(prefListener);
}
public void unregisterListener(){
if(prefListener!=null)
preferences.unregisterOnSharedPreferenceChangeListener(prefListener);
}
public void setDbUpdating(boolean value){
final SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(DB_UPDATING,value);
editor.apply();
}
public interface OnDBUpdateStatusChangeListener {
void onDBStatusChanged(boolean updating);
boolean defaultStatusValue();
}
}
diff --git a/src/it/reyboz/bustorino/middleware/DBUpdateWorker.java b/src/it/reyboz/bustorino/middleware/DBUpdateWorker.java
index a6c5c1f..d1cbe59 100644
--- a/src/it/reyboz/bustorino/middleware/DBUpdateWorker.java
+++ b/src/it/reyboz/bustorino/middleware/DBUpdateWorker.java
@@ -1,137 +1,139 @@
package it.reyboz.bustorino.middleware;
+import android.annotation.SuppressLint;
import android.app.Notification;
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;
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 String SUCCESS_REASON_KEY = "SUCCESS_REASON";
public static final int SUCCESS_NO_ACTION_NEEDED = 9;
public static final int SUCCESS_UPDATE_DONE = 1;
private int notifi_ID=62341;
public static final String FORCED_UPDATE = "FORCED-UPDATE";
public static final String DEBUG_TAG = "Busto-UpdateWorker";
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);
final SharedPreferences shPr = con.getSharedPreferences(con.getString(R.string.mainSharedPreferences),MODE_PRIVATE);
- final int current_DB_version = shPr.getInt(DatabaseUpdate.DB_VERSION_KEY,-1);
+ final int current_DB_version = shPr.getInt(DatabaseUpdate.DB_VERSION_KEY,-10);
final int new_DB_version = DatabaseUpdate.getNewVersion();
final boolean isUpdateCompulsory = getInputData().getBoolean(FORCED_UPDATE,false);
final int notificationID = showNotification();
Log.d(DEBUG_TAG, "Have previous version: "+current_DB_version +" and new version "+new_DB_version);
Log.d(DEBUG_TAG, "Update compulsory: "+isUpdateCompulsory);
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 Result.failure(out);
}
//we got a good version
if (current_DB_version >= new_DB_version && !isUpdateCompulsory) {
//don't need to update
cancelNotification(notificationID);
return Result.success(new Data.Builder().
putInt(SUCCESS_REASON_KEY, SUCCESS_NO_ACTION_NEEDED).build());
}
//start the real update
AtomicReference 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;
}
cancelNotification(notificationID);
return 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(DatabaseUpdate.DB_VERSION_KEY, new_DB_version);
editor.apply();
cancelNotification(notificationID);
return 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(){
final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Notifications.DEFAULT_CHANNEL_ID)
.setContentTitle("Libre BusTO - Updating Database")
.setProgress(0,0,true)
.setPriority(NotificationCompat.PRIORITY_LOW);
builder.setSmallIcon(R.drawable.ic_star_filled);
final NotificationManagerCompat notifcManager = NotificationManagerCompat.from(getApplicationContext());
final int notification_ID = 32198;
notifcManager.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/src/it/reyboz/bustorino/middleware/GeneralActivity.java b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
index 7a2381d..b6cc81c 100644
--- a/src/it/reyboz/bustorino/middleware/GeneralActivity.java
+++ b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
@@ -1,131 +1,135 @@
package it.reyboz.bustorino.middleware;
import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import java.util.HashMap;
import it.reyboz.bustorino.R;
/**
* Activity class that contains all the generally useful methods
*/
public abstract class GeneralActivity extends AppCompatActivity {
final static protected int PERMISSION_REQUEST_POSITION = 33;
final static protected String LOCATION_PERMISSION_GIVEN = "loc_permission";
final static protected int STORAGE_PERMISSION_REQ = 291;
final static protected int PERMISSION_OK = 0;
final static protected int PERMISSION_ASKING = 11;
final static protected int PERMISSION_NEG_CANNOT_ASK = -3;
final static private String DEBUG_TAG = "BusTO-GeneralAct";
/*
* Permission stuff
*/
protected HashMap permissionDoneRunnables = new HashMap<>();
protected HashMap permissionAsked = new HashMap<>();
protected void setOption(String optionName, boolean value) {
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean(optionName, value);
editor.commit();
}
protected boolean getOption(String optionName, boolean optDefault) {
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
return preferences.getBoolean(optionName, optDefault);
}
+
+ protected SharedPreferences getMainSharedPreferences(){
+ return getSharedPreferences(getString(R.string.mainSharedPreferences),MODE_PRIVATE);
+ }
public void hideKeyboard() {
View view = getCurrentFocus();
if (view != null) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(view.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
public boolean isConnected() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
public void showToastMessage(int messageID, boolean short_lenght) {
final int length = short_lenght ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG;
Toast.makeText(getApplicationContext(), messageID, length).show();
}
public void assertLocationPermissions() {
if(ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_POSITION);
}
}
public int askForPermissionIfNeeded(String permission, int requestID){
if(ContextCompat.checkSelfPermission(getApplicationContext(),permission)==PackageManager.PERMISSION_GRANTED){
return PERMISSION_OK;
}
//need to ask for the permission
//consider scenario when we have already asked for permission
boolean alreadyAsked = false;
Integer num_trials = 0;
synchronized (this){
if (permissionAsked.containsKey(permission)){
num_trials = permissionAsked.get(permission);
if (num_trials != null && num_trials > 3)
alreadyAsked = true;
}
}
Log.d(DEBUG_TAG,"Already asked for permission: "+permission+" -> "+num_trials);
if(!alreadyAsked){
ActivityCompat.requestPermissions(this,new String[]{permission}, requestID);
synchronized (this){
if (num_trials!=null){
permissionAsked.put(permission, num_trials+1);
}
}
return PERMISSION_ASKING;
} else {
return PERMISSION_NEG_CANNOT_ASK;
}
}
public void createSnackbar(int ViewID, String message,int duration){
Snackbar.make(findViewById(ViewID),message,duration);
}
/*
METHOD THAT MIGHT BE USEFUL LATER
public void assertPermissions(String[] permissions){
ArrayList permissionstoRequest = new ArrayList<>();
for(int i=0;i