Page MenuHomeGitPull.it

D57.1732749017.diff
No OneTemporary

Size
62 KB
Referenced Files
None
Subscribers
None

D57.1732749017.diff

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -22,7 +22,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<activity
- android:name=".ActivityMain"
+ android:name=".ActivityPrincipal"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
@@ -68,7 +68,7 @@
<activity
android:name=".ActivityAbout"
android:label="@string/about"
- android:parentActivityName=".ActivityMain"
+ android:parentActivityName=".ActivityPrincipal"
android:theme="@style/AboutTheme">
<!-- API < 16: -->
@@ -99,8 +99,10 @@
android:value=".ActivityMain"/>
</activity>
- <activity android:name=".ActivityPrincipal"
- android:label="Principal" >
+ <activity
+ android:name=".ActivityMain"
+ android:screenOrientation="portrait"
+ android:label="@string/app_name" >
</activity>
<provider
@@ -122,11 +124,11 @@
<activity
android:name=".ActivitySettings"
android:label="@string/title_activity_settings"
- android:parentActivityName=".ActivityMain"
+ android:parentActivityName=".ActivityPrincipal"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value="it.reyboz.bustorino.ActivityMain"/>
+ android:value="it.reyboz.bustorino.ActivityPrincipal"/>
</activity>
</application>
diff --git a/build.gradle b/build.gradle
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.2'
+ classpath 'com.android.tools.build:gradle:4.1.3'
}
ext {
//libraries versions
@@ -92,7 +92,7 @@
implementation "androidx.work:work-runtime:$work_version"
- implementation 'com.google.android.material:material:1.3.0'
+ implementation "com.google.android.material:material:1.3.0"
implementation 'org.jsoup:jsoup:1.13.1'
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Oct 01 23:03:06 CEST 2020
+#Sat Apr 24 16:03:07 CEST 2021
distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
+zipStoreBase=GRADLE_USER_HOME
diff --git a/res/layout/nav_header.xml b/res/layout/nav_header.xml
--- a/res/layout/nav_header.xml
+++ b/res/layout/nav_header.xml
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical" android:layout_width="match_parent"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/grey_100"
+ android:background="@color/teal_300"
+ android:gravity="bottom"
+ android:minHeight="120dp"
+ android:orientation="vertical"
android:padding="16dp"
- android:theme="@style/ThemeOverlay.AppCompat.Dark"
- android:gravity="bottom">
-
+ android:theme="@style/ThemeOverlay.AppCompat.Dark">
+ <!--
<ImageView
android:id="@+id/nav_img"
android:layout_width="match_parent"
android:layout_height="100dp"
android:minHeight="40dp"
app:srcCompat="@drawable/ic_mars2020" />
+ -->
<TextView
@@ -21,10 +24,10 @@
android:layout_height="wrap_content"
- android:text="@string/app_name"
+ android:text="@string/app_name_full"
android:textAppearance="@style/ThemeOverlay.AppCompat.Light"
- android:textSize="20sp"
- />
+ android:textColor="#FFFFFF"
+ android:textSize="20sp" />
</LinearLayout>
\ No newline at end of file
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -102,7 +102,7 @@
<string name="settings_group_database">Gestione del database</string>
<string name="settings_reset_database">Comincia aggiornamento manuale del database</string>
-
+ <string name="enable_position_message_map">Consenti l\'accesso alla posizione per mostrarla sulla mappa</string>
<string name="enableGpsText">Abilitare il GPS</string>
<string name="settings_search_radius">Raggio di ricerca</string>
<string name="settings_experimental">Funzionalità sperimentali</string>
@@ -134,10 +134,11 @@
<string name="too_many_permission_asks">Chiesto troppe volte per il permesso %1$s</string>
<string name="permission_storage_maps_msg">Non si può usare questa funzionalità senza il permesso di archivio</string>
<string name="storage_permission">di archivio</string>
- <string name="message_crash">L\'app è andata in crash. Invia il report agli sviluppatori toccando OK.
- \n Il report potrebbe contenere informazioni sulla tua configurazione del telefono, o sullo stato al momento del crash.
- \n Tutte le informazioni sensibili nel report verranno utilizzate solo per scopi diagnostici dagli sviluppatori, e non verranno mai pubblicate e/o divulgate.</string>
- <string name="acra_email_message">L\'applicazione è crashata, e il crash report è stato messo negli allegati. Se vuoi, descrivi cosa stavi facendo prima del crash: \n</string>
+ <string name="message_crash">Un bug ha fatto crashare l\'app!
+ \nPremi \"OK\" per inviare il report agli sviluppatori via email, così potranno scovare e risolvere il tuo bug!
+ \nIl report contiene piccole informazioni non sensibili sulla configurazione del tuo telefono e sullo stato dell\'app al momento del crash.
+ </string>
+ <string name="acra_email_message">L\'applicazione è crashata, e il crash report è stato messo negli allegati. Se vuoi, descrivi cosa stavi facendo prima che si interrompesse: \n</string>
<string name="nav_arrivals_text">Arrivi</string>
<string name="nav_map_text">Mappa</string>
<string name="nav_favorites_text">Preferiti</string>
@@ -145,5 +146,7 @@
<string name="drawer_close">Chiudi drawer</string>
<string name="experiments">Esperimenti</string>
<string name="donate_now">Offrici un caffè</string>
+ <string name="map">Mappa</string>
+ <string name="stop_search_view_title">Ricerca fermate</string>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -14,5 +14,6 @@
<color name="accent">#009688</color>-->
<color name="metro_red">#DE0908</color>
<color name="blue_extraurbano">#2060DD</color>
+ <color name="white">#FFFFFF</color>
</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2,6 +2,7 @@
<resources>
<string name="app_name" translatable="false">BusTO</string>
+ <string name="app_name_full" translatable="false">Libre BusTO</string>
<string name="app_name_debug" translatable="false">BusTO Debug</string>
<string name="app_description">You\'re using the latest in technology when it comes to respecting your privacy.
</string>
@@ -115,6 +116,7 @@
<string name="settings_group_database">Database management</string>
<string name="settings_reset_database">Launch manual database update</string>
+ <string name="enable_position_message_map">Allow access to position to show it on the map</string>
<string name="enableGpsText">Please enable GPS</string>
<string name="database_update_message">Database update in progress&#8230;</string>
<string name="bus_arriving_at">is arriving at</string>
@@ -147,10 +149,9 @@
<string name="too_many_permission_asks">Asked for %1$s permission too many times</string>
<string name="permission_storage_maps_msg">Cannot use the map with the storage permission!</string>
<string name="storage_permission">storage</string>
- <string name="message_crash">The application has crashed. If you want, you can send the send the report via email to
- the developers by pressing \"OK\".
- \n Note that sensitive information may be contained in the report, and if so, it will be only used for
- diagnostic purposes by the developers, and never published.
+ <string name="message_crash">The application has crashed because you encountered a bug.
+ \nIf you want, you can help the developers by sending the crash report via email.
+ \nNote that no sensitive data is contained in the report, just small bits of info on your phone and app configuration/state.
</string>
<string name="acra_email_message">The application crashed and the crash report is in the attachments. Please
describe what you were doing before the crash: \n
@@ -162,4 +163,6 @@
<string name="drawer_close">Close navigation drawer</string>
<string name="experiments">Experiments</string>
<string name="donate_now">Buy us a coffee</string>
+ <string name="map">Map</string>
+ <string name="stop_search_view_title">Search by stop</string>
</resources>
diff --git a/src/debug/AndroidManifest.xml b/src/debug/AndroidManifest.xml
--- a/src/debug/AndroidManifest.xml
+++ b/src/debug/AndroidManifest.xml
@@ -11,7 +11,7 @@
tools:replace="android:label"
>
<activity
- android:name=".ActivityMain"
+ android:name=".ActivityPrincipal"
android:label="@string/app_name_debug"
tools:replace="android:label"
/>
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
@@ -34,6 +34,7 @@
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
@@ -654,21 +655,19 @@
@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(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
- ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;
+ //final boolean canRunPosition = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || getOption(LOCATION_PERMISSION_GIVEN, false);
+ final boolean noPermission = ContextCompat.checkSelfPermission(getApplicationContext(),
+ Manifest.permission.ACCESS_FINE_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(getApplicationContext(),runningAct);
Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
return;
- } else {
- Toast.makeText(getApplicationContext(), "Asked for permission position too many times", Toast.LENGTH_LONG).show();
- }
+
} else setOption(LOCATION_PERMISSION_GIVEN, true);
LocationManager locManager = (LocationManager) getSystemService(LOCATION_SERVICE);
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,13 +1,16 @@
package it.reyboz.bustorino;
+import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -30,6 +33,7 @@
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
+import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import it.reyboz.bustorino.backend.Stop;
@@ -82,11 +86,32 @@
drawerToggle.syncState();
mDrawer.addDrawerListener(drawerToggle);
+ mDrawer.addDrawerListener(new DrawerLayout.DrawerListener() {
+ @Override
+ public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
+
+ }
+
+ @Override
+ public void onDrawerOpened(@NonNull View drawerView) {
+ hideKeyboard();
+ }
+
+ @Override
+ public void onDrawerClosed(@NonNull View drawerView) {
+
+ }
+
+ @Override
+ public void onDrawerStateChanged(int newState) {
+ }
+ });
+
+
mNavView = findViewById(R.id.nvView);
setupDrawerContent(mNavView);
-
/// LEGACY CODE
//---------------------------- START INTENT CHECK QUEUE ------------------------------------
@@ -135,8 +160,6 @@
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)
@@ -189,6 +212,11 @@
return new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.drawer_open, R.string.drawer_close);
}
+
+ /**
+ * Setup drawer actions
+ * @param navigationView the navigation view on which to set the callbacks
+ */
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
menuItem -> {
@@ -213,7 +241,21 @@
return true;
} else if(menuItem.getItemId() == R.id.nav_map_item){
closeDrawerIfOpen();
- createAndShowMapFragment(null);
+ final String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
+ int result = askForPermissionIfNeeded(permission, STORAGE_PERMISSION_REQ);
+ switch (result) {
+ case PERMISSION_OK:
+ createAndShowMapFragment(null);
+ break;
+ case PERMISSION_ASKING:
+ permissionDoneRunnables.put(permission,
+ () -> createAndShowMapFragment(null));
+ break;
+ case PERMISSION_NEG_CANNOT_ASK:
+ String storage_perm = getString(R.string.storage_permission);
+ String text = getString(R.string.too_many_permission_asks, storage_perm);
+ Toast.makeText(getApplicationContext(),text, Toast.LENGTH_LONG).show();
+ }
return true;
}
//selectDrawerItem(menuItem);
@@ -256,6 +298,27 @@
return super.onCreateOptionsMenu(menu);
}
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode==STORAGE_PERMISSION_REQ){
+ final String storagePerm = Manifest.permission.WRITE_EXTERNAL_STORAGE;
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ Log.d(DEBUG_TAG, "Permissions check: " + Arrays.toString(permissions));
+
+ if (permissionDoneRunnables.containsKey(storagePerm)) {
+ Runnable toRun = permissionDoneRunnables.get(storagePerm);
+ if (toRun != null)
+ toRun.run();
+ permissionDoneRunnables.remove(storagePerm);
+ }
+ } else {
+ //permission denied
+ showToastMessage(R.string.permission_storage_maps_msg, false);
+ }
+ }
+ }
+
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
@@ -387,21 +450,35 @@
if (probableFragment!=null){
probableFragment.readyGUIfor(fragmentType);
}
+ int titleResId;
switch (fragmentType){
case MAP:
mNavView.setCheckedItem(R.id.nav_map_item);
+ titleResId = R.string.map;
break;
case FAVORITES:
mNavView.setCheckedItem(R.id.nav_favorites_item);
+ titleResId = R.string.nav_favorites_text;
break;
case ARRIVALS:
- case NEARBY_STOPS:
+ titleResId = R.string.nav_arrivals_text;
+ mNavView.setCheckedItem(R.id.nav_arrivals);
+ break;
case STOPS:
+ titleResId = R.string.stop_search_view_title;
+ mNavView.setCheckedItem(R.id.nav_arrivals);
+ break;
case MAIN_SCREEN_FRAGMENT:
+ case NEARBY_STOPS:
case NEARBY_ARRIVALS:
+ titleResId=R.string.app_name_full;
mNavView.setCheckedItem(R.id.nav_arrivals);
break;
+ default:
+ titleResId = 0;
}
+ if(getSupportActionBar()!=null && titleResId!=0)
+ getSupportActionBar().setTitle(titleResId);
}
@Override
diff --git a/src/it/reyboz/bustorino/BustoApp.java b/src/it/reyboz/bustorino/BustoApp.java
--- a/src/it/reyboz/bustorino/BustoApp.java
+++ b/src/it/reyboz/bustorino/BustoApp.java
@@ -5,16 +5,20 @@
import org.acra.ACRA;
import org.acra.BuildConfig;
-import org.acra.annotation.AcraCore;
-import org.acra.annotation.AcraDialog;
-import org.acra.annotation.AcraMailSender;
+import org.acra.ReportField;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.DialogConfigurationBuilder;
import org.acra.config.MailSenderConfigurationBuilder;
import org.acra.data.StringFormat;
+import static org.acra.ReportField.*;
+
public class BustoApp extends Application {
+ private static final ReportField[] REPORT_FIELDS = {REPORT_ID, APP_VERSION_CODE, APP_VERSION_NAME,
+ PACKAGE_NAME, PHONE_MODEL, BRAND, PRODUCT, ANDROID_VERSION, BUILD_CONFIG, CUSTOM_DATA,
+ IS_SILENT, STACK_TRACE, INITIAL_CONFIGURATION, CRASH_CONFIGURATION, DISPLAY, USER_COMMENT,
+ USER_APP_START_DATE, USER_CRASH_DATE, LOGCAT, SHARED_PREFERENCES};
@Override
protected void attachBaseContext(Context base) {
@@ -30,7 +34,9 @@
builder.getPluginConfigurationBuilder(DialogConfigurationBuilder.class).setResText(R.string.message_crash)
.setResTheme(R.style.AppTheme)
.setEnabled(true);
+ builder.setReportContent(REPORT_FIELDS);
if (!it.reyboz.bustorino.BuildConfig.DEBUG)
ACRA.init(this, builder);
+
}
}
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
@@ -6,6 +6,7 @@
import android.net.NetworkInfo;
import android.net.Uri;
import android.util.Log;
+import android.util.TypedValue;
import android.view.View;
public abstract class utils {
@@ -24,9 +25,15 @@
return Math.abs(EarthRadius*c);
}
+ /*
public static int convertDipToPixels(Context con,float dips)
{
return (int) (dips * con.getResources().getDisplayMetrics().density + 0.5f);
+ }
+ */
+
+ public static float convertDipToPixels(Context con, float dp){
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,con.getResources().getDisplayMetrics());
}
public static int calculateNumColumnsFromSize(View containerView, int pixelsize){
int width = containerView.getWidth();
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
@@ -185,6 +185,7 @@
}
});
String displayName = getArguments().getString(STOP_TITLE);
+ if(displayName!=null)
setTextViewMessage(String.format(
getString(R.string.passages), displayName));
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
@@ -1,5 +1,7 @@
package it.reyboz.bustorino.fragments;
+import android.view.View;
+
public interface CommonFragmentListener {
diff --git a/src/it/reyboz/bustorino/fragments/FavoritesFragment.java b/src/it/reyboz/bustorino/fragments/FavoritesFragment.java
--- a/src/it/reyboz/bustorino/fragments/FavoritesFragment.java
+++ b/src/it/reyboz/bustorino/fragments/FavoritesFragment.java
@@ -23,6 +23,7 @@
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
+import java.util.ArrayList;
import java.util.List;
import it.reyboz.bustorino.ActivityFavorites;
@@ -93,6 +94,8 @@
FavoritesViewModel model = new ViewModelProvider(this).get(FavoritesViewModel.class);
model.getFavorites().observe(getViewLifecycleOwner(), this::showStops);
+
+ showStops(new ArrayList<>());
return root;
}
@Override
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
@@ -5,12 +5,12 @@
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.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageButton;
@@ -38,6 +38,8 @@
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.zxing.integration.android.IntentIntegrator;
+import java.util.Map;
+
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.ArrivalsFetcher;
import it.reyboz.bustorino.backend.FiveTAPIFetcher;
@@ -45,11 +47,14 @@
import it.reyboz.bustorino.backend.FiveTStopsFetcher;
import it.reyboz.bustorino.backend.GTTJSONFetcher;
import it.reyboz.bustorino.backend.GTTStopsFetcher;
+import it.reyboz.bustorino.backend.Palina;
import it.reyboz.bustorino.backend.StopsFinderByName;
+import it.reyboz.bustorino.middleware.AppLocationManager;
import it.reyboz.bustorino.middleware.AsyncDataDownload;
+import it.reyboz.bustorino.util.LocationCriteria;
import it.reyboz.bustorino.util.Permissions;
-import static android.content.Context.LOCATION_SERVICE;
+import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSIONS;
import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSION_GIVEN;
@@ -112,14 +117,74 @@
}
};
+ /// LOCATION STUFF ///
+ boolean pendingNearbyStopsRequest = false;
+ boolean locationPermissionGranted, locationPermissionAsked = false;
+ AppLocationManager locationManager;
+ private final LocationCriteria cr = new LocationCriteria(2000, 10000);
+ //Location
+ private AppLocationManager.LocationRequester requester = new AppLocationManager.LocationRequester() {
+ @Override
+ public void onLocationChanged(Location loc) {
- /// LOCATION STUFF ///
- boolean pendingNearbyStopsRequest = false;
- LocationManager locmgr;
+ }
+
+ @Override
+ public void onLocationStatusChanged(int status) {
+
+ if(status == AppLocationManager.LOCATION_GPS_AVAILABLE && !isNearbyFragmentShown()){
+ //request Stops
+ pendingNearbyStopsRequest = false;
+
+ mainHandler.post(new NearbyStopsRequester(getContext(), cr));
+ }
+ }
+
+ @Override
+ public long getLastUpdateTimeMillis() {
+ return 50;
+ }
+
+ @Override
+ public LocationCriteria getLocationCriteria() {
+ return cr;
+ }
+
+ @Override
+ public void onLocationProviderAvailable() {
+ //Log.w(DEBUG_TAG, "pendingNearbyStopRequest: "+pendingNearbyStopsRequest);
+ if(!isNearbyFragmentShown()){
+ pendingNearbyStopsRequest = false;
+ mainHandler.post(new NearbyStopsRequester(getContext(), cr));
+ }
+ }
+
+ @Override
+ public void onLocationDisabled() {
+
+ }
+ };
+ private final ActivityResultLauncher<String[]> requestPermissionLauncher =
+ registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
+ @Override
+ public void onActivityResult(Map<String, Boolean> result) {
+ if(result==null || result.get(Manifest.permission.ACCESS_COARSE_LOCATION) == null
+ ||result.get(Manifest.permission.ACCESS_FINE_LOCATION) ) return;
+
+ if(result.get(Manifest.permission.ACCESS_COARSE_LOCATION) && result.get(Manifest.permission.ACCESS_FINE_LOCATION)){
+ locationPermissionGranted = true;
+ Log.w(DEBUG_TAG, "Starting position");
+ if (mListener!= null && getContext()!=null){
+ if (locationManager==null)
+ locationManager = AppLocationManager.getInstance(getContext());
+ locationManager.addLocationRequestFor(requester);
+ }
+ }
+ }
+ });
- private final Criteria cr = new Criteria();
//// ACTIVITY ATTACHED (LISTENER ///
private CommonFragmentListener mListener;
@@ -208,7 +273,7 @@
cr.setCostAllowed(true);
cr.setPowerRequirement(Criteria.NO_REQUIREMENT);
- locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
+ locationManager = AppLocationManager.getInstance(getContext());
Log.d(DEBUG_TAG, "OnCreateView, savedInstanceState null: "+(savedInstanceState==null));
@@ -272,16 +337,15 @@
if (setupOnAttached) {
if (pendingStopID==null)
//We want the nearby bus stops!
- mainHandler.post(new NearbyStopsRequester(getContext(), cr, locListener));
+ mainHandler.post(new NearbyStopsRequester(context, cr));
else{
///TODO: if there is a stop displayed, we need to hold the update
}
- //If there are no providers available, then, wait for them
setupOnAttached = false;
- } else {
}
+
}
@Override
public void onDetach() {
@@ -295,8 +359,24 @@
public void onResume() {
final Context con = getContext();
- if (con != null)
- locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
+ Log.w(DEBUG_TAG, "OnResume called");
+ if (con != null) {
+ if(locationManager==null)
+ locationManager = AppLocationManager.getInstance(con);
+
+ if(Permissions.locationPermissionGranted(con)){
+ Log.d(DEBUG_TAG, "Location permission OK");
+ if(!locationManager.isRequesterRegistered(requester))
+ locationManager.addLocationRequestFor(requester);
+ } else if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){
+ //we have already asked for the location, and we should show an explanation in order
+ // to ask again (TODO)
+ //do nothing
+ } else{
+ //request permission
+ requestPermissionLauncher.launch(Permissions.LOCATION_PERMISSIONS);
+ }
+ }
else {
Log.w(DEBUG_TAG, "Context is null at onResume");
}
@@ -324,7 +404,7 @@
@Override
public void onPause() {
//mainHandler = null;
- locmgr = null;
+ locationManager.removeLocationRequestFor(requester);
super.onPause();
}
@@ -384,10 +464,8 @@
}
////////////////////////////////////// GUI HELPERS /////////////////////////////////////////////
-
public void showKeyboard() {
- if (getActivity() == null)
- return;
+ if(getActivity() == null) return;
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
View view = searchMode == SEARCH_BY_ID ? busStopSearchByIDEditText : busStopSearchByNameEditText;
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
@@ -408,6 +486,10 @@
busStopSearchByNameEditText.setVisibility(View.VISIBLE);
floatingActionButton.setImageResource(R.drawable.numeric);
}
+ protected boolean isNearbyFragmentShown(){
+ Fragment fragment = getChildFragmentManager().findFragmentByTag(NearbyStopsFragment.FRAGMENT_TAG);
+ return (fragment!= null && fragment.isVisible());
+ }
/**
* Having that cursor at the left of the edit text makes me cancer.
@@ -456,6 +538,17 @@
//actionHelpMenuItem.setVisible(false);
}
+ void showNearbyStopsFragment(){
+ 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, NearbyStopsFragment.FRAGMENT_TAG);
+ ft.commit();
+ }
+
@Override
public void showFloatingActionButton(boolean yes) {
@@ -475,7 +568,7 @@
//if we are getting results, already, stop waiting for nearbyStops
if (pendingNearbyStopsRequest && (fragmentType == FragmentKind.ARRIVALS || fragmentType == FragmentKind.STOPS)) {
- locmgr.removeUpdates(locListener);
+ locationManager.removeLocationRequestFor(requester);
pendingNearbyStopsRequest = false;
}
@@ -538,65 +631,48 @@
}
}
/////////// 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) {
+ /*
+ private void startStopRequest(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) {
+ public NearbyStopsRequester(Context appContext, Criteria criteria) {
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);
+ if(isNearbyFragmentShown()) {
+ //nothing to do
+ Log.w(DEBUG_TAG, "launched nearby fragment request but we already are showing");
+ return;
+ }
+
+ final boolean isOldVersion = Build.VERSION.SDK_INT < Build.VERSION_CODES.M;
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) {
+ if (!isOldVersion) {
pendingNearbyStopsRequest = true;
- Permissions.assertLocationPermissions(appContext,getActivity());
+ //Permissions.assertLocationPermissions(appContext,getActivity());
+ requestPermissionLauncher.launch(LOCATION_PERMISSIONS);
Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
return;
} else {
@@ -604,35 +680,20 @@
}
} 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)
+ AppLocationManager appLocationManager = AppLocationManager.getInstance(appContext);
+ final boolean haveProviders = appLocationManager.anyLocationProviderMatchesCriteria(cr);
+ if (haveProviders
&& 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();
+ showNearbyStopsFragment();
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);
+ } else if(!haveProviders){
+ Log.e(DEBUG_TAG, "NO PROVIDERS FOR POSITION");
}
}
}
}
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/fragments/MapFragment.java b/src/it/reyboz/bustorino/fragments/MapFragment.java
--- a/src/it/reyboz/bustorino/fragments/MapFragment.java
+++ b/src/it/reyboz/bustorino/fragments/MapFragment.java
@@ -1,9 +1,9 @@
package it.reyboz.bustorino.fragments;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
@@ -13,10 +13,13 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
+import android.widget.Toast;
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.app.ActivityCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.preference.PreferenceManager;
@@ -40,6 +43,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.Stop;
@@ -47,8 +51,7 @@
import it.reyboz.bustorino.map.CustomInfoWindow;
import it.reyboz.bustorino.map.LocationOverlay;
import it.reyboz.bustorino.middleware.GeneralActivity;
-
-import static it.reyboz.bustorino.util.Permissions.PERMISSION_REQUEST_POSITION;
+import it.reyboz.bustorino.util.Permissions;
public class MapFragment extends BaseFragment {
@@ -108,6 +111,30 @@
}
};
+ private final ActivityResultLauncher<String[]> positionRequestLauncher =
+ registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
+ @Override
+ @SuppressLint("MissingPermission")
+ public void onActivityResult(Map<String, Boolean> result) {
+ if(result.get(Manifest.permission.ACCESS_COARSE_LOCATION) && result.get(Manifest.permission.ACCESS_FINE_LOCATION)){
+
+ map.getOverlays().remove(mLocationOverlay);
+ startLocationOverlay(true);
+ if(getContext()==null || getContext().getSystemService(Context.LOCATION_SERVICE)==null)
+ return;
+ LocationManager locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
+ Location userLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (userLocation != null) {
+ map.getController().setZoom(POSITION_FOUND_ZOOM);
+ GeoPoint startPoint = new GeoPoint(userLocation);
+ setLocationFollowing(true);
+ map.getController().setCenter(startPoint);
+ }
+ }
+ else Log.w(DEBUG_TAG,"No location permission");
+ }
+ });
+
public MapFragment() {
}
public static MapFragment getInstance(){
@@ -181,13 +208,21 @@
btCenterMap.setOnClickListener(v -> {
//Log.i(TAG, "centerMap clicked ");
- final GeoPoint myPosition = mLocationOverlay.getMyLocation();
- map.getController().animateTo(myPosition);
+ if(Permissions.locationPermissionGranted(getContext())) {
+ final GeoPoint myPosition = mLocationOverlay.getMyLocation();
+ map.getController().animateTo(myPosition);
+ } else
+ Toast.makeText(getContext(), R.string.enable_position_message_map, Toast.LENGTH_SHORT)
+ .show();
});
btFollowMe.setOnClickListener(v -> {
//Log.i(TAG, "btFollowMe clicked ");
- switchLocationFollowing(!followingLocation);
+ if(Permissions.locationPermissionGranted(getContext()))
+ setLocationFollowing(!followingLocation);
+ else
+ Toast.makeText(getContext(), R.string.enable_position_message_map, Toast.LENGTH_SHORT)
+ .show();
});
return root;
@@ -261,8 +296,11 @@
* Switch following the location on and off
* @param value true if we want to follow location
*/
- public void switchLocationFollowing(Boolean value){
+ public void setLocationFollowing(Boolean value){
followingLocation = value;
+ if(mLocationOverlay==null || getContext() == null)
+ //nothing else to do
+ return;
if (value){
mLocationOverlay.enableFollowLocation();
} else {
@@ -282,6 +320,26 @@
}
+ /**
+ * Start the location overlay. Enable only when
+ * a) we know we have the permission
+ * b) the location map is set
+ */
+ private void startLocationOverlay(boolean enableLocation){
+ if(getActivity()== null) throw new IllegalStateException("Cannot enable LocationOverlay now");
+ // Location Overlay
+ // from OpenBikeSharing (THANK GOD)
+ Log.d(DEBUG_TAG, "Starting position overlay");
+ GpsMyLocationProvider imlp = new GpsMyLocationProvider(getActivity().getBaseContext());
+ imlp.setLocationUpdateMinDistance(5);
+ imlp.setLocationUpdateMinTime(2000);
+ this.mLocationOverlay = new LocationOverlay(imlp,map, locationCallbacks);
+ if (enableLocation) mLocationOverlay.enableMyLocation();
+ mLocationOverlay.setOptionsMenuEnabled(true);
+
+ map.getOverlays().add(this.mLocationOverlay);
+ }
+
public void startMap(Bundle incoming, Bundle savedInstanceState) {
//Check that we're attached
GeneralActivity activity = getActivity() instanceof GeneralActivity ? (GeneralActivity) getActivity() : null;
@@ -312,52 +370,48 @@
IMapController mapController = map.getController();
GeoPoint startPoint = null;
- boolean havePositionPermission = true;
-
- if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- activity.askForPermissionIfNeeded(Manifest.permission.ACCESS_FINE_LOCATION, PERMISSION_REQUEST_POSITION);
- havePositionPermission = false;
- }
- // Location Overlay
- // from OpenBikeSharing (THANK GOD)
- GpsMyLocationProvider imlp = new GpsMyLocationProvider(activity.getBaseContext());
- imlp.setLocationUpdateMinDistance(5);
- imlp.setLocationUpdateMinTime(2000);
- this.mLocationOverlay = new LocationOverlay(imlp,map, locationCallbacks);
- mLocationOverlay.enableMyLocation();
- mLocationOverlay.setOptionsMenuEnabled(true);
-
+ // set the center point
if (marker != null) {
startPoint = marker;
mapController.setZoom(POSITION_FOUND_ZOOM);
- switchLocationFollowing(false);
+ setLocationFollowing(false);
} else if (savedInstanceState != null) {
mapController.setZoom(savedInstanceState.getDouble(MAP_CURRENT_ZOOM_KEY));
mapController.setCenter(new GeoPoint(savedInstanceState.getDouble(MAP_CENTER_LAT_KEY),
savedInstanceState.getDouble(MAP_CENTER_LON_KEY)));
Log.d(DEBUG_TAG, "Location following from savedInstanceState: "+savedInstanceState.getBoolean(FOLLOWING_LOCAT_KEY));
- switchLocationFollowing(savedInstanceState.getBoolean(FOLLOWING_LOCAT_KEY));
+ setLocationFollowing(savedInstanceState.getBoolean(FOLLOWING_LOCAT_KEY));
} else {
Log.d(DEBUG_TAG, "No position found from intent or saved state");
boolean found = false;
LocationManager locationManager =
(LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
- if (locationManager != null) {
+ //check for permission
+ if (locationManager != null && Permissions.locationPermissionGranted(activity)) {
+ @SuppressLint("MissingPermission")
Location userLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (userLocation != null) {
mapController.setZoom(POSITION_FOUND_ZOOM);
startPoint = new GeoPoint(userLocation);
found = true;
- switchLocationFollowing(true);
+ setLocationFollowing(true);
+ }
+ } else if(!Permissions.locationPermissionGranted(activity)){
+ if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){
+ //TODO: show dialog for permission rationale
+ Toast.makeText(activity, R.string.enable_position_message_map, Toast.LENGTH_SHORT).show();
}
+ positionRequestLauncher.launch(Permissions.LOCATION_PERMISSIONS);
+
}
if(!found){
startPoint = new GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON);
- mapController.setZoom(16.0);
- switchLocationFollowing(false);
+ mapController.setZoom(17.0);
+ setLocationFollowing(false);
}
}
+ startLocationOverlay(Permissions.locationPermissionGranted(activity));
// set the minimum zoom level
map.setMinZoomLevel(15.0);
@@ -366,10 +420,6 @@
mapController.setCenter(startPoint);
}
-
-
- map.getOverlays().add(this.mLocationOverlay);
-
//add stops overlay
map.getOverlays().add(this.stopsFolderOverlay);
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
@@ -68,6 +68,8 @@
public final static int TYPE_STOPS = 19, TYPE_ARRIVALS = 20;
private int fragment_type;
+ public final static String FRAGMENT_TAG="NearbyStopsFrag";
+
//data Bundle
private final String BUNDLE_LOCATION = "location";
private final int LOADER_ID = 0;
@@ -135,12 +137,13 @@
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
+ if (getContext() == null) throw new RuntimeException();
View root = inflater.inflate(R.layout.fragment_nearby_stops, container, false);
gridRecyclerView = root.findViewById(R.id.stopGridRecyclerView);
- gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP));
+ gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), Float.valueOf(utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP)).intValue());
gridRecyclerView.setLayoutManager(gridLayoutManager);
gridRecyclerView.setHasFixedSize(false);
circlingProgressBar = root.findViewById(R.id.loadingBar);
@@ -226,7 +229,6 @@
+ " must implement OnFragmentInteractionListener");
}
Log.d(DEBUG_TAG, "OnAttach called");
-
}
@Override
@@ -408,6 +410,8 @@
gridRecyclerView.setVisibility(View.VISIBLE);
}
messageTextView.setVisibility(View.GONE);
+
+ if(mListener!=null) mListener.readyGUIfor(FragmentKind.NEARBY_STOPS);
}
private void showArrivalsInRecycler(List<Palina> palinas){
@@ -434,6 +438,8 @@
//arrivalsStopAdapter.notifyDataSetChanged();
showRecyclerHidingLoadMessage();
+ if(mListener!=null) mListener.readyGUIfor(FragmentKind.NEARBY_ARRIVALS);
+
}
private void setNoStopsLayout(){
@@ -601,7 +607,7 @@
@Override
public LocationCriteria getLocationCriteria() {
- return new LocationCriteria(60,TIME_INTERVAL_REQUESTS);
+ return new LocationCriteria(120,TIME_INTERVAL_REQUESTS);
}
@Override
@@ -611,6 +617,16 @@
void resetUpdateTime(){
lastUpdateTime = -1;
}
+
+ @Override
+ public void onLocationProviderAvailable() {
+
+ }
+
+ @Override
+ public void onLocationDisabled() {
+
+ }
}
/**
diff --git a/src/it/reyboz/bustorino/map/LocationOverlay.java b/src/it/reyboz/bustorino/map/LocationOverlay.java
--- a/src/it/reyboz/bustorino/map/LocationOverlay.java
+++ b/src/it/reyboz/bustorino/map/LocationOverlay.java
@@ -44,6 +44,7 @@
@Override
public void disableFollowLocation() {
+
super.disableFollowLocation();
callbacks.onDisableFollowMyLocation();
}
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
@@ -17,7 +17,10 @@
*/
package it.reyboz.bustorino.middleware;
+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;
@@ -25,7 +28,11 @@
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
+
+import androidx.core.content.ContextCompat;
+
import it.reyboz.bustorino.util.LocationCriteria;
+import it.reyboz.bustorino.util.Permissions;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -39,37 +46,42 @@
public static final int LOCATION_GPS_AVAILABLE = 22;
public static final int LOCATION_UNAVAILABLE = -22;
- private Context con;
- private LocationManager locMan;
+ private final Context appContext;
+ private final LocationManager locMan;
public static final String DEBUG_TAG = "BUSTO LocAdapter";
private final String BUNDLE_LOCATION = "location";
private static AppLocationManager instance;
private int oldGPSLocStatus = LOCATION_UNAVAILABLE;
private int minimum_time_milli = -1;
- private ArrayList<WeakReference<LocationRequester>> requestersRef = new ArrayList<>();
+ private boolean isLocationPermissionGiven = false;
+
+ private final ArrayList<WeakReference<LocationRequester>> requestersRef = new ArrayList<>();
- private AppLocationManager(Context con) {
- this.con = con.getApplicationContext();
- locMan = (LocationManager) con.getSystemService(Context.LOCATION_SERVICE);
+ private AppLocationManager(Context context) {
+ this.appContext = context.getApplicationContext();
+ locMan = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ isLocationPermissionGiven = checkLocationPermission(context);
}
public static AppLocationManager getInstance(Context con) {
- if(instance==null) instance = new AppLocationManager(con.getApplicationContext());
+ if(instance==null) instance = new AppLocationManager(con);
return instance;
}
+
+ public static boolean checkLocationPermission(Context context){
+ return ContextCompat.checkSelfPermission(context,
+ Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
+ }
- private void requestGPSPositionUpdates(){
+ private void requestGPSPositionUpdates() throws SecurityException{
final int timeinterval = (minimum_time_milli>0 && minimum_time_milli<Integer.MAX_VALUE)? minimum_time_milli : 2000;
- try {
- locMan.removeUpdates(this);
- locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, timeinterval, 5, this);
- } catch (SecurityException exc){
- exc.printStackTrace();
- Toast.makeText(con,"Cannot access GPS location",Toast.LENGTH_SHORT).show();
- }
+
+ locMan.removeUpdates(this);
+ locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, timeinterval, 5, this);
+
}
private void cleanAndUpdateRequesters(){
minimum_time_milli = Integer.MAX_VALUE;
@@ -88,15 +100,19 @@
public void addLocationRequestFor(LocationRequester req){
boolean present = false;
minimum_time_milli = Integer.MAX_VALUE;
+ int countNull = 0;
ListIterator<WeakReference<LocationRequester>> iter = requestersRef.listIterator();
while(iter.hasNext()){
final LocationRequester cReq = iter.next().get();
- if(cReq==null) iter.remove();
- else if(cReq.equals(req)){
+ if(cReq==null) {
+ countNull++;
+ iter.remove();
+ } else if(cReq.equals(req)){
present = true;
minimum_time_milli = Math.min(cReq.getLocationCriteria().getTimeInterval(),minimum_time_milli);
}
}
+ Log.d(DEBUG_TAG, countNull+" listeners have been removed because null");
if(!present) {
WeakReference<LocationRequester> newref = new WeakReference<>(req);
requestersRef.add(newref);
@@ -104,7 +120,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");
+ Log.d(DEBUG_TAG,"Requesting location updates");
requestGPSPositionUpdates();
}
@@ -134,6 +150,12 @@
else cReq.onLocationStatusChanged(status);
}
}
+ public boolean isRequesterRegistered(LocationRequester requester){
+ for(WeakReference<LocationRequester> regRef: requestersRef){
+ if(regRef.get()!=null && regRef.get() ==requester) return true;
+ }
+ return false;
+ }
@Override
public void onLocationChanged(Location location) {
@@ -176,21 +198,35 @@
}
oldGPSLocStatus = status;
}
- Log.d(DEBUG_TAG, "Provider: "+provider+" status: "+status);
+ Log.d(DEBUG_TAG, "Provider status changed: "+provider+" status: "+status);
}
@Override
public void onProviderEnabled(String provider) {
+ cleanAndUpdateRequesters();
requestGPSPositionUpdates();
Log.d(DEBUG_TAG, "Provider: "+provider+" enabled");
+ for(WeakReference<LocationRequester> req: requestersRef){
+ if(req.get()==null) continue;
+ req.get().onLocationProviderAvailable();
+ }
+
}
@Override
public void onProviderDisabled(String provider) {
- locMan.removeUpdates(this);
+ cleanAndUpdateRequesters();
+ for(WeakReference<LocationRequester> req: requestersRef){
+ if(req.get()==null) continue;
+ req.get().onLocationDisabled();
+ }
+ //locMan.removeUpdates(this);
Log.d(DEBUG_TAG, "Provider: "+provider+" disabled");
}
+ public boolean anyLocationProviderMatchesCriteria(Criteria cr) {
+ return Permissions.anyLocationProviderMatchesCriteria(locMan, cr, true);
+ }
/**
* Interface to be implemented to get the location request
*/
@@ -207,6 +243,16 @@
*/
void onLocationStatusChanged(int status);
+ /**
+ * We have a location provider available
+ */
+ void onLocationProviderAvailable();
+ /**
+ * Called when location is disabled
+ */
+ void onLocationDisabled();
+
+
/**
* Give the last time of update the requester has
* Set it to -1 in order to receive each new location
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
@@ -2,12 +2,16 @@
import android.Manifest;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.google.android.material.snackbar.Snackbar;
+
+import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
@@ -20,6 +24,7 @@
import java.util.HashMap;
import it.reyboz.bustorino.R;
+import it.reyboz.bustorino.backend.utils;
/**
* Activity class that contains all the generally useful methods
@@ -81,7 +86,7 @@
synchronized (this){
if (permissionAsked.containsKey(permission)){
num_trials = permissionAsked.get(permission);
- if (num_trials != null && num_trials > 3)
+ if (num_trials != null && num_trials > 4)
alreadyAsked = true;
}
@@ -121,4 +126,29 @@
ActivityCompat.requestPermissions(this,permissionstoRequest.toArray(new String[permissionstoRequest]));
}
*/
+
+ //KEYBOARD STUFF
+ protected View getRootView() {
+ return findViewById(android.R.id.content);
+ }
+
+ /**
+ * This method doesn't work, DO NOT USE
+ * @return if the keyboard is open
+ * TODO: fix this if you want
+ */
+ @Deprecated
+ public Boolean isKeyboardOpen(){
+ Rect visibleBounds = new Rect();
+ this.getRootView().getWindowVisibleDisplayFrame(visibleBounds);
+
+ double heightDiff = getRootView().getHeight() - visibleBounds.height();
+ final double marginOfError = Math.round(utils.convertDipToPixels(this,50f));
+ return heightDiff > marginOfError;
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
}
diff --git a/src/it/reyboz/bustorino/util/LocationCriteria.java b/src/it/reyboz/bustorino/util/LocationCriteria.java
--- a/src/it/reyboz/bustorino/util/LocationCriteria.java
+++ b/src/it/reyboz/bustorino/util/LocationCriteria.java
@@ -17,13 +17,21 @@
*/
package it.reyboz.bustorino.util;
+import android.location.Criteria;
+
/**
* Own Location Criteria, because it's fun
+ *
*/
-public class LocationCriteria {
+public class LocationCriteria extends Criteria {
private final float minAccuracy;
private final int timeInterval;
+ /**
+ * Constructor
+ * @param minAccuracy in meters
+ * @param timeInterval in milliseconds
+ */
public LocationCriteria(float minAccuracy,int timeInterval){
this.minAccuracy = minAccuracy;
this.timeInterval = timeInterval;
diff --git a/src/it/reyboz/bustorino/util/Permissions.java b/src/it/reyboz/bustorino/util/Permissions.java
--- a/src/it/reyboz/bustorino/util/Permissions.java
+++ b/src/it/reyboz/bustorino/util/Permissions.java
@@ -8,8 +8,11 @@
import android.location.LocationManager;
import android.util.Log;
+import androidx.activity.result.ActivityResultCaller;
+import androidx.activity.result.ActivityResultLauncher;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
import java.util.List;
@@ -24,6 +27,9 @@
final static public int PERMISSION_ASKING = 11;
final static public int PERMISSION_NEG_CANNOT_ASK = -3;
+ final static public String[] LOCATION_PERMISSIONS={Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION};
+
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: ");
@@ -32,9 +38,18 @@
}
return providers.size() > 0;
}
+ public static boolean isPermissionGranted(Context con,String permission){
+ return ContextCompat.checkSelfPermission(con, permission) == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean locationPermissionGranted(Context con){
+ return isPermissionGranted(con, Manifest.permission.ACCESS_FINE_LOCATION) &&
+ isPermissionGranted(con, Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
public static void assertLocationPermissions(Context con, Activity activity) {
- if(ContextCompat.checkSelfPermission(con, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
+ if(!isPermissionGranted(con, Manifest.permission.ACCESS_FINE_LOCATION) ||
+ !isPermissionGranted(con,Manifest.permission.ACCESS_COARSE_LOCATION)){
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_POSITION);
}
}

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 28, 00:10 (21 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
675592
Default Alt Text
D57.1732749017.diff (62 KB)

Event Timeline