Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F6999121
D53.1765104665.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
70 KB
Referenced Files
None
Subscribers
None
D53.1765104665.diff
View Options
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");
@@ -466,7 +471,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);
}
}
@@ -483,7 +488,7 @@
//if we sent a request for a new NearbyStopsFragment
if (pendingNearbyStopsRequest) {
pendingNearbyStopsRequest = false;
- theHandler.post(new NearbyStopsRequester());
+ theHandler.post(new NearbyStopsRequester(this));
}
} else {
@@ -532,13 +537,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);
}
}
@@ -606,7 +611,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));
}
}
@@ -639,6 +644,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);
@@ -650,7 +662,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 {
@@ -700,26 +712,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
@@ -838,55 +830,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
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 11:51 (2 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1427151
Default Alt Text
D53.1765104665.diff (70 KB)
Attached To
Mode
D53: Make new drawer activity work with the main screen
Attached
Detach File
Event Timeline
Log In to Comment