Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F13562526
D57.1783999404.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Authored By
Unknown
Size
57 KB
Referenced Files
None
Subscribers
None
D57.1783999404.diff
View Options
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>
@@ -145,5 +145,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…</string>
<string name="bus_arriving_at">is arriving at</string>
@@ -162,4 +164,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/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/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
Details
Attached
Mime Type
text/plain
Expires
Tue, Jul 14, 05:23 (22 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2000330
Default Alt Text
D57.1783999404.diff (57 KB)
Attached To
Mode
D57: Make ActivityPrincipal the default activity
Attached
Detach File
Event Timeline