commit 9dfbba27d37ded1d6b13577c80c52b766789e95a Author: Fabio Mazza Date: Sun May 31 19:11:46 2026 +0200 Add button for app information, fix swiperefreshlayout stuff Summary: Add button for app information, fix callback to main fragment stuff Reviewers: #libre_busto_hackers, valerio.bozzolan Reviewed By: #libre_busto_hackers, valerio.bozzolan Subscribers: valerio.bozzolan Project Tags: #libre_busto Differential Revision: https://gitpull.it/D252 diff --git a/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java b/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java index a95a538..2a1379a 100644 --- a/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java +++ b/app/src/main/java/it/reyboz/bustorino/ActivityPrincipal.java @@ -682,7 +682,7 @@ public class ActivityPrincipal extends GeneralActivity implements FragmentListen .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); } - + /* @Nullable private MainScreenFragment getMainFragmentIfVisible(){ FragmentManager fraMan = getSupportFragmentManager(); @@ -691,12 +691,17 @@ public class ActivityPrincipal extends GeneralActivity implements FragmentListen else return null; } + */ + @Override public void showFloatingActionButton(boolean yes) { - var frag = getMainFragmentIfVisible(); - if(frag!=null){ - frag.showFloatingActionButton(yes); + var framan = getSupportFragmentManager(); + var frag = framan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG); + if(frag instanceof MainScreenFragment mainFrag){ + mainFrag.showFloatingActionButton(yes); + } else{ + Log.d(DEBUG_TAG, "No main screen fragment found to set showFloatingActionButton"); } } @@ -759,9 +764,10 @@ public class ActivityPrincipal extends GeneralActivity implements FragmentListen } if(getSupportActionBar()!=null && titleResId!=null) getSupportActionBar().setTitle(titleResId); - MainScreenFragment mainFragmentIfVisible = getMainFragmentIfVisible(); - if (mainFragmentIfVisible!=null){ - mainFragmentIfVisible.readyGUIfor(fragmentType); + //MainScreenFragment mainFragmentIfVisible = getMainFragmentIfVisible(); + var frag = getSupportFragmentManager().findFragmentByTag(MainScreenFragment.FRAGMENT_TAG); + if (frag instanceof MainScreenFragment mainFrag){ + mainFrag.readyGUIfor(fragmentType); } } @@ -836,17 +842,19 @@ public class ActivityPrincipal extends GeneralActivity implements FragmentListen @Override public void toggleSpinner(boolean state) { - MainScreenFragment probableFragment = getMainFragmentIfVisible(); - if (probableFragment!=null){ - probableFragment.toggleSpinner(state); + var frag = getSupportFragmentManager().findFragmentByTag(MainScreenFragment.FRAGMENT_TAG); + if (frag instanceof MainScreenFragment mainFrag) { + mainFrag.toggleSpinner(state); } } @Override public void enableRefreshLayout(boolean yes) { - MainScreenFragment probableFragment = getMainFragmentIfVisible(); - if (probableFragment!=null){ - probableFragment.enableRefreshLayout(yes); + Log.d(DEBUG_TAG, "enableRefreshLayout: "+yes); + var framan = getSupportFragmentManager(); + var frag = framan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG); + if (frag instanceof MainScreenFragment mainFrag){ + mainFrag.enableRefreshLayout(yes); } } diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ButtonsFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/ButtonsFragment.kt index 8ae3d11..33760ff 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/ButtonsFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/ButtonsFragment.kt @@ -27,10 +27,10 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.card.MaterialCardView +import it.reyboz.bustorino.ActivityAbout import it.reyboz.bustorino.ActivitySettings import it.reyboz.bustorino.R import it.reyboz.bustorino.adapters.RecyclerViewMargin @@ -54,10 +54,6 @@ class ButtonsFragment : BarcodeFragment() { arguments?.let { } - if(listener is FragmentListenerMain){ - val ll = listener as FragmentListenerMain - ll.enableRefreshLayout(false) - } } private val marginHoriz = 30 private val margin = 11 @@ -76,8 +72,13 @@ class ButtonsFragment : BarcodeFragment() { CardMenuItem(CardAction.FAVORITES_STOPS, getString(R.string.action_favorites), R.drawable.ic_star_filled_white), CardMenuItem(CardAction.LINES, getString(R.string.lines), R.drawable.ic_moving_emph), CardMenuItem(CardAction.SETTINGS, getString(R.string.action_settings), R.drawable.ic_baseline_settings_24), - CardMenuItem(CardAction.QR_SCAN, getString(R.string.scan_qr_code_stop), R.drawable.qr_code_scan) - ) + CardMenuItem(CardAction.QR_SCAN, getString(R.string.scan_qr_code_stop), + R.drawable.qr_code_scan), + CardMenuItem(CardAction.INFO, + getString(R.string.action_about), R.drawable.ic_baseline_info_24 + ), + + ) recyclerView = root.findViewById(R.id.buttonsRecyclerView) @@ -89,32 +90,6 @@ class ButtonsFragment : BarcodeFragment() { recyclerView.addItemDecoration(margins) - /*gridLayout = root.findViewById(R.id.homeGridLayout) - - items.forEach { item -> - // Inflate base layout - val cardView = LayoutInflater.from(requireContext()) - .inflate(R.layout.item_card_button, gridLayout, false) - - // Popola icona e testo - cardView.findViewById(R.id.cardIcon).setImageResource(item.iconRes) - cardView.findViewById(R.id.cardLabel).text = item.label - // Parametri griglia: colonna flessibile + margini - cardView.layoutParams = GridLayout.LayoutParams().apply { - width = 0 - height = GridLayout.LayoutParams.WRAP_CONTENT - columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f) - setMargins(marginHoriz, marginVer, marginHoriz, marginVer) // margini tra le card - } - - // Click - cardView.setOnClickListener { onCardClicked(item) } - - gridLayout.addView(cardView) - } - - */ - return root } @@ -137,6 +112,9 @@ class ButtonsFragment : BarcodeFragment() { CardAction.QR_SCAN -> { launchBarcodeScan() } + CardAction.INFO ->{ + startActivity(Intent(requireContext(), ActivityAbout::class.java)) + } } } @@ -169,6 +147,10 @@ class ButtonsFragment : BarcodeFragment() { override fun onResume() { super.onResume() listener?.readyGUIfor(FragmentKind.HOME_BUTTONS) + if(listener is FragmentListenerMain){ + val ll = listener as FragmentListenerMain + ll.enableRefreshLayout(false) + } } companion object { @@ -192,7 +174,7 @@ class ButtonsFragment : BarcodeFragment() { val iconRes: Int ) enum class CardAction { - NEARBY, MAP, FAVORITES_STOPS, LINES, SETTINGS, QR_SCAN + NEARBY, MAP, FAVORITES_STOPS, LINES, SETTINGS, QR_SCAN, INFO } } @@ -203,7 +185,7 @@ class ActionsCardAdapter(val actions: List, parent: ViewGroup, viewType: Int ): ViewHolder { - val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_button, parent, false) + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_button_home, parent, false) /* // Altezza match_parent per uniformare le card della stessa riga view.layoutParams = RecyclerView.LayoutParams( diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java index 82264ac..f8d3020 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java @@ -704,6 +704,7 @@ public class MainScreenFragment extends BarcodeFragment implements FragmentList } @Override public void enableRefreshLayout(boolean yes) { + Log.d(DEBUG_TAG, "Enabling refresh layout: " + yes); swipeRefreshLayout.setEnabled(yes); } diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt deleted file mode 100644 index 25c5db5..0000000 --- a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt +++ /dev/null @@ -1,273 +0,0 @@ -/* - BusTO (middleware) - Copyright (C) 2019 Fabio Mazza - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ -package it.reyboz.bustorino.middleware - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.location.* -import android.os.Bundle -import android.util.Log -import androidx.core.content.ContextCompat -import it.reyboz.bustorino.util.LocationCriteria -import java.lang.ref.WeakReference -import kotlin.math.min - -/** - * 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 - private val locMan: LocationManager - private val BUNDLE_LOCATION = "location" - private var oldGPSLocStatus = LOCATION_UNAVAILABLE - private var minimum_time_milli = -1 - private val requestersRef = ArrayList>() - - init { - appContext = context.applicationContext - locMan = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - } - - @Throws(SecurityException::class) - private fun requestGPSPositionUpdates(): Boolean { - val timeinterval = - if (minimum_time_milli > 0 && minimum_time_milli < Int.MAX_VALUE) minimum_time_milli else 2000 - locMan.removeUpdates(this) - if (!checkLocationPermission(appContext)){ - Log.e(DEBUG_TAG, "No location permission!!") - return false - } - if (locMan.allProviders.contains("gps")) locMan.requestLocationUpdates( - LocationManager.GPS_PROVIDER, - timeinterval.toLong(), - 5f, - this - ) - /*LocationManagerCompat.requestLocationUpdates(locMan, LocationManager.GPS_PROVIDER, - new LocationRequestCompat.Builder(timeinterval).setMinUpdateDistanceMeters(5.F).build(),this, ); - TODO: find a way to do this - */ - return true - } - - private fun cleanAndUpdateRequesters() { - minimum_time_milli = Int.MAX_VALUE - val iter = requestersRef.listIterator() - while (iter.hasNext()) { - val cReq = iter.next().get() - if (cReq == null) iter.remove() else { - minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) - .toInt() - } - } - Log.d( - DEBUG_TAG, - "Updated requesters, got " + requestersRef.size + " listeners to update every " + minimum_time_milli + " ms at least" - ) - } - - fun addLocationRequestFor(req: LocationRequester) { - var present = false - minimum_time_milli = Int.MAX_VALUE - var countNull = 0 - val iter = requestersRef.listIterator() - while (iter.hasNext()) { - val cReq = iter.next().get() - if (cReq == null) { - countNull++ - iter.remove() - } else if (cReq == req) { - present = true - minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) - .toInt() - } - } - Log.d(DEBUG_TAG, "$countNull listeners have been removed because null") - if (!present) { - val newref = WeakReference(req) - requestersRef.add(newref) - minimum_time_milli = min(req.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) - .toInt() - Log.d(DEBUG_TAG, "Added new stop requester, instance of " + req.javaClass.simpleName) - } - if (requestersRef.size > 0) { - Log.d(DEBUG_TAG, "Requesting location updates") - requestGPSPositionUpdates() - } - } - - fun removeLocationRequestFor(req: LocationRequester) { - minimum_time_milli = Int.MAX_VALUE - val iter = requestersRef.listIterator() - while (iter.hasNext()) { - val cReq = iter.next().get() - if (cReq == null || cReq == req) iter.remove() else { - minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) - .toInt() - } - } - if (requestersRef.size <= 0) { - locMan.removeUpdates(this) - } - } - - private fun sendLocationStatusToAll(status: Int) { - val iter = requestersRef.listIterator() - while (iter.hasNext()) { - val cReq = iter.next().get() - if (cReq == null) iter.remove() else cReq.onLocationStatusChanged(status) - } - } - - fun isRequesterRegistered(requester: LocationRequester): Boolean { - for (regRef in requestersRef) { - if (regRef.get() != null && regRef.get() === requester) return true - } - return false - } - - override fun onLocationChanged(location: Location) { - Log.d( - DEBUG_TAG, "found location: \nlat: ${location.latitude} lon: ${location.longitude} accuracy: ${location.accuracy}" - ) - val iter = requestersRef.listIterator() - var new_min_interval = Int.MAX_VALUE - while (iter.hasNext()) { - val requester = iter.next().get() - if (requester == null) iter.remove() else { - val timeNow = System.currentTimeMillis() - val criteria = requester.locationCriteria - if (location.accuracy < criteria.minAccuracy && - timeNow - requester.lastUpdateTimeMillis > criteria.timeInterval - ) { - requester.onLocationChanged(location) - Log.d( - "AppLocationManager", - "Updating position for instance of requester " + requester.javaClass.simpleName - ) - } - //update minimum time interval - new_min_interval = min(requester.locationCriteria.timeInterval.toDouble(), new_min_interval.toDouble()) - .toInt() - } - } - minimum_time_milli = new_min_interval - if (requestersRef.size == 0) { - //stop requesting the position - locMan.removeUpdates(this) - } - } - - @Deprecated("Deprecated in Java") - override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { - //IF ANOTHER LOCATION SOURCE IS READY, USE IT - //OTHERWISE, SIGNAL THAT WE HAVE NO LOCATION - if (oldGPSLocStatus != status) { - if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { - sendLocationStatusToAll(LOCATION_UNAVAILABLE) - } else if (status == LocationProvider.AVAILABLE) { - sendLocationStatusToAll(LOCATION_GPS_AVAILABLE) - } - oldGPSLocStatus = status - } - Log.d(DEBUG_TAG, "Provider status changed: $provider status: $status") - } - - override fun onProviderEnabled(provider: String) { - cleanAndUpdateRequesters() - requestGPSPositionUpdates() - Log.d(DEBUG_TAG, "Provider: $provider enabled") - for (req in requestersRef) { - if (req.get() == null) continue - req.get()!!.onLocationProviderAvailable() - } - } - - override fun onProviderDisabled(provider: String) { - cleanAndUpdateRequesters() - for (req in requestersRef) { - if (req.get() == null) continue - req.get()!!.onLocationDisabled() - } - //locMan.removeUpdates(this); - Log.d(DEBUG_TAG, "Provider: $provider disabled") - } - - - /** - * Interface to be implemented to get the location request - */ - interface LocationRequester { - /** - * Do something with the newly obtained location - * @param loc the obtained location - */ - fun onLocationChanged(loc: Location?) - - /** - * Inform the requester that the GPS status has changed - * @param status new status - */ - fun onLocationStatusChanged(status: Int) - - /** - * We have a location provider available - */ - fun onLocationProviderAvailable() - - /** - * Called when location is disabled - */ - fun onLocationDisabled() - - /** - * Give the last time of update the requester has - * Set it to -1 in order to receive each new location - * @return the time for update in milliseconds since epoch - */ - val lastUpdateTimeMillis: Long - - /** - * Get the specifications for the location - * @return fully parsed LocationCriteria - */ - val locationCriteria: LocationCriteria - } - - companion object { - const val LOCATION_GPS_AVAILABLE = 22 - const val LOCATION_UNAVAILABLE = -22 - private const val DEBUG_TAG = "BUSTO LocAdapter" - private var instance: AppLocationManager? = null - @JvmStatic - fun getInstance(con: Context): AppLocationManager { - if (instance == null) instance = AppLocationManager(con) - return instance!! - } - - fun checkLocationPermission(context: Context?): Boolean { - return ContextCompat.checkSelfPermission( - context!!, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - } - } -} diff --git a/app/src/main/java/it/reyboz/bustorino/util/Permissions.kt b/app/src/main/java/it/reyboz/bustorino/util/Permissions.kt index 2ec7efc..2dc9894 100644 --- a/app/src/main/java/it/reyboz/bustorino/util/Permissions.kt +++ b/app/src/main/java/it/reyboz/bustorino/util/Permissions.kt @@ -35,15 +35,6 @@ class Permissions private constructor(private val appContext: Context) { */ private var askedTimesLocation = AtomicInteger(0) - fun anyLocationProviderMatchesCriteria(mng: LocationManager, cr: Criteria, enabled: Boolean): Boolean { - val providers = mng.getProviders(cr, enabled) - Log.d(DEBUG_TAG, "Getting enabled location providers: ") - for (s in providers) { - Log.d(DEBUG_TAG, "Provider " + s) - } - return !providers.isEmpty() - } - fun checkRequestLocationPermissions(activity: Activity, launcher: ActivityResultLauncher>): Boolean { diff --git a/app/src/main/res/drawable/ic_outline_info_24.xml b/app/src/main/res/drawable/ic_outline_info_24.xml index dca49ae..23d190e 100644 --- a/app/src/main/res/drawable/ic_outline_info_24.xml +++ b/app/src/main/res/drawable/ic_outline_info_24.xml @@ -1,5 +1,9 @@ - - + + diff --git a/app/src/main/res/layout/item_card_button.xml b/app/src/main/res/layout/item_card_button_home.xml similarity index 96% rename from app/src/main/res/layout/item_card_button.xml rename to app/src/main/res/layout/item_card_button_home.xml index 976eaf8..e2755df 100644 --- a/app/src/main/res/layout/item_card_button.xml +++ b/app/src/main/res/layout/item_card_button_home.xml @@ -15,7 +15,7 @@ android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center" - android:padding="20dp"> + android:padding="18dp"> Suivant Nom de l\'arrêt de bus Aucune arrivée prévue pour cette arrêt - Il semble qu\'il n\\\'y a aucun arrêt de bus avec ce nom - À propos de l\\\'application + Il semble qu\'il n\'y a aucun arrêt de bus avec ce nom + À propos de l\'application Aucune ligne trouvée dans cette catégorie Aucune ligne ne correspond à la recherche Ligne %1$s diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index ae15f99..3866111 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -40,7 +40,7 @@ Nessun QR code trovato, riprova Preferiti Aiuto - Informazioni + Informazioni sull\'app Più informazioni Vai alla wiki https://gitpull.it/w/librebusto/it/