Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F11409410
D151.1773333830.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
35 KB
Referenced Files
None
Subscribers
None
D151.1773333830.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
@@ -28,6 +28,7 @@
import android.view.View
import android.view.ViewGroup
import android.widget.*
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
@@ -53,6 +54,8 @@
import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops
import it.reyboz.bustorino.map.*
import it.reyboz.bustorino.map.CustomInfoWindow.TouchResponder
+import it.reyboz.bustorino.middleware.LocationUtils
+import it.reyboz.bustorino.util.Permissions
import it.reyboz.bustorino.viewmodels.LinesViewModel
import it.reyboz.bustorino.viewmodels.LivePositionsViewModel
import kotlinx.coroutines.delay
@@ -88,9 +91,10 @@
private lateinit var switchButton: ImageButton
private var favoritesButton: ImageButton? = null
- private lateinit var locationIcon: ImageButton
+ private var locationIcon: ImageButton? = null
private var isLineInFavorite = false
private var appContext: Context? = null
+ private var isLocationPermissionOK = false
private val lineSharedPrefMonitor = SharedPreferences.OnSharedPreferenceChangeListener { pref, keychanged ->
if(keychanged!=PreferencesHolder.PREF_FAVORITE_LINES || lineID.isEmpty()) return@OnSharedPreferenceChangeListener
val newFavorites = pref.getStringSet(PreferencesHolder.PREF_FAVORITE_LINES, HashSet())
@@ -146,6 +150,24 @@
private lateinit var stopsOverlay: FolderOverlay
private lateinit var locationOverlay: LocationOverlay
+ private val locationOverlayResponder = object : LocationOverlay.OverlayCallbacks{
+ override fun onDisableFollowMyLocation() {
+ Log.d(DEBUG_TAG, "Follow location disabled")
+ }
+
+ override fun onEnableFollowMyLocation() {
+ Log.d(DEBUG_TAG, "Follow location enabled")
+ }
+ }
+ //location request responder
+ private val locationRequestResLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ res ->
+ //onActivityResult(res: map<String,Boolean>)
+ if(res[Permissions.LOCATION_PERMISSIONS[0]] ==true || res[Permissions.LOCATION_PERMISSIONS[1]] ==true)
+ locationIcon?.let { onPositionIconButtonClick(it) }
+ else{
+ context?.let { Toast.makeText(it,R.string.location_permission_not_granted, Toast.LENGTH_SHORT).show() }
+ }
+ }
//fragment actions
private lateinit var fragmentListener: CommonFragmentListener
@@ -209,7 +231,7 @@
if(map.visibility == View.VISIBLE){
map.visibility = View.GONE
stopsRecyclerView.visibility = View.VISIBLE
- locationIcon.visibility = View.GONE
+ locationIcon?.visibility = View.GONE
viewModel.setMapShowing(false)
liveBusViewModel.stopMatoUpdates()
@@ -219,7 +241,7 @@
} else{
stopsRecyclerView.visibility = View.GONE
map.visibility = View.VISIBLE
- locationIcon.visibility = View.VISIBLE
+ locationIcon?.visibility = View.VISIBLE
viewModel.setMapShowing(true)
//map.overlayManager.add(busPositionsOverlay)
@@ -232,21 +254,15 @@
switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_list_30))
}
}
- locationIcon.setOnClickListener {
- if(locationOverlay.isMyLocationEnabled){
- //switch off
- locationOverlay.disableMyLocation()
- locationIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_grey))
- //show message
- Toast.makeText(requireContext(),R.string.location_disabled,Toast.LENGTH_SHORT).show()
- } else{
- //switch on
- locationOverlay.enableMyLocation()
- locationIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_red))
- //show message
- Toast.makeText(requireContext(),R.string.location_enabled,Toast.LENGTH_SHORT).show()
- }
+ locationIcon?.let {view ->
+ if(!LocationUtils.isLocationEnabled(requireContext()) || !Permissions.anyLocationPermissionsGranted(requireContext()))
+ setLocationIconEnabled(false)
+ //set click Listener
+ view.setOnClickListener(this::onPositionIconButtonClick)
}
+ //set
+
+
viewModel.setRouteIDQuery(lineID)
val keySourcePositions = getString(R.string.pref_positions_source)
@@ -360,6 +376,48 @@
return rootView
}
+ private fun setLocationIconEnabled(setTrue: Boolean){
+ if(setTrue)
+ locationIcon?.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_red))
+ else
+ locationIcon?.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_grey))
+ }
+
+ /**
+ * Switch position icon from activ
+ */
+ private fun onPositionIconButtonClick(view: View){
+ if(locationOverlay.isMyLocationEnabled){
+ //switch off
+ locationOverlay.disableMyLocation()
+ //set image on respective button
+ setLocationIconEnabled(false)
+ if(context!=null) {
+ if (LocationUtils.isLocationEnabled(context)) {
+ //show message
+ Toast.makeText(context, R.string.location_disabled, Toast.LENGTH_SHORT).show()
+ }
+ }
+ } else{
+ //switch on
+ locationOverlay.enableMyLocation()
+ if(context!=null) {
+ if(!Permissions.anyLocationPermissionsGranted(context)) {
+ locationRequestResLauncher.launch(Permissions.LOCATION_PERMISSIONS)
+ Toast.makeText(context, R.string.enable_position_message_map, Toast.LENGTH_SHORT).show()
+ }
+ else if (LocationUtils.isLocationEnabled(context)) {
+ //set image on button
+ setLocationIconEnabled(true)
+ //show message
+ Toast.makeText(context, R.string.location_enabled, Toast.LENGTH_SHORT).show()
+ } else{
+ Toast.makeText(context, R.string.map_location_disabled_device, Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+
private fun initializeMap(rootView : View){
val ctx = requireContext().applicationContext
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
@@ -368,16 +426,7 @@
map.let {
it.setTileSource(TileSourceFactory.MAPNIK)
- locationOverlay = LocationOverlay.createLocationOverlay(true, it, requireContext(), object : LocationOverlay.OverlayCallbacks{
- override fun onDisableFollowMyLocation() {
- Log.d(DEBUG_TAG, "Follow location disabled")
- }
-
- override fun onEnableFollowMyLocation() {
- Log.d(DEBUG_TAG, "Follow location enabled")
- }
-
- })
+ locationOverlay = LocationOverlay.createLocationOverlay(true, it, requireContext(), locationOverlayResponder)
locationOverlay.disableFollowLocation()
stopsOverlay = FolderOverlay()
@@ -409,9 +458,7 @@
mapViewModel.currentZoom.value!!,null,null)
//controller.setCenter(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!))
//controller.setZoom(mapViewModel.currentZoom.value!!)
-
*/
-
}
mapController.setZoom(zoom)
mapController.setCenter(centerMap)
@@ -424,7 +471,6 @@
zoomToCurrentPattern()
firstInit = false
-
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -53,6 +53,7 @@
import it.reyboz.bustorino.middleware.BarcodeScanUtils;
import it.reyboz.bustorino.util.LocationCriteria;
import it.reyboz.bustorino.util.Permissions;
+import org.jetbrains.annotations.NotNull;
import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSIONS;
@@ -92,11 +93,11 @@
*/
private static final int SEARCH_BY_NAME = 0;
private static final int SEARCH_BY_ID = 1;
- private static final int SEARCH_BY_ROUTE = 2; // TODO: implement this -- https://gitpull.it/T12
+ //private static final int SEARCH_BY_ROUTE = 2; // implement this -- DONE!
private int searchMode;
//private ImageButton addToFavorites;
//// HIDDEN BUT IMPORTANT ELEMENTS ////
- FragmentManager fragMan;
+ FragmentManager childFragMan;
Handler mainHandler;
private final Runnable refreshStop = new Runnable() {
public void run() {
@@ -105,8 +106,8 @@
ArrivalsFetcher[] arrivalsFetchers = new ArrivalsFetcher[fetcherList.size()];
arrivalsFetchers = fetcherList.toArray(arrivalsFetchers);
- if (fragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
- ArrivalsFragment fragment = (ArrivalsFragment) fragMan.findFragmentById(R.id.resultFrame);
+ if (childFragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
+ ArrivalsFragment fragment = (ArrivalsFragment) childFragMan.findFragmentById(R.id.resultFrame);
if (fragment == null){
//we create a new fragment, which is WRONG
Log.e("BusTO-RefreshStop", "Asking for refresh when there is no fragment");
@@ -166,7 +167,7 @@
Log.d(DEBUG_TAG, "Permissions for location are: "+result);
if(Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_COARSE_LOCATION))
- && Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION))){
+ || Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION))){
locationPermissionGranted = true;
Log.w(DEBUG_TAG, "Starting position");
if (mListener!= null && getContext()!=null){
@@ -178,7 +179,7 @@
//showNearbyStopsFragment();
Log.d(DEBUG_TAG, "We have location permission");
if(pendingNearbyStopsFragmentRequest){
- showNearbyFragmentIfNeeded(cr);
+ showNearbyFragmentIfPossible();
pendingNearbyStopsFragmentRequest = false;
}
}
@@ -203,7 +204,7 @@
//pendingNearbyStopsRequest = false;
if (getContext()!= null && !isNearbyFragmentShown())
//mainHandler.post(new NearbyStopsRequester(getContext(), cr));
- showNearbyFragmentIfNeeded(cr);
+ showNearbyFragmentIfPossible();
}
}
@@ -227,7 +228,7 @@
"we have no location permission");
pendingNearbyStopsFragmentRequest = true;
//mainHandler.post(new NearbyStopsRequester(getContext(), cr));
- showNearbyFragmentIfNeeded(cr);
+ showNearbyFragmentIfPossible();
}
}
@@ -313,8 +314,8 @@
searchButton.setOnClickListener(this::onSearchClick);
// Fragment stuff
- fragMan = getChildFragmentManager();
- fragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
+ childFragMan = getChildFragmentManager();
+ childFragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
fragmentHelper = new FragmentHelper(this, getChildFragmentManager(), getContext(), R.id.resultFrame);
setSearchModeBusStopID();
@@ -430,7 +431,7 @@
pendingNearbyStopsFragmentRequest = true;
}
else {
- showNearbyFragmentIfNeeded(cr);
+ showNearbyFragmentIfPossible();
}
} else {
//The Introductory Activity is about to be started, hence pause the request and show later
@@ -462,7 +463,7 @@
pendingNearbyStopsFragmentRequest = true;
}
else {
- showNearbyFragmentIfNeeded(cr);
+ showNearbyFragmentIfPossible();
}
//deactivate flag
pendingIntroRun = false;
@@ -474,8 +475,21 @@
} //don't request permission
// if we have a pending stopID request, do it
Log.d(DEBUG_TAG, "Pending stop ID for arrivals: "+pendingStopID);
- //this is the second time we are attaching this fragment
+ //this is the second time we are attaching this fragment ->
Log.d(DEBUG_TAG, "Waiting for new stop request: "+ suppressArrivalsReload);
+ //TODO: if we come back to this from another fragment, and the user has given again the permission
+ // for the Location, we should show the Nearby Stops
+ if(!suppressArrivalsReload && pendingStopID==null){
+ //none of the following cases are true
+ // check if we are showing any fragment
+ final Fragment fragment = getChildFragmentManager().findFragmentById(R.id.resultFrame);
+ if(fragment==null || swipeRefreshLayout.getVisibility() != View.VISIBLE){
+ //we are not showing anything
+ if(Permissions.anyLocationPermissionsGranted(getContext())){
+ showNearbyFragmentIfPossible();
+ }
+ }
+ }
if (suppressArrivalsReload){
// we have to suppress the reloading of the (possible) ArrivalsFragment
Fragment fragment = getChildFragmentManager().findFragmentById(R.id.resultFrame);
@@ -603,7 +617,7 @@
}
protected boolean isNearbyFragmentShown(){
Fragment fragment = getChildFragmentManager().findFragmentByTag(NearbyStopsFragment.FRAGMENT_TAG);
- return (fragment!= null && fragment.isVisible());
+ return (fragment!= null && fragment.isResumed());
}
/**
@@ -650,14 +664,14 @@
private void actuallyShowNearbyStopsFragment(){
swipeRefreshLayout.setVisibility(View.VISIBLE);
- final Fragment existingFrag = fragMan.findFragmentById(R.id.resultFrame);
+ final Fragment existingFrag = childFragMan.findFragmentById(R.id.resultFrame);
// fragment;
if (!(existingFrag instanceof NearbyStopsFragment)){
Log.d(DEBUG_TAG, "actually showing Nearby Stops Fragment");
//there is no fragment showing
final NearbyStopsFragment fragment = NearbyStopsFragment.newInstance(NearbyStopsFragment.FragType.STOPS);
- FragmentTransaction ft = fragMan.beginTransaction();
+ FragmentTransaction ft = childFragMan.beginTransaction();
ft.replace(R.id.resultFrame, fragment, NearbyStopsFragment.FRAGMENT_TAG);
if (getActivity()!=null && !getActivity().isFinishing())
@@ -777,28 +791,23 @@
requestPermissionLauncher.launch(LOCATION_PERMISSIONS);
}
- private void showNearbyFragmentIfNeeded(Criteria cr){
- if(isNearbyFragmentShown()) {
+ private void showNearbyFragmentIfPossible() {
+ if (isNearbyFragmentShown()) {
//nothing to do
- Log.w(DEBUG_TAG, "launched nearby fragment request but we already are showing");
+ Log.w(DEBUG_TAG, "Asked to show nearby fragment but we already are showing it");
return;
}
- if(getContext()==null){
+ if (getContext() == null) {
Log.e(DEBUG_TAG, "Wanting to show nearby fragment but context is null");
return;
}
- AppLocationManager appLocationManager = AppLocationManager.getInstance(getContext());
- final boolean haveProviders = appLocationManager.anyLocationProviderMatchesCriteria(cr);
- if (haveProviders
- && fragmentHelper.getLastSuccessfullySearchedBusStop() == null
- && !fragMan.isDestroyed()) {
+ if (fragmentHelper.getLastSuccessfullySearchedBusStop() == null
+ && !childFragMan.isDestroyed()) {
//Go ahead with the request
actuallyShowNearbyStopsFragment();
pendingNearbyStopsFragmentRequest = false;
- } else if(!haveProviders){
- Log.e(DEBUG_TAG, "NO PROVIDERS FOR POSITION");
}
}
/////////// LOCATION METHODS //////////
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
@@ -17,14 +17,19 @@
*/
package it.reyboz.bustorino.fragments;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
+import android.location.LocationManager;
import android.os.Bundle;
+import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.location.LocationListenerCompat;
+import androidx.core.location.LocationManagerCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
@@ -50,6 +55,7 @@
import it.reyboz.bustorino.adapters.SquareStopAdapter;
import it.reyboz.bustorino.middleware.AutoFitGridLayoutManager;
import it.reyboz.bustorino.util.LocationCriteria;
+import it.reyboz.bustorino.util.Permissions;
import it.reyboz.bustorino.util.StopSorterByDistance;
import it.reyboz.bustorino.viewmodels.NearbyStopsViewModel;
import org.jetbrains.annotations.NotNull;
@@ -73,6 +79,7 @@
}
}
}
+ private enum LocationShowingStatus {SEARCHING, FIRST_FIX, DISABLED, NO_PERMISSION}
private FragmentListenerMain mListener;
private FragmentLocationListener fragmentLocationListener;
@@ -84,9 +91,6 @@
public final static String FRAGMENT_TAG="NearbyStopsFrag";
- //data Bundle
- private final String BUNDLE_LOCATION = "location";
- private final int LOADER_ID = 0;
private RecyclerView gridRecyclerView;
private SquareStopAdapter dataAdapter;
@@ -106,7 +110,7 @@
private Integer MAX_DISTANCE = -3;
private int MIN_NUM_STOPS = -1;
private int TIME_INTERVAL_REQUESTS = -1;
- private AppLocationManager locManager;
+ private LocationManager locManager;
//These are useful for the case of nearby arrivals
private NearbyArrivalsDownloader arrivalsManager = null;
@@ -117,6 +121,8 @@
private ArrayList<Stop> currentNearbyStops = new ArrayList<>();
private NearbyArrivalsDownloader nearbyArrivalsDownloader;
+ private LocationShowingStatus showingStatus = LocationShowingStatus.NO_PERMISSION;
+
private final NearbyArrivalsDownloader.ArrivalsListener arrivalsListener = new NearbyArrivalsDownloader.ArrivalsListener() {
@Override
public void setProgress(int completedRequests, int pendingRequests) {
@@ -172,7 +178,7 @@
if (getArguments() != null) {
setFragmentType(FragType.fromNum(getArguments().getInt(FRAGMENT_TYPE_KEY)));
}
- locManager = AppLocationManager.getInstance(getContext());
+ locManager = (LocationManager) requireContext().getSystemService(Context.LOCATION_SERVICE);
fragmentLocationListener = new FragmentLocationListener();
if (getContext()!=null) {
globalSharedPref = getContext().getSharedPreferences(getString(R.string.mainSharedPreferences), Context.MODE_PRIVATE);
@@ -205,19 +211,23 @@
switchButton.setOnClickListener(v -> switchFragmentType());
Log.d(DEBUG_TAG, "onCreateView");
+ final Context appContext =requireContext().getApplicationContext();
DatabaseUpdate.watchUpdateWorkStatus(getContext(), this, new Observer<List<WorkInfo>>() {
+ @SuppressLint("MissingPermission")
@Override
public void onChanged(List<WorkInfo> workInfos) {
if(workInfos.isEmpty()) return;
WorkInfo wi = workInfos.get(0);
- if (wi.getState() == WorkInfo.State.RUNNING && locManager.isRequesterRegistered(fragmentLocationListener)) {
- locManager.removeLocationRequestFor(fragmentLocationListener);
+ if (wi.getState() == WorkInfo.State.RUNNING && fragmentLocationListener.isRegistered) {
+ locManager.removeUpdates(fragmentLocationListener);
+ fragmentLocationListener.isRegistered = true;
dbUpdateRunning = true;
} else{
//start the request
- if(!locManager.isRequesterRegistered(fragmentLocationListener))
- locManager.addLocationRequestFor(fragmentLocationListener);
+ if(!fragmentLocationListener.isRegistered){
+ requestLocationUpdates();
+ }
dbUpdateRunning = false;
}
}
@@ -237,9 +247,27 @@
showStopsInViews(currentNearbyStops, lastPosition);
}
});
+ if(Permissions.anyLocationPermissionsGranted(appContext)){
+ setShowingStatus(LocationShowingStatus.SEARCHING);
+ } else {
+ setShowingStatus(LocationShowingStatus.NO_PERMISSION);
+
+ }
return root;
}
+ //because linter is stupid and cannot look inside *anyLocationPermissionGranted*
+ @SuppressLint("MissingPermission")
+ private boolean requestLocationUpdates(){
+ if(Permissions.anyLocationPermissionsGranted(requireContext())) {
+ locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 3000, 10.0f, fragmentLocationListener
+ );
+ fragmentLocationListener.isRegistered = true;
+ return true;
+ } else return false;
+ }
+
/**
@@ -257,6 +285,40 @@
}
}
+ private void setShowingStatus(@NonNull LocationShowingStatus newStatus){
+ if(newStatus == showingStatus){
+ Log.d(DEBUG_TAG, "Asked to set new displaying status but it's the same");
+ return;
+ }
+ switch (newStatus){
+ case FIRST_FIX:
+ circlingProgressBar.setVisibility(View.GONE);
+ loadingTextView.setVisibility(View.GONE);
+ gridRecyclerView.setVisibility(View.VISIBLE);
+ messageTextView.setVisibility(View.GONE);
+ break;
+ case NO_PERMISSION:
+ circlingProgressBar.setVisibility(View.GONE);
+ loadingTextView.setVisibility(View.GONE);
+ messageTextView.setText(R.string.enable_position_message_nearby);
+ messageTextView.setVisibility(View.VISIBLE);
+ break;
+ case DISABLED:
+ if (showingStatus== LocationShowingStatus.SEARCHING){
+ circlingProgressBar.setVisibility(View.GONE);
+ loadingTextView.setVisibility(View.GONE);
+ }
+ messageTextView.setText(R.string.enableGpsText);
+ messageTextView.setVisibility(View.VISIBLE);
+ break;
+ case SEARCHING:
+ circlingProgressBar.setVisibility(View.VISIBLE);
+ loadingTextView.setVisibility(View.VISIBLE);
+ gridRecyclerView.setVisibility(View.GONE);
+ messageTextView.setVisibility(View.GONE);
+ }
+ showingStatus = newStatus;
+ }
@Override
@@ -270,6 +332,8 @@
}
Log.d(DEBUG_TAG, "OnAttach called");
viewModel = new ViewModelProvider(this).get(NearbyStopsViewModel.class);
+
+
}
@Override
@@ -277,7 +341,8 @@
super.onPause();
gridRecyclerView.setAdapter(null);
- locManager.removeLocationRequestFor(fragmentLocationListener);
+ locManager.removeUpdates(fragmentLocationListener);
+ fragmentLocationListener.isRegistered = false;
Log.d(DEBUG_TAG,"On paused called");
}
@@ -285,8 +350,9 @@
public void onResume() {
super.onResume();
try{
- if(!dbUpdateRunning && !locManager.isRequesterRegistered(fragmentLocationListener))
- locManager.addLocationRequestFor(fragmentLocationListener);
+ if(!dbUpdateRunning && !fragmentLocationListener.isRegistered) {
+ requestLocationUpdates();
+ }
} catch (SecurityException ex){
//ignored
//try another location provider
@@ -519,12 +585,10 @@
/**
* Local locationListener, to use for the GPS
*/
- class FragmentLocationListener implements AppLocationManager.LocationRequester{
+ class FragmentLocationListener implements LocationListenerCompat {
- private int oldLocStatus = -2;
- private LocationCriteria cr;
private long lastUpdateTime = -1;
-
+ public boolean isRegistered = false;
@Override
public void onLocationChanged(Location location) {
@@ -548,6 +612,27 @@
Log.d("BusTO:NearPositListen","can start request for stops: "+ !dbUpdateRunning);
}
+ @Override
+ public void onProviderEnabled(@NonNull String provider) {
+ Log.d(DEBUG_TAG, "Location provider "+provider+" enabled");
+ if(provider.equals(LocationManager.GPS_PROVIDER)){
+ setShowingStatus(LocationShowingStatus.SEARCHING);
+ }
+ }
+
+ @Override
+ public void onProviderDisabled(@NonNull String provider) {
+ Log.d(DEBUG_TAG, "Location provider "+provider+" disabled");
+ if(provider.equals(LocationManager.GPS_PROVIDER)) {
+ setShowingStatus(LocationShowingStatus.DISABLED);
+ }
+ }
+
+ @Override
+ public void onStatusChanged(@NonNull @NotNull String provider, int status, @Nullable @org.jetbrains.annotations.Nullable Bundle extras) {
+ LocationListenerCompat.super.onStatusChanged(provider, status, extras);
+ }
+ /*
@Override
public void onLocationStatusChanged(int status) {
switch(status){
@@ -587,5 +672,7 @@
public void onLocationDisabled() {
}
+
+ */
}
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
@@ -1,17 +1,22 @@
package it.reyboz.bustorino.fragments;
+import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
import it.reyboz.bustorino.BuildConfig;
+import java.util.Map;
+
import static android.content.Context.MODE_PRIVATE;
public abstract class ScreenBaseFragment extends Fragment {
@@ -62,4 +67,24 @@
editor.putBoolean(optionName, value);
editor.apply();
}
+ public ActivityResultLauncher<String[]> getPositionRequestLauncher(LocationRequestListener listener){
+ return registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<>() {
+ @Override
+ public void onActivityResult(Map<String, Boolean> result) {
+ if (result == null) return;
+
+ if (result.get(Manifest.permission.ACCESS_COARSE_LOCATION) == null ||
+ result.get(Manifest.permission.ACCESS_FINE_LOCATION) == null)
+ return;
+ final boolean coarseGranted = Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_COARSE_LOCATION));
+ final boolean fineGranted = Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION));
+
+ listener.onPermissionResult(coarseGranted, fineGranted);
+ }
+ });
+ }
+
+ public interface LocationRequestListener{
+ void onPermissionResult(boolean isCoarseGranted, boolean isFineGranted);
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
--- a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
+++ b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
@@ -24,6 +24,7 @@
import android.os.Bundle
import android.util.Log
import androidx.core.content.ContextCompat
+import androidx.core.location.LocationListenerCompat
import it.reyboz.bustorino.util.LocationCriteria
import it.reyboz.bustorino.util.Permissions
import java.lang.ref.WeakReference
@@ -31,6 +32,8 @@
/**
* Singleton class used to access location. Possibly extended with other location sources.
+ *
+ * 2024: This is far too much. We need to simplify the whole mechanism (no more singleton)
*/
class AppLocationManager private constructor(context: Context) : LocationListener {
private val appContext: Context
@@ -259,9 +262,9 @@
private const val DEBUG_TAG = "BUSTO LocAdapter"
private var instance: AppLocationManager? = null
@JvmStatic
- fun getInstance(con: Context): AppLocationManager? {
+ fun getInstance(con: Context): AppLocationManager {
if (instance == null) instance = AppLocationManager(con)
- return instance
+ return instance!!
}
fun checkLocationPermission(context: Context?): Boolean {
diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java b/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java
@@ -0,0 +1,28 @@
+package it.reyboz.bustorino.middleware;
+
+import android.content.Context;
+import android.location.LocationManager;
+import android.os.Build;
+import android.provider.Settings;
+import androidx.core.content.ContextCompat;
+
+public class LocationUtils {
+
+ public static LocationManager getSystemLocationManager(Context context){
+ return ContextCompat.getSystemService(context, LocationManager.class);
+ }
+
+ //thanks to https://stackoverflow.com/questions/10311834/how-to-check-if-location-services-are-enabled
+ public static Boolean isLocationEnabled(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ // This is a new method provided in API 28
+ LocationManager lm = getSystemLocationManager(context);
+ return lm.isLocationEnabled();
+ } else {
+ // This was deprecated in API 28
+ int mode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF);
+ return (mode != Settings.Secure.LOCATION_MODE_OFF);
+ }
+ }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/util/Permissions.java b/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
--- a/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
+++ b/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
@@ -41,7 +41,7 @@
for (String s : providers) {
Log.d(DEBUG_TAG, "Provider " + s);
}
- return providers.size() > 0;
+ return !providers.isEmpty();
}
public static boolean isPermissionGranted(Context con,String permission){
return ContextCompat.checkSelfPermission(con, permission) == PackageManager.PERMISSION_GRANTED;
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -151,6 +151,7 @@
<string name="enable_position">Attiva o disattiva posizione</string>
<string name="location_enabled">Posizione attivata</string>
<string name="location_disabled">Posizione disattivata</string>
+ <string name="map_location_disabled_device">La posizione è disabilitata sul dispositivo</string>
<!--
Arrival times sources
@@ -265,6 +266,8 @@
<string name="grant_location_permission">Abilita accesso alla posizione</string>
<string name="location_permission_granted">Accesso alla posizione abilitato</string>
+ <string name="location_permission_not_granted">Accesso alla posizione non consentito dall\'utente</string>
+
<string name="grant_notification_permission">Abilita notifiche</string>
<string name="notification_permission_granted">Notifiche abilitate</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -149,8 +149,9 @@
<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="enable_position_message_map">Allow access to location to show it on the map</string>
+ <string name="enable_position_message_nearby">Allow access to location to show stops nearby</string>
+ <string name="enableGpsText">Please enable location on the device</string>
<string name="database_update_msg_inapp">Database update in progress…</string>
<string name="database_update_msg_notif">Updating the database</string>
<string name="database_update_req">Force database update</string>
@@ -172,6 +173,7 @@
<string name="enable_position">Enable or disable location</string>
<string name="location_enabled">Location enabled</string>
<string name="location_disabled">Location disabled</string>
+ <string name="map_location_disabled_device">Location is disabled on device</string>
<!--
Arrival times sources
@@ -295,6 +297,7 @@
</string>
<string name="grant_location_permission">Grant location permission</string>
<string name="location_permission_granted">Location permission granted</string>
+ <string name="location_permission_not_granted">Location permission has not been granted</string>
<string name="close_tutorial">OK, close the tutorial</string>
<string name="close_tutorial_short">Close the tutorial</string>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 12, 17:43 (20 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737461
Default Alt Text
D151.1773333830.diff (35 KB)
Attached To
Mode
D151: Button behaviour change when location is disabled
Attached
Detach File
Event Timeline
Log In to Comment