diff --git a/sensorhub-android-app/res/drawable/ic_loading.xml b/sensorhub-android-app/res/drawable/ic_loading.xml
new file mode 100644
index 0000000..65d83e5
--- /dev/null
+++ b/sensorhub-android-app/res/drawable/ic_loading.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/sensorhub-android-app/res/drawable/ic_loading_animated.xml b/sensorhub-android-app/res/drawable/ic_loading_animated.xml
new file mode 100644
index 0000000..76e1571
--- /dev/null
+++ b/sensorhub-android-app/res/drawable/ic_loading_animated.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/sensorhub-android-app/src/org/sensorhub/android/DashboardFragment.java b/sensorhub-android-app/src/org/sensorhub/android/DashboardFragment.java
index 62f2ee9..fca6f41 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/DashboardFragment.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/DashboardFragment.java
@@ -169,17 +169,36 @@ private void updateFabIcon() {
}
}
+ private void showFabProgress() {
+ if (fab == null) return;
+ fab.setImageResource(R.drawable.ic_loading_animated);
+ fab.setEnabled(false);
+ }
+
+ private void hideFabProgress() {
+ if (fab == null) return;
+ fab.setEnabled(true);
+ updateFabIcon();
+ }
+
private void stopHub() {
- Toast.makeText(requireContext(), R.string.stopping_sensorhub, Toast.LENGTH_SHORT).show();
+ showFabProgress();
+ newStatusMessage(getString(R.string.stopping_sensorhub));
stopRefreshingStatus();
- provider.stopSensorHub();
- updateFabIcon();
hideVideoPreview();
clearTextureView();
videoStatusCard.setVisibility(View.GONE);
if (meshtasticCard != null) meshtasticCard.setVisibility(View.GONE);
- newStatusMessage(getString(R.string.sensorhub_stopped));
- requireActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ provider.stopSensorHub();
+
+ // Brief delay to let the service finish stopping on its background thread
+ displayHandler.postDelayed(() -> {
+ if (!isAdded()) return;
+ hideFabProgress();
+ updateFabIcon();
+ newStatusMessage(getString(R.string.sensorhub_stopped));
+ requireActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }, 1000);
}
private void clearTextureView() {
@@ -231,7 +250,7 @@ public void onClick(DialogInterface dialog, int whichButton) {
showVideoConfigErrorPopup();
newStatusMessage(getString(R.string.video_config_error));
} else {
- Toast.makeText(requireContext(), R.string.starting_sensorhub, Toast.LENGTH_SHORT).show();
+ showFabProgress();
newStatusMessage(getString(R.string.starting_sensorhub));
provider.getSostClients().clear();
provider.getConSysClients().clear();
@@ -280,6 +299,7 @@ private void pollHubReady() {
if (!provider.isOshStarted()) {
provider.setOshStarted(true);
+ hideFabProgress();
updateFabIcon();
serverStatusContainer.removeAllViews();
serverCardViews.clear();
@@ -292,6 +312,7 @@ private void pollHubReady() {
} else if (hubPollAttempts < HUB_POLL_MAX_ATTEMPTS) {
displayHandler.postDelayed(this::pollHubReady, HUB_POLL_INTERVAL_MS);
} else {
+ hideFabProgress();
newStatusMessage(getString(R.string.sensorhub_start_failed));
updateFabIcon();
}