Page MenuHomeGitPull.it

D151.1773254416.diff
No OneTemporary

Size
35 KB
Referenced Files
None
Subscribers
None

D151.1773254416.diff

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&#8230;</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

Mime Type
text/plain
Expires
Wed, Mar 11, 19:40 (1 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737461
Default Alt Text
D151.1773254416.diff (35 KB)

Event Timeline