Page MenuHomeGitPull.it

D53.1765168548.diff
No OneTemporary

Size
70 KB
Referenced Files
None
Subscribers
None

D53.1765168548.diff

diff --git a/res/drawable/ic_baseline_settings_24.xml b/res/drawable/ic_baseline_settings_24.xml
new file mode 100644
--- /dev/null
+++ b/res/drawable/ic_baseline_settings_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FFFFFF"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
+</vector>
diff --git a/res/layout/activity_about.xml b/res/layout/activity_about.xml
--- a/res/layout/activity_about.xml
+++ b/res/layout/activity_about.xml
@@ -2,15 +2,21 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
tools:context="it.reyboz.bustorino.ActivityAbout">
+ <!-- The ActionBar displayed at the top -->
+
+ <include
+ layout="@layout/default_toobar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
<TextView
android:id="@+id/aboutTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
+ android:layout_marginLeft="@dimen/activity_horizontal_margin"
+ android:layout_marginRight="@dimen/activity_horizontal_margin"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/new_main_activity.xml b/res/layout/activity_principal.xml
rename from res/layout/new_main_activity.xml
rename to res/layout/activity_principal.xml
diff --git a/res/layout/fragment_main_screen.xml b/res/layout/fragment_main_screen.xml
--- a/res/layout/fragment_main_screen.xml
+++ b/res/layout/fragment_main_screen.xml
@@ -3,7 +3,9 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".fragments.MainScreenFragment">
+ tools:context=".fragments.MainScreenFragment"
+ android:paddingTop="10dip"
+ >
<ImageButton
android:id="@+id/QRButton"
@@ -17,7 +19,7 @@
android:layout_marginStart="16dp"
android:background="@drawable/qrcode_button_custom"
android:contentDescription="@string/qrcode"
- android:onClick="onQRButtonClick" />
+ />
<EditText
android:id="@+id/busStopSearchByIDEditText"
@@ -44,21 +46,22 @@
<!--android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"-->
<EditText
- android:id="@+id/busStopSearchByNameEditText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="5dp"
- android:layout_marginLeft="5dip"
- android:layout_marginRight="5dip"
- android:layout_toEndOf="@+id/QRButton"
- android:layout_toLeftOf="@+id/searchButton"
- android:layout_toRightOf="@+id/QRButton"
- android:layout_toStartOf="@+id/searchButton"
- android:ems="10"
- android:hint="@string/insert_bus_stop_name"
- android:imeOptions="actionSearch"
- android:singleLine="true"
- android:visibility="gone">
+ android:id="@+id/busStopSearchByNameEditText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="5dp"
+ android:layout_marginLeft="5dip"
+ android:layout_marginRight="5dip"
+ android:layout_toEndOf="@+id/QRButton"
+ android:layout_toLeftOf="@+id/searchButton"
+ android:layout_toRightOf="@+id/QRButton"
+ android:layout_toStartOf="@+id/searchButton"
+
+ android:ems="10"
+ android:hint="@string/insert_bus_stop_name"
+ android:imeOptions="actionSearch"
+ android:singleLine="true"
+ android:visibility="gone">
<requestFocus />
</EditText>
@@ -75,7 +78,7 @@
android:layout_marginRight="16dp"
android:background="@drawable/search_button_custom"
android:contentDescription="@string/search"
- android:onClick="onSearchClick" />
+ />
<ProgressBar
android:id="@+id/progressBar"
@@ -121,7 +124,6 @@
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:background="@drawable/route_background_bus"
- android:onClick="onHideHint"
android:text="@string/hint_button"
android:textColor="@color/grey_100"
android:textSize="19sp"
@@ -152,7 +154,6 @@
android:layout_alignParentRight="true"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
- android:onClick="onToggleKeyboardLayout"
android:src="@drawable/alphabetical"
fabSize="normal"
backgroundTint="@color/teal_500"
diff --git a/res/menu/drawer_main.xml b/res/menu/drawer_main.xml
--- a/res/menu/drawer_main.xml
+++ b/res/menu/drawer_main.xml
@@ -16,4 +16,9 @@
android:title="@string/nav_favorites_text" />
</group>
+ <item android:id="@+id/drawer_action_settings"
+ android:title="@string/action_settings"
+ android:icon="@drawable/ic_baseline_settings_24"
+ />
+
</menu>
\ No newline at end of file
diff --git a/res/menu/extra_menu_items.xml b/res/menu/extra_menu_items.xml
new file mode 100644
--- /dev/null
+++ b/res/menu/extra_menu_items.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ >
+ <item
+ android:id="@+id/action_about"
+ android:orderInCategory="4"
+ android:title="@string/action_about_more" />
+ <item
+ android:id="@+id/action_hack"
+ android:orderInCategory="6"
+ android:title="@string/action_hack"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/action_source"
+ android:orderInCategory="7"
+ android:title="@string/action_source"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/action_licence"
+ android:orderInCategory="8"
+ android:title="@string/action_licence"
+ app:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/res/values/theme.xml b/res/values/theme.xml
--- a/res/values/theme.xml
+++ b/res/values/theme.xml
@@ -7,7 +7,7 @@
<item name="colorAccent">@color/teal_500</item>
</style>
- <style name="AboutTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+ <style name="AboutTheme" parent="AppTheme.NoActionBar">
<item name="colorPrimary">@color/teal_300</item>
<item name="colorPrimaryDark">@color/teal_500</item>
<item name="colorAccent">@color/blue_700</item>
diff --git a/src/it/reyboz/bustorino/ActivityAbout.java b/src/it/reyboz/bustorino/ActivityAbout.java
--- a/src/it/reyboz/bustorino/ActivityAbout.java
+++ b/src/it/reyboz/bustorino/ActivityAbout.java
@@ -17,6 +17,7 @@
*/
package it.reyboz.bustorino;
+import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NavUtils;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
@@ -40,19 +41,18 @@
aboutTextView.setText(htmlText);
aboutTextView.setMovementMethod(LinkMovementMethod.getInstance());
- // Back button
- ActionBar ab = getSupportActionBar();
- assert ab != null;
- ab.setDisplayHomeAsUpEnabled(true);
+ Toolbar mToolbar = findViewById(R.id.default_toolbar);
+ setSupportActionBar(mToolbar);
+ if (getSupportActionBar()!=null)
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- // Respond to the action bar's Up/Home button
- case android.R.id.home:
- NavUtils.navigateUpFromSameTask(this);
- return true;
+ // Respond to the action bar's Up/Home button
+ if (item.getItemId() == android.R.id.home) {//NavUtils.navigateUpFromSameTask(this);
+ onBackPressed();
+ return true;
}
return super.onOptionsItemSelected(item);
}
diff --git a/src/it/reyboz/bustorino/ActivityMain.java b/src/it/reyboz/bustorino/ActivityMain.java
--- a/src/it/reyboz/bustorino/ActivityMain.java
+++ b/src/it/reyboz/bustorino/ActivityMain.java
@@ -18,6 +18,7 @@
package it.reyboz.bustorino;
import android.Manifest;
+import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -69,11 +70,14 @@
import it.reyboz.bustorino.data.UserDB;
import it.reyboz.bustorino.fragments.*;
import it.reyboz.bustorino.middleware.*;
+import it.reyboz.bustorino.util.Permissions;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
+
public class ActivityMain extends GeneralActivity implements FragmentListenerMain {
/*
@@ -132,15 +136,19 @@
* @see swipeRefreshLayout
*/
private final Handler theHandler = new Handler();
- private final Runnable refreshing = new Runnable() {
+ private final Runnable refreshStop = new Runnable() {
public void run() {
if (framan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
ArrivalsFragment fragment = (ArrivalsFragment) framan.findFragmentById(R.id.resultFrame);
- String stopName = fragment.getStopID();
+ if (fragment == null){
+ new AsyncDataDownload(fh, arrivalsFetchers, getApplicationContext()).execute();
+ } else{
+ String stopName = fragment.getStopID();
- new AsyncDataDownload(fh, fragment.getCurrentFetchersAsArray()).execute(stopName);
+ new AsyncDataDownload(fh, fragment.getCurrentFetchersAsArray(), getApplicationContext()).execute(stopName);
+ }
} else //we create a new fragment, which is WRONG
- new AsyncDataDownload(fh, arrivalsFetchers).execute();
+ new AsyncDataDownload(fh, arrivalsFetchers, getApplicationContext()).execute();
}
};
@@ -191,14 +199,14 @@
// Called when the layout is pulled down
swipeRefreshLayout
- .setOnRefreshListener(() -> theHandler.post(refreshing));
+ .setOnRefreshListener(() -> theHandler.post(refreshStop));
/**
* @author Marco Gagino!!!
*/
//swipeRefreshLayout.setColorSchemeColors(R.color.blue_500, R.color.orange_500); // setColorScheme is deprecated, setColorSchemeColors isn't
swipeRefreshLayout.setColorSchemeResources(R.color.blue_500, R.color.orange_500);
- fh = new FragmentHelper(this, R.id.listRefreshLayout, R.id.resultFrame);
+ fh = new FragmentHelper(this, framan, getApplicationContext(),R.id.resultFrame);
setSearchModeBusStopID();
//---------------------------- START INTENT CHECK QUEUE ------------------------------------
@@ -258,9 +266,6 @@
requestArrivalsForStopID(busStopID);
}
//Try (hopefully) database update
- //TODO: Check if service shows the notification
- //Old code for the db update
- //DatabaseUpdateService.startDBUpdate(getApplicationContext());
PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 1, TimeUnit.DAYS)
@@ -317,7 +322,7 @@
cr.setCostAllowed(true);
cr.setPowerRequirement(Criteria.NO_REQUIREMENT);
//We want the nearby bus stops!
- theHandler.post(new NearbyStopsRequester());
+ theHandler.post(new NearbyStopsRequester(this));
//If there are no providers available, then, wait for them
@@ -363,7 +368,7 @@
fh.setBlockAllActivities(false);
//TODO: check if current LiveData-bound observer works
if (pendingNearbyStopsRequest)
- theHandler.post(new NearbyStopsRequester());
+ theHandler.post(new NearbyStopsRequester(this));
ActionBar bar = getSupportActionBar();
if(bar!=null) bar.show();
else Log.w(DEBUG_TAG, "ACTION BAR IS NULL");
@@ -469,7 +474,7 @@
} else { // searchMode == SEARCH_BY_NAME
String query = busStopSearchByNameEditText.getText().toString();
//new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper);
- new AsyncDataDownload(fh, stopsFinderByNames).execute(query);
+ new AsyncDataDownload(fh, stopsFinderByNames, getApplicationContext()).execute(query);
}
}
@@ -486,7 +491,7 @@
//if we sent a request for a new NearbyStopsFragment
if (pendingNearbyStopsRequest) {
pendingNearbyStopsRequest = false;
- theHandler.post(new NearbyStopsRequester());
+ theHandler.post(new NearbyStopsRequester(this));
}
} else {
@@ -535,13 +540,13 @@
if (fragment !=null && fragment.getStopID() != null && fragment.getStopID().equals(ID)){
// Run with previous fetchers
//fragment.getCurrentFetchers().toArray()
- new AsyncDataDownload(fh,fragment.getCurrentFetchersAsArray()).execute(ID);
+ new AsyncDataDownload(fh,fragment.getCurrentFetchersAsArray(), this).execute(ID);
} else{
- new AsyncDataDownload(fh, arrivalsFetchers).execute(ID);
+ new AsyncDataDownload(fh, arrivalsFetchers, this).execute(ID);
}
}
else {
- new AsyncDataDownload(fh,arrivalsFetchers).execute(ID);
+ new AsyncDataDownload(fh, arrivalsFetchers, this).execute(ID);
Log.d("MainActiv", "Started search for arrivals of stop " + ID);
}
}
@@ -609,7 +614,7 @@
Log.d(DEBUG_TAG, "Provider " + provider + " got enabled");
if (locmgr != null && pendingNearbyStopsRequest && locmgr.getProvider(provider).meetsCriteria(cr)) {
pendingNearbyStopsRequest = false;
- theHandler.post(new NearbyStopsRequester());
+ theHandler.post(new NearbyStopsRequester(this));
}
}
@@ -642,6 +647,13 @@
* Run location requests separately and asynchronously
*/
class NearbyStopsRequester implements Runnable {
+
+ Activity runningAct;
+
+ public NearbyStopsRequester(Activity runningAct) {
+ this.runningAct = runningAct;
+ }
+
@Override
public void run() {
final boolean canRunPosition = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || getOption(LOCATION_PERMISSION_GIVEN, false);
@@ -653,7 +665,7 @@
if (noPermission) {
if (!canRunPosition) {
pendingNearbyStopsRequest = true;
- assertLocationPermissions();
+ Permissions.assertLocationPermissions(getApplicationContext(),runningAct);
Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
return;
} else {
@@ -703,26 +715,6 @@
///////////////////////////////// OTHER STUFF //////////////////////////////////////////////////
- /**
- * Check if the last Bus Stop is in the favorites
- *
- * @return
- */
- public boolean isStopInFavorites(String busStopId) {
- boolean found = false;
-
- // no stop no party
- if (busStopId != null) {
- SQLiteDatabase userDB = new UserDB(getApplicationContext()).getReadableDatabase();
- found = UserDB.isStopInFavorites(userDB, busStopId);
- }
-
- return found;
- }
-
- /**
- * Add the last Stop to favorites
- */
@Override
@@ -841,55 +833,8 @@
}
- /**
- * Open an URL in the default browser.
- *
- * @param url URL
- */
- public void openIceweasel(String url) {
- Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- startActivity(browserIntent1);
- }
-
- ///////////////////// INTENT HELPER ////////////////////////////////////////////////////////////
-
- /**
- * Try to extract the bus stop ID from a URi
- *
- * @param uri The URL
- * @return bus stop ID or null
- */
- public static String getBusStopIDFromUri(Uri uri) {
- String busStopID;
-
- // everithing catches fire when passing null to a switch.
- String host = uri.getHost();
- if (host == null) {
- Log.e("ActivityMain", "Not an URL: " + uri);
- return null;
- }
-
- switch (host) {
- case "m.gtt.to.it":
- // http://m.gtt.to.it/m/it/arrivi.jsp?n=1254
- busStopID = uri.getQueryParameter("n");
- if (busStopID == null) {
- Log.e("ActivityMain", "Expected ?n from: " + uri);
- }
- break;
- case "www.gtt.to.it":
- case "gtt.to.it":
- // http://www.gtt.to.it/cms/percorari/arrivi?palina=1254
- busStopID = uri.getQueryParameter("palina");
- if (busStopID == null) {
- Log.e("ActivityMain", "Expected ?palina from: " + uri);
- }
- break;
- default:
- Log.e("ActivityMain", "Unexpected intent URL: " + uri);
- busStopID = null;
- }
- return busStopID;
+ private void openIceweasel(String url){
+ utils.openIceweasel(url, this);
}
}
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/ActivityMap.java b/src/it/reyboz/bustorino/ActivityMap.java
--- a/src/it/reyboz/bustorino/ActivityMap.java
+++ b/src/it/reyboz/bustorino/ActivityMap.java
@@ -87,7 +87,7 @@
protected ImageButton btCenterMap;
protected ImageButton btFollowMe;
- @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
+ //@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/src/it/reyboz/bustorino/ActivityPrincipal.java b/src/it/reyboz/bustorino/ActivityPrincipal.java
--- a/src/it/reyboz/bustorino/ActivityPrincipal.java
+++ b/src/it/reyboz/bustorino/ActivityPrincipal.java
@@ -1,33 +1,62 @@
package it.reyboz.bustorino;
+import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.content.res.Resources;
+import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+import android.view.Menu;
import android.view.MenuItem;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
-import androidx.core.app.NavUtils;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.work.BackoffPolicy;
+import androidx.work.Constraints;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.NetworkType;
+import androidx.work.PeriodicWorkRequest;
+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.concurrent.TimeUnit;
+
+import it.reyboz.bustorino.data.DBUpdateWorker;
+import it.reyboz.bustorino.data.DatabaseUpdate;
+import it.reyboz.bustorino.fragments.FragmentKind;
+import it.reyboz.bustorino.fragments.FragmentListenerMain;
+import it.reyboz.bustorino.fragments.MainScreenFragment;
import it.reyboz.bustorino.middleware.GeneralActivity;
-public class ActivityPrincipal extends GeneralActivity {
+import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
+import static it.reyboz.bustorino.backend.utils.openIceweasel;
+
+public class ActivityPrincipal extends GeneralActivity implements FragmentListenerMain {
private DrawerLayout mDrawer;
private NavigationView mNavView;
private ActionBarDrawerToggle drawerToggle;
private final static String DEBUG_TAG="BusTO Act Principal";
+ private Snackbar snackbar;
+
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.new_main_activity);
+ setContentView(R.layout.activity_principal);
+ final SharedPreferences theShPr = getMainSharedPreferences();
+
Toolbar mToolbar = findViewById(R.id.default_toolbar);
setSupportActionBar(mToolbar);
@@ -35,6 +64,8 @@
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
else Log.w(DEBUG_TAG, "NO ACTION BAR");
+ mToolbar.setOnMenuItemClickListener(new ToolbarItemClickListener());
+
mDrawer = findViewById(R.id.drawer_layout);
drawerToggle = setupDrawerToggle(mToolbar);
@@ -50,6 +81,101 @@
setupDrawerContent(mNavView);
+ /// LEGACY CODE
+ //---------------------------- START INTENT CHECK QUEUE ------------------------------------
+
+ // Intercept calls from URL intent
+ boolean tryedFromIntent = false;
+
+ String busStopID = null;
+ Uri data = getIntent().getData();
+ if (data != null) {
+ busStopID = getBusStopIDFromUri(data);
+ tryedFromIntent = true;
+ }
+
+ // Intercept calls from other activities
+ if (!tryedFromIntent) {
+ Bundle b = getIntent().getExtras();
+ if (b != null) {
+ busStopID = b.getString("bus-stop-ID");
+
+ /**
+ * I'm not very sure if you are coming from an Intent.
+ * Some launchers work in strange ways.
+ */
+ tryedFromIntent = busStopID != null;
+ }
+ }
+
+ //---------------------------- END INTENT CHECK QUEUE --------------------------------------
+
+ if (busStopID == null) {
+ // Show keyboard if can't start from intent
+ // JUST DON'T
+ // showKeyboard();
+
+ // You haven't obtained anything... from an intent?
+ if (tryedFromIntent) {
+
+ // This shows a luser warning
+ Toast.makeText(getApplicationContext(),
+ R.string.insert_bus_stop_number_error, Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ // If you are here an intent has worked successfully
+ //setBusStopSearchByIDEditText(busStopID);
+
+ requestArrivalsForStopID(busStopID);
+ }
+ //Try (hopefully) database update
+
+
+ PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 1, TimeUnit.DAYS)
+ .setBackoffCriteria(BackoffPolicy.LINEAR, 30, TimeUnit.MINUTES)
+ .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
+ .build())
+ .build();
+ final WorkManager workManager = WorkManager.getInstance(this);
+
+ final int version = theShPr.getInt(DatabaseUpdate.DB_VERSION_KEY, -10);
+ if (version >= 0)
+ workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+ ExistingPeriodicWorkPolicy.KEEP, wr);
+ else workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+ ExistingPeriodicWorkPolicy.REPLACE, wr);
+ /*
+ Set database update
+ */
+ workManager.getWorkInfosForUniqueWorkLiveData(DBUpdateWorker.DEBUG_TAG)
+ .observe(this, workInfoList -> {
+ // If there are no matching work info, do nothing
+ if (workInfoList == null || workInfoList.isEmpty()) {
+ return;
+ }
+ Log.d(DEBUG_TAG, "WorkerInfo: "+workInfoList);
+
+ boolean showProgress = false;
+ for (WorkInfo workInfo : workInfoList) {
+ if (workInfo.getState() == WorkInfo.State.RUNNING) {
+ showProgress = true;
+ }
+ }
+
+ if (showProgress) {
+ createDefaultSnackbar();
+ } else {
+ if(snackbar!=null) {
+ snackbar.dismiss();
+ snackbar = null;
+ }
+ }
+
+ });
+ // show the main fragment
+ showMainFragment();
+
+
}
private ActionBarDrawerToggle setupDrawerToggle(Toolbar toolbar) {
// NOTE: Make sure you pass in a valid toolbar reference. ActionBarDrawToggle() does not require it
@@ -60,7 +186,12 @@
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
menuItem -> {
-
+ if (menuItem.getItemId() == R.id.drawer_action_settings) {
+ Log.d("MAINBusTO", "Pressed button preferences");
+ closeDrawerIfOpen();
+ startActivity(new Intent(ActivityPrincipal.this, ActivitySettings.class));
+ return true;
+ }
//selectDrawerItem(menuItem);
Log.d(DEBUG_TAG, "pressed item "+menuItem.toString());
@@ -70,6 +201,11 @@
}
+ private void closeDrawerIfOpen(){
+ if (mDrawer.isDrawerOpen(GravityCompat.START))
+ mDrawer.closeDrawer(GravityCompat.START);
+ }
+
// `onPostCreate` called when activity start-up is complete after `onStart()`
// NOTE 1: Make sure to override the method with only a single `Bundle` argument
@@ -89,20 +225,24 @@
drawerToggle.onConfigurationChanged(newConfig);
}
+
@Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.extra_menu_items, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+ @Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int[] cases = {R.id.nav_arrivals, R.id.nav_favorites_item};
+ Log.d(DEBUG_TAG, "Item pressed");
+
switch (item.getItemId()){
case android.R.id.home:
mDrawer.openDrawer(GravityCompat.START);
return true;
-
- case R.id.nav_arrivals:
- //do something
- break;
default:
}
@@ -118,9 +258,116 @@
@Override
public void onBackPressed() {
+ boolean foundFragment = false;
+ Fragment shownFrag = getSupportFragmentManager().findFragmentById(R.id.mainActContentFrame);
if (mDrawer.isDrawerOpen(GravityCompat.START))
mDrawer.closeDrawer(GravityCompat.START);
+ else if(shownFrag != null && shownFrag.isVisible() && shownFrag.getChildFragmentManager().getBackStackEntryCount() > 0){
+ shownFrag.getChildFragmentManager().popBackStack();
+ }
+ else if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
+ getSupportFragmentManager().popBackStack();
+ }
else
super.onBackPressed();
}
+
+ private void createDefaultSnackbar() {
+ if (snackbar == null) {
+ snackbar = Snackbar.make(findViewById(R.id.searchButton), R.string.database_update_message, Snackbar.LENGTH_INDEFINITE);
+ }
+ snackbar.show();
+ }
+
+ private MainScreenFragment showMainFragment(){
+ FragmentManager fraMan = getSupportFragmentManager();
+
+ MainScreenFragment fragment = MainScreenFragment.newInstance();
+
+ FragmentTransaction transaction = fraMan.beginTransaction();
+ transaction.replace(R.id.mainActContentFrame, fragment, MainScreenFragment.FRAGMENT_TAG);
+ transaction.commit();
+ return fragment;
+ }
+ @Nullable
+ private MainScreenFragment getMainFragmentIfVisible(){
+ FragmentManager fraMan = getSupportFragmentManager();
+ Fragment fragment = fraMan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG);
+ if (fragment!= null && fragment.isVisible()) return (MainScreenFragment) fragment;
+ else return null;
+ }
+
+ @Override
+ public void showFloatingActionButton(boolean yes) {
+ //TODO
+ }
+
+ @Override
+ public void readyGUIfor(FragmentKind fragmentType) {
+ MainScreenFragment probableFragment = getMainFragmentIfVisible();
+ if (probableFragment!=null){
+ probableFragment.readyGUIfor(fragmentType);
+ }
+ }
+
+ @Override
+ public void requestArrivalsForStopID(String ID) {
+ FragmentManager fraMan = getSupportFragmentManager();
+ Fragment fragment = fraMan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG);
+ MainScreenFragment mainScreenFragment = null;
+ if (fragment==null | !(fragment instanceof MainScreenFragment)){
+ mainScreenFragment = showMainFragment();
+ }
+ else if(!fragment.isVisible()){
+
+ fraMan.beginTransaction().replace(R.id.mainActContentFrame, fragment)
+ .addToBackStack(null)
+ .commit();
+ mainScreenFragment = (MainScreenFragment) fragment;
+ Log.d(DEBUG_TAG, "Found the main fragment");
+ } else{
+ mainScreenFragment = (MainScreenFragment) fragment;
+ }
+
+ mainScreenFragment.requestArrivalsForStopID(ID);
+ }
+
+ @Override
+ public void toggleSpinner(boolean state) {
+ MainScreenFragment probableFragment = getMainFragmentIfVisible();
+ if (probableFragment!=null){
+ probableFragment.toggleSpinner(state);
+ }
+ }
+
+ @Override
+ public void enableRefreshLayout(boolean yes) {
+ MainScreenFragment probableFragment = getMainFragmentIfVisible();
+ if (probableFragment!=null){
+ probableFragment.enableRefreshLayout(yes);
+ }
+ }
+
+ class ToolbarItemClickListener implements Toolbar.OnMenuItemClickListener{
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_about:
+ startActivity(new Intent(ActivityPrincipal.this, ActivityAbout.class));
+ return true;
+ case R.id.action_hack:
+ openIceweasel(getString(R.string.hack_url), getApplicationContext());
+ return true;
+ case R.id.action_source:
+ openIceweasel("https://gitpull.it/source/libre-busto/", getApplicationContext());
+ return true;
+ case R.id.action_licence:
+ openIceweasel("https://www.gnu.org/licenses/gpl-3.0.html", getApplicationContext());
+ return true;
+ default:
+ }
+ return false;
+ }
+ }
}
diff --git a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
--- a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
+++ b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
@@ -59,6 +59,7 @@
}
} catch (JSONException ex){
res.set(result.PARSER_ERROR);
+ Log.w(DEBUG_NAME, "Couldn't get the JSON repr of:\n"+response);
return null;
}
res.set(result.OK);
diff --git a/src/it/reyboz/bustorino/backend/Palina.java b/src/it/reyboz/bustorino/backend/Palina.java
--- a/src/it/reyboz/bustorino/backend/Palina.java
+++ b/src/it/reyboz/bustorino/backend/Palina.java
@@ -20,6 +20,8 @@
import android.util.Log;
+import androidx.annotation.NonNull;
+
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -173,11 +175,14 @@
if(mSource == Passaggio.Source.UNDETERMINED)
break;
}
+ // if the Source is still null, set undetermined
+ if (mSource == null) mSource = Passaggio.Source.UNDETERMINED;
//finished with the check, setting flags
routesModified = false;
allSource = mSource;
}
+ @NonNull
public Passaggio.Source getPassaggiSourceIfAny(){
if(allSource==null || routesModified){
checkPassaggi();
diff --git a/src/it/reyboz/bustorino/backend/utils.java b/src/it/reyboz/bustorino/backend/utils.java
--- a/src/it/reyboz/bustorino/backend/utils.java
+++ b/src/it/reyboz/bustorino/backend/utils.java
@@ -1,6 +1,11 @@
package it.reyboz.bustorino.backend;
import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.util.Log;
import android.view.View;
public abstract class utils {
@@ -28,4 +33,67 @@
float ncols = ((float)width)/pixelsize;
return (int) Math.floor(ncols);
}
+
+ /**
+ * Check if there is an internet connection
+ * @param con context object to get the system service
+ * @return true if we are
+ */
+ public static boolean isConnected(Context con) {
+ ConnectivityManager connMgr = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
+ return networkInfo != null && networkInfo.isConnected();
+ }
+
+
+ ///////////////////// INTENT HELPER ////////////////////////////////////////////////////////////
+
+ /**
+ * Try to extract the bus stop ID from a URi
+ *
+ * @param uri The URL
+ * @return bus stop ID or null
+ */
+ public static String getBusStopIDFromUri(Uri uri) {
+ String busStopID;
+
+ // everithing catches fire when passing null to a switch.
+ String host = uri.getHost();
+ if (host == null) {
+ Log.e("ActivityMain", "Not an URL: " + uri);
+ return null;
+ }
+
+ switch (host) {
+ case "m.gtt.to.it":
+ // http://m.gtt.to.it/m/it/arrivi.jsp?n=1254
+ busStopID = uri.getQueryParameter("n");
+ if (busStopID == null) {
+ Log.e("ActivityMain", "Expected ?n from: " + uri);
+ }
+ break;
+ case "www.gtt.to.it":
+ case "gtt.to.it":
+ // http://www.gtt.to.it/cms/percorari/arrivi?palina=1254
+ busStopID = uri.getQueryParameter("palina");
+ if (busStopID == null) {
+ Log.e("ActivityMain", "Expected ?palina from: " + uri);
+ }
+ break;
+ default:
+ Log.e("ActivityMain", "Unexpected intent URL: " + uri);
+ busStopID = null;
+ }
+ return busStopID;
+ }
+
+ /**
+ * Open an URL in the default browser.
+ *
+ * @param url URL
+ */
+ public static void openIceweasel(String url, Context context) {
+ Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ context.startActivity(browserIntent1);
+ }
}
diff --git a/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java b/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
--- a/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
+++ b/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
@@ -276,7 +276,10 @@
*/
protected void showArrivalsSources(Palina p){
final Passaggio.Source source = p.getPassaggiSourceIfAny();
-
+ if (source == null){
+ Log.e(DEBUG_TAG, "NULL SOURCE");
+ return;
+ }
String source_txt;
switch (source){
case GTTJSON:
diff --git a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
--- a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
+++ b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
@@ -21,4 +21,9 @@
* @param ID the Stop ID
*/
void requestArrivalsForStopID(String ID);
+
+ /**
+ * Method to call when we want to hide the keyboard
+ */
+ void hideKeyboard();
}
diff --git a/src/it/reyboz/bustorino/fragments/FragmentHelper.java b/src/it/reyboz/bustorino/fragments/FragmentHelper.java
--- a/src/it/reyboz/bustorino/fragments/FragmentHelper.java
+++ b/src/it/reyboz/bustorino/fragments/FragmentHelper.java
@@ -18,18 +18,18 @@
package it.reyboz.bustorino.fragments;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.sqlite.SQLiteException;
+import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log;
+import android.widget.Toast;
+
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.Fetcher;
import it.reyboz.bustorino.backend.Palina;
import it.reyboz.bustorino.backend.Stop;
+import it.reyboz.bustorino.backend.utils;
import it.reyboz.bustorino.data.NextGenDB;
import it.reyboz.bustorino.middleware.*;
@@ -40,28 +40,30 @@
* Helper class to manage the fragments and their needs
*/
public class FragmentHelper {
- GeneralActivity act;
+ //GeneralActivity act;
+ private final FragmentListenerMain listenerMain;
+ private final WeakReference<FragmentManager> managerWeakRef;
private Stop lastSuccessfullySearchedBusStop;
//support for multiple frames
private final int secondaryFrameLayout;
- private final int swipeRefID;
private final int primaryFrameLayout;
+ private final Context context;
public static final int NO_FRAME = -3;
+ private static final String DEBUG_TAG = "BusTO FragmHelper";
private WeakReference<AsyncDataDownload> lastTaskRef;
- private NextGenDB newDBHelper;
private boolean shouldHaltAllActivities=false;
- public FragmentHelper(GeneralActivity act, int swipeRefID, int mainFrame) {
- this(act,swipeRefID,mainFrame,NO_FRAME);
+ public FragmentHelper(FragmentListenerMain listener, FragmentManager framan, Context context, int mainFrame) {
+ this(listener,framan, context,mainFrame,NO_FRAME);
}
- public FragmentHelper(GeneralActivity act, int swipeRefID, int primaryFrameLayout, int secondaryFrameLayout) {
- this.act = act;
- this.swipeRefID = swipeRefID;
+ public FragmentHelper(FragmentListenerMain listener, FragmentManager fraMan, Context context, int primaryFrameLayout, int secondaryFrameLayout) {
+ this.listenerMain = listener;
+ this.managerWeakRef = new WeakReference<>(fraMan);
this.primaryFrameLayout = primaryFrameLayout;
this.secondaryFrameLayout = secondaryFrameLayout;
- newDBHelper = new NextGenDB(act.getApplicationContext());
+ this.context = context.getApplicationContext();
}
/**
@@ -89,19 +91,23 @@
boolean sameFragment;
ArrivalsFragment arrivalsFragment;
- if(act==null || shouldHaltAllActivities) {
+ if(managerWeakRef.get()==null || shouldHaltAllActivities) {
//SOMETHING WENT VERY WRONG
+ Log.e(DEBUG_TAG, "We are asked for a new stop but we can't show anything");
return;
}
- FragmentManager fm = act.getSupportFragmentManager();
+ FragmentManager fm = managerWeakRef.get();
if(fm.findFragmentById(primaryFrameLayout) instanceof ArrivalsFragment) {
arrivalsFragment = (ArrivalsFragment) fm.findFragmentById(primaryFrameLayout);
+ //Log.d(DEBUG_TAG, "Arrivals are for fragment with same stop?");
sameFragment = arrivalsFragment.isFragmentForTheSameStop(p);
- } else
+ } else {
sameFragment = false;
+ Log.d(DEBUG_TAG, "We aren't showing an ArrivalsFragment");
+ }
setLastSuccessfullySearchedBusStop(p);
if(!sameFragment) {
@@ -122,7 +128,7 @@
// DO NOT CALL `setListAdapter` ever on arrivals fragment
arrivalsFragment.updateFragmentData(p);
- act.hideKeyboard();
+ listenerMain.hideKeyboard();
toggleSpinner(false);
}
@@ -132,9 +138,14 @@
* @param query String queried
*/
public void createFragmentFor(List<Stop> resultList,String query){
- act.hideKeyboard();
+ listenerMain.hideKeyboard();
StopListFragment listfragment = StopListFragment.newInstance(query);
- attachFragmentToContainer(act.getSupportFragmentManager(),listfragment,false,"search_"+query);
+ if(managerWeakRef.get()==null || shouldHaltAllActivities) {
+ //SOMETHING WENT VERY WRONG
+ Log.e(DEBUG_TAG, "We are asked for a new stop but we can't show anything");
+ return;
+ }
+ attachFragmentToContainer(managerWeakRef.get(),listfragment,false,"search_"+query);
listfragment.setStopList(resultList);
toggleSpinner(false);
@@ -145,12 +156,7 @@
* @param on new status of spinner system
*/
public void toggleSpinner(boolean on){
- if (act instanceof FragmentListenerMain)
- ((FragmentListenerMain) act).toggleSpinner(on);
- else {
- SwipeRefreshLayout srl = (SwipeRefreshLayout) act.findViewById(swipeRefID);
- srl.setRefreshing(false);
- }
+ listenerMain.toggleSpinner(on);
}
/**
@@ -171,21 +177,6 @@
//fm.executePendingTransactions();
}
- synchronized public int insertBatchDataInNextGenDB(ContentValues[] valuesArr,String tableName){
- if(newDBHelper !=null)
- try {
- return newDBHelper.insertBatchContent(valuesArr, tableName);
- } catch (SQLiteException exc){
- Log.w("DB Batch inserting: ","ERROR Inserting the data batch: ",exc.fillInStackTrace());
- return -2;
- }
- else return -1;
- }
-
- synchronized public ContentResolver getContentResolver(){
- return act.getContentResolver();
- }
-
public void setBlockAllActivities(boolean shouldI) {
this.shouldHaltAllActivities = shouldI;
}
@@ -208,13 +199,13 @@
case OK:
break;
case CLIENT_OFFLINE:
- act.showToastMessage(R.string.network_error, true);
+ showToastMessage(R.string.network_error, true);
break;
case SERVER_ERROR:
- if (act.isConnected()) {
- act.showToastMessage(R.string.parsing_error, true);
+ if (utils.isConnected(context)) {
+ showToastMessage(R.string.parsing_error, true);
} else {
- act.showToastMessage(R.string.network_error, true);
+ showToastMessage(R.string.network_error, true);
}
case PARSER_ERROR:
default:
@@ -229,9 +220,13 @@
}
}
- public void showShortToast(int message){
- if (act!=null)
- act.showToastMessage(message,true);
+ public void showToastMessage(int messageID, boolean short_lenght) {
+ final int length = short_lenght ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG;
+ if (context != null)
+ Toast.makeText(context, messageID, length).show();
+ }
+ private void showShortToast(int messageID){
+ showToastMessage(messageID, true);
}
}
diff --git a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -1,25 +1,43 @@
package it.reyboz.bustorino.fragments;
+import android.Manifest;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Build;
import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatImageButton;
+import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
+import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.zxing.integration.android.IntentIntegrator;
+
+import it.reyboz.bustorino.ActivityMain;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.ArrivalsFetcher;
import it.reyboz.bustorino.backend.FiveTAPIFetcher;
@@ -31,6 +49,10 @@
import it.reyboz.bustorino.backend.StopsFinderByName;
import it.reyboz.bustorino.data.UserDB;
import it.reyboz.bustorino.middleware.AsyncDataDownload;
+import it.reyboz.bustorino.util.Permissions;
+
+import static android.content.Context.LOCATION_SERVICE;
+import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSION_GIVEN;
/**
@@ -45,7 +67,8 @@
private static final String DEBUG_TAG = "BusTO - MainFragment";
- private CommonFragmentListener mListener;
+ public final static String FRAGMENT_TAG = "MainScreenFragment";
+
/// UI ELEMENTS //
private ImageButton addToFavorites;
private FragmentHelper fragmentHelper;
@@ -57,6 +80,8 @@
private Button hideHintButton;
private MenuItem actionHelpMenuItem;
private FloatingActionButton floatingActionButton;
+
+ private boolean setupOnAttached = true;
//private Snackbar snackbar;
/*
* Search mode
@@ -67,8 +92,38 @@
private int searchMode;
//private ImageButton addToFavorites;
private final ArrivalsFetcher[] arrivalsFetchers = new ArrivalsFetcher[]{new FiveTAPIFetcher(), new GTTJSONFetcher(), new FiveTScraperFetcher()};
+ //// HIDDEN BUT IMPORTANT ELEMENTS ////
+ FragmentManager fragMan;
+ Handler mainHandler;
+ private final Runnable refreshStop = new Runnable() {
+ public void run() {
+ if (fragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
+ ArrivalsFragment fragment = (ArrivalsFragment) fragMan.findFragmentById(R.id.resultFrame);
+ if (fragment == null){
+ //we create a new fragment, which is WRONG
+ new AsyncDataDownload(fragmentHelper, arrivalsFetchers,getContext()).execute();
+ } else{
+ String stopName = fragment.getStopID();
+
+ new AsyncDataDownload(fragmentHelper, fragment.getCurrentFetchersAsArray(), getContext()).execute(stopName);
+ }
+ } else //we create a new fragment, which is WRONG
+ new AsyncDataDownload(fragmentHelper, arrivalsFetchers, getContext()).execute();
+ }
+ };
+
+
+ /// LOCATION STUFF ///
+ boolean pendingNearbyStopsRequest = false;
+ LocationManager locmgr;
+
+ private final Criteria cr = new Criteria();
+
+ //// ACTIVITY ATTACHED (LISTENER ///
+ private CommonFragmentListener mListener;
+
public MainScreenFragment() {
// Required empty public constructor
}
@@ -104,11 +159,100 @@
hideHintButton = root.findViewById(R.id.hideHintButton);
swipeRefreshLayout = root.findViewById(R.id.listRefreshLayout);
floatingActionButton = root.findViewById(R.id.floatingActionButton);
+ busStopSearchByIDEditText.setSelectAllOnFocus(true);
+ busStopSearchByIDEditText
+ .setOnEditorActionListener((v, actionId, event) -> {
+ // IME_ACTION_SEARCH alphabetical option
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ onSearchClick(v);
+ return true;
+ }
+ return false;
+ });
+ busStopSearchByNameEditText
+ .setOnEditorActionListener((v, actionId, event) -> {
+ // IME_ACTION_SEARCH alphabetical option
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ onSearchClick(v);
+ return true;
+ }
+ return false;
+ });
+
+ swipeRefreshLayout
+ .setOnRefreshListener(() -> mainHandler.post(refreshStop));
+ swipeRefreshLayout.setColorSchemeResources(R.color.blue_500, R.color.orange_500);
+
+ floatingActionButton.setOnClickListener((this::onToggleKeyboardLayout));
+ hideHintButton.setOnClickListener(this::onHideHint);
+
+ AppCompatImageButton qrButton = root.findViewById(R.id.QRButton);
+ qrButton.setOnClickListener(this::onQRButtonClick);
+
+ AppCompatImageButton searchButton = root.findViewById(R.id.searchButton);
+ searchButton.setOnClickListener(this::onSearchClick);
+
+ // Fragment stuff
+ fragMan = getChildFragmentManager();
+ fragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
+
+ fragmentHelper = new FragmentHelper(this, getChildFragmentManager(), getContext(), R.id.resultFrame);
+ setSearchModeBusStopID();
+
+
+ cr.setAccuracy(Criteria.ACCURACY_FINE);
+ cr.setAltitudeRequired(false);
+ cr.setBearingRequired(false);
+ cr.setCostAllowed(true);
+ cr.setPowerRequirement(Criteria.NO_REQUIREMENT);
+
+ locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
return root;
}
+ @Override
+ public void onAttach(@NonNull Context context) {
+ super.onAttach(context);
+ mainHandler = new Handler();
+ if (context instanceof CommonFragmentListener) {
+ mListener = (CommonFragmentListener) context;
+ } else {
+ throw new RuntimeException(context.toString()
+ + " must implement CommonFragmentListener");
+ }
+ if (setupOnAttached){
+ //We want the nearby bus stops!
+ mainHandler.post(new NearbyStopsRequester(getContext(),cr, locListener));
+ //If there are no providers available, then, wait for them
+
+ setupOnAttached = false;
+ }
+
+ }
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mListener = null;
+ }
+ @Override
+ public void onResume() {
+
+ final Context con = getContext();
+ if (con != null)
+ locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
+ else {
+ Log.w(DEBUG_TAG, "Context is null at onResume");
+ }
+ super.onResume();
+ }
+ @Override
+ public void onPause() {
+ //mainHandler = null;
+ locmgr = null;
+ super.onPause();
+ }
/*
GUI METHODS
*/
@@ -139,7 +283,7 @@
} else { // searchMode == SEARCH_BY_NAME
String query = busStopSearchByNameEditText.getText().toString();
//new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper);
- new AsyncDataDownload(fragmentHelper, stopsFinderByNames).execute(query);
+ new AsyncDataDownload(fragmentHelper, stopsFinderByNames, getContext()).execute(query);
}
}
@@ -201,16 +345,15 @@
private void showHints() {
howDoesItWorkTextView.setVisibility(View.VISIBLE);
hideHintButton.setVisibility(View.VISIBLE);
- actionHelpMenuItem.setVisible(false);
+ //actionHelpMenuItem.setVisible(false);
}
private void hideHints() {
howDoesItWorkTextView.setVisibility(View.GONE);
hideHintButton.setVisibility(View.GONE);
- actionHelpMenuItem.setVisible(true);
+ //actionHelpMenuItem.setVisible(true);
}
- //TODO: toggle spinner from mainActivity
@Override
public void toggleSpinner(boolean enable) {
if (enable) {
@@ -227,13 +370,13 @@
private void prepareGUIForBusLines() {
swipeRefreshLayout.setEnabled(true);
swipeRefreshLayout.setVisibility(View.VISIBLE);
- actionHelpMenuItem.setVisible(true);
+ //actionHelpMenuItem.setVisible(true);
}
private void prepareGUIForBusStops() {
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setVisibility(View.VISIBLE);
- actionHelpMenuItem.setVisible(false);
+ //actionHelpMenuItem.setVisible(false);
}
@@ -250,10 +393,9 @@
*/
@Override
public void readyGUIfor(FragmentKind fragmentType) {
- throw new UnsupportedOperationException();
- /*
+
hideKeyboard();
- //TODO: fix this
+
//if we are getting results, already, stop waiting for nearbyStops
if (pendingNearbyStopsRequest && (fragmentType == FragmentKind.ARRIVALS || fragmentType == FragmentKind.STOPS)) {
locmgr.removeUpdates(locListener);
@@ -277,7 +419,7 @@
return;
}
// Shows hints
- */
+
}
@@ -293,16 +435,112 @@
if (fragment != null && fragment.getStopID() != null && fragment.getStopID().equals(ID)){
// Run with previous fetchers
//fragment.getCurrentFetchers().toArray()
- new AsyncDataDownload(fragmentHelper,fragment.getCurrentFetchersAsArray()).execute(ID);
+ new AsyncDataDownload(fragmentHelper,fragment.getCurrentFetchersAsArray(), getContext()).execute(ID);
} else{
- new AsyncDataDownload(fragmentHelper, arrivalsFetchers).execute(ID);
+ new AsyncDataDownload(fragmentHelper, arrivalsFetchers, getContext()).execute(ID);
}
}
else {
- new AsyncDataDownload(fragmentHelper,arrivalsFetchers).execute(ID);
+ new AsyncDataDownload(fragmentHelper,arrivalsFetchers, getContext()).execute(ID);
Log.d("MainActiv", "Started search for arrivals of stop " + ID);
}
}
+ /////////// LOCATION METHODS //////////
+ final LocationListener locListener = new LocationListener() {
+ @Override
+ public void onLocationChanged(Location location) {
+ Log.d(DEBUG_TAG, "Location changed");
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ Log.d(DEBUG_TAG, "Location provider status: " + status);
+ if (status == LocationProvider.AVAILABLE) {
+ resolveStopRequest(provider);
+ }
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ resolveStopRequest(provider);
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ }
+ };
+
+ private void resolveStopRequest(String provider) {
+ Log.d(DEBUG_TAG, "Provider " + provider + " got enabled");
+ if (locmgr != null && mainHandler != null && pendingNearbyStopsRequest && locmgr.getProvider(provider).meetsCriteria(cr)) {
+ pendingNearbyStopsRequest = false;
+ mainHandler.post(new NearbyStopsRequester(getContext(), cr, locListener));
+ }
+ }
+
+ /**
+ * Run location requests separately and asynchronously
+ */
+ class NearbyStopsRequester implements Runnable {
+ Context appContext;
+ Criteria cr;
+ LocationListener listener;
+
+ public NearbyStopsRequester(Context appContext, Criteria criteria, LocationListener listener) {
+ this.appContext = appContext.getApplicationContext();
+ this.cr = criteria;
+ this.listener = listener;
+ }
+
+ @Override
+ public void run() {
+ final boolean canRunPosition = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || getOption(LOCATION_PERMISSION_GIVEN, false);
+ final boolean noPermission = ActivityCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
+ ActivityCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;
+
+ //if we don't have the permission, we have to ask for it, if we haven't
+ // asked too many times before
+ if (noPermission) {
+ if (!canRunPosition) {
+ pendingNearbyStopsRequest = true;
+ Permissions.assertLocationPermissions(appContext,getActivity());
+ Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
+ return;
+ } else {
+ Toast.makeText(appContext, "Asked for permission position too many times", Toast.LENGTH_LONG).show();
+ }
+ } else setOption(LOCATION_PERMISSION_GIVEN, true);
+
+ LocationManager locManager = (LocationManager) appContext.getSystemService(LOCATION_SERVICE);
+ if (locManager == null) {
+ Log.e(DEBUG_TAG, "location manager is nihil, cannot create NearbyStopsFragment");
+ return;
+ }
+ if (Permissions.anyLocationProviderMatchesCriteria(locManager, cr, true)
+ && fragmentHelper.getLastSuccessfullySearchedBusStop() == null
+ && !fragMan.isDestroyed()) {
+ //Go ahead with the request
+ Log.d("mainActivity", "Recreating stop fragment");
+ swipeRefreshLayout.setVisibility(View.VISIBLE);
+ NearbyStopsFragment fragment = NearbyStopsFragment.newInstance(NearbyStopsFragment.TYPE_STOPS);
+ Fragment oldFrag = fragMan.findFragmentById(R.id.resultFrame);
+ FragmentTransaction ft = fragMan.beginTransaction();
+ if (oldFrag != null)
+ ft.remove(oldFrag);
+ ft.add(R.id.resultFrame, fragment, "nearbyStop_correct");
+ ft.commit();
+ //fragMan.executePendingTransactions();
+ pendingNearbyStopsRequest = false;
+ } else if (!Permissions.anyLocationProviderMatchesCriteria(locManager, cr, true)) {
+ //Wait for the providers
+ Log.d(DEBUG_TAG, "Queuing position request");
+ pendingNearbyStopsRequest = true;
+
+ locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, 0.1f, listener);
+ }
+
+ }
+ }
}
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
--- a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
+++ b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
@@ -139,15 +139,15 @@
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_nearby_stops, container, false);
- gridRecyclerView = (RecyclerView) root.findViewById(R.id.stopGridRecyclerView);
+ gridRecyclerView = root.findViewById(R.id.stopGridRecyclerView);
gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP));
gridRecyclerView.setLayoutManager(gridLayoutManager);
gridRecyclerView.setHasFixedSize(false);
- circlingProgressBar = (ProgressBar) root.findViewById(R.id.loadingBar);
- flatProgressBar = (ProgressBar) root.findViewById(R.id.horizontalProgressBar);
- messageTextView = (TextView) root.findViewById(R.id.messageTextView);
- titleTextView = (TextView) root.findViewById(R.id.titleTextView);
- switchButton = (AppCompatButton) root.findViewById(R.id.switchButton);
+ circlingProgressBar = root.findViewById(R.id.loadingBar);
+ flatProgressBar = root.findViewById(R.id.horizontalProgressBar);
+ messageTextView = root.findViewById(R.id.messageTextView);
+ titleTextView = root.findViewById(R.id.titleTextView);
+ switchButton = root.findViewById(R.id.switchButton);
preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
@@ -217,6 +217,7 @@
@Override
public void onAttach(Context context) {
super.onAttach(context);
+ /// TODO: RISOLVERE PROBLEMA: il context qui e' l'Activity non il Fragment
if (context instanceof FragmentListenerMain) {
mListener = (FragmentListenerMain) context;
} else {
diff --git a/src/it/reyboz/bustorino/middleware/AppLocationManager.java b/src/it/reyboz/bustorino/middleware/AppLocationManager.java
--- a/src/it/reyboz/bustorino/middleware/AppLocationManager.java
+++ b/src/it/reyboz/bustorino/middleware/AppLocationManager.java
@@ -104,6 +104,7 @@
Log.d(DEBUG_TAG,"Added new stop requester, instance of "+req.getClass().getSimpleName());
}
if(requestersRef.size()>0){
+ Log.d(DEBUG_TAG,"Requesting position updates");
requestGPSPositionUpdates();
}
@@ -136,7 +137,7 @@
@Override
public void onLocationChanged(Location location) {
- Log.d("GPSLocationListener","found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy());
+ Log.d(DEBUG_TAG,"found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy());
ListIterator<WeakReference<LocationRequester>> iter = requestersRef.listIterator();
int new_min_interval = Integer.MAX_VALUE;
while(iter.hasNext()){
@@ -175,16 +176,19 @@
}
oldGPSLocStatus = status;
}
+ Log.d(DEBUG_TAG, "Provider: "+provider+" status: "+status);
}
@Override
public void onProviderEnabled(String provider) {
requestGPSPositionUpdates();
+ Log.d(DEBUG_TAG, "Provider: "+provider+" enabled");
}
@Override
public void onProviderDisabled(String provider) {
locMan.removeUpdates(this);
+ Log.d(DEBUG_TAG, "Provider: "+provider+" disabled");
}
/**
diff --git a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
--- a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
+++ b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
@@ -19,6 +19,7 @@
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.content.Context;
import android.database.SQLException;
import android.net.Uri;
import android.os.AsyncTask;
@@ -28,6 +29,7 @@
import it.reyboz.bustorino.backend.*;
import it.reyboz.bustorino.data.AppDataProvider;
+import it.reyboz.bustorino.data.NextGenDB;
import it.reyboz.bustorino.fragments.FragmentHelper;
import it.reyboz.bustorino.data.NextGenDB.Contract.*;
@@ -51,13 +53,15 @@
WeakReference<FragmentHelper> helperRef;
private final ArrayList<Thread> otherActivities = new ArrayList<>();
private final Fetcher[] theFetchers;
+ private Context context;
- public AsyncDataDownload(FragmentHelper fh, @NonNull Fetcher[] fetchers) {
+ public AsyncDataDownload(FragmentHelper fh, @NonNull Fetcher[] fetchers, Context context) {
RequestType type;
helperRef = new WeakReference<>(fh);
fh.setLastTaskRef(new WeakReference<>(this));
res = new AtomicReference<>();
+ this.context = context.getApplicationContext();
theFetchers = fetchers;
if (theFetchers.length < 1){
@@ -118,7 +122,7 @@
List<Route> branches = ((FiveTAPIFetcher) f).getDirectionsForStop(stopID,gres);
if(gres.get() == Fetcher.result.OK){
p.addInfoFromRoutes(branches);
- Thread t = new Thread(new BranchInserter(branches,fh,stopID));
+ Thread t = new Thread(new BranchInserter(branches, context));
t.start();
otherActivities.add(t);
@@ -236,11 +240,13 @@
public class BranchInserter implements Runnable{
private final List<Route> routesToInsert;
- private final FragmentHelper fragmentHelper;
+ private final Context context;
+ private final NextGenDB nextGenDB;
- public BranchInserter(List<Route> routesToInsert,FragmentHelper fh,String stopID) {
+ public BranchInserter(List<Route> routesToInsert,@NonNull Context con) {
this.routesToInsert = routesToInsert;
- this.fragmentHelper = fh;
+ this.context = con;
+ nextGenDB = new NextGenDB(context);
}
@Override
@@ -298,7 +304,7 @@
}
}
starttime = System.currentTimeMillis();
- ContentResolver cr = fragmentHelper.getContentResolver();
+ ContentResolver cr = context.getContentResolver();
try {
cr.bulkInsert(Uri.parse("content://" + AppDataProvider.AUTHORITY + "/branches/"), values);
endtime = System.currentTimeMillis();
@@ -313,7 +319,7 @@
starttime = System.currentTimeMillis();
ContentValues[] valArr = connectionsVals.toArray(new ContentValues[0]);
Log.d("DataDownloadInsert","inserting "+valArr.length+" connections");
- int rows = fragmentHelper.insertBatchDataInNextGenDB(valArr,ConnectionsTable.TABLE_NAME);
+ int rows = nextGenDB.insertBatchContent(valArr,ConnectionsTable.TABLE_NAME);
endtime = System.currentTimeMillis();
Log.d("DataDownload","Inserted connections found, took "+(endtime-starttime)+" ms, inserted "+rows+" rows");
}
diff --git a/src/it/reyboz/bustorino/middleware/GeneralActivity.java b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
--- a/src/it/reyboz/bustorino/middleware/GeneralActivity.java
+++ b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
@@ -63,23 +63,12 @@
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){
diff --git a/src/it/reyboz/bustorino/util/Permissions.java b/src/it/reyboz/bustorino/util/Permissions.java
new file mode 100644
--- /dev/null
+++ b/src/it/reyboz/bustorino/util/Permissions.java
@@ -0,0 +1,41 @@
+package it.reyboz.bustorino.util;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Criteria;
+import android.location.LocationManager;
+import android.util.Log;
+
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.util.List;
+
+public class Permissions {
+ final static public String DEBUG_TAG = "BusTO -Permissions";
+
+ final static public int PERMISSION_REQUEST_POSITION = 33;
+ final static public String LOCATION_PERMISSION_GIVEN = "loc_permission";
+ final static public int STORAGE_PERMISSION_REQ = 291;
+
+ final static public int PERMISSION_OK = 0;
+ final static public int PERMISSION_ASKING = 11;
+ final static public int PERMISSION_NEG_CANNOT_ASK = -3;
+
+ public static boolean anyLocationProviderMatchesCriteria(LocationManager mng, Criteria cr, boolean enabled) {
+ List<String> providers = mng.getProviders(cr, enabled);
+ Log.d(DEBUG_TAG, "Getting enabled location providers: ");
+ for (String s : providers) {
+ Log.d(DEBUG_TAG, "Provider " + s);
+ }
+ return providers.size() > 0;
+ }
+
+ public static void assertLocationPermissions(Context con, Activity activity) {
+ if(ContextCompat.checkSelfPermission(con, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
+ ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_POSITION);
+ }
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 8, 05:35 (20 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1426101
Default Alt Text
D53.1765168548.diff (70 KB)

Event Timeline