forked from upstream-mirrors/OpenTracks
Recording without GPS: show a Snackbar to warn user that recording is not using GPS.
This commit is contained in:
committed by
Román Martínez
parent
5c06c7548f
commit
7ca6925e7d
@@ -3,7 +3,6 @@ package de.dennisguse.opentracks;
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -21,6 +20,7 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
|
||||
import java.util.List;
|
||||
@@ -36,6 +36,7 @@ import de.dennisguse.opentracks.fragments.StatisticsRecordingFragment;
|
||||
import de.dennisguse.opentracks.services.RecordingStatus;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.ui.intervals.IntervalsFragment;
|
||||
@@ -63,6 +64,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
|
||||
private static final String CURRENT_TAB_TAG_KEY = "current_tab_tag_key";
|
||||
|
||||
private Snackbar snackbar;
|
||||
|
||||
// The following are setFrequency in onCreate
|
||||
private ContentProviderUtils contentProviderUtils;
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
@@ -76,45 +79,41 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
|
||||
private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT;
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = new TrackRecordingServiceConnection.Callback() {
|
||||
@Override
|
||||
public void onConnected(TrackRecordingService service) {
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
|
||||
service.getRecordingStatusObservable()
|
||||
.observe(TrackRecordingActivity.this, this::onRecordingStatusChanged);
|
||||
|
||||
service.getRecordingStatusObservable()
|
||||
.observe(TrackRecordingActivity.this, status -> onRecordingStatusChanged(status));
|
||||
service.getGpsStatusObservable()
|
||||
.observe(TrackRecordingActivity.this, this::onGpsStatusChanged);
|
||||
|
||||
if (!service.isRecording()) {
|
||||
if (trackId == null) {
|
||||
// trackId isn't initialized -> leads a new recording.
|
||||
trackId = service.startNewTrack();
|
||||
} else {
|
||||
// trackId is initialized -> resumes the track.
|
||||
service.resumeTrack(trackId);
|
||||
}
|
||||
|
||||
// A recording track is on.
|
||||
trackDataHub.loadTrack(trackId);
|
||||
trackDataHub.setRecordingStatus(recordingStatus);
|
||||
if (!service.isRecording()) {
|
||||
if (trackId == null) {
|
||||
// trackId isn't initialized -> leads a new recording.
|
||||
trackId = service.startNewTrack();
|
||||
} else {
|
||||
// trackId is initialized -> resumes the track.
|
||||
service.resumeTrack(trackId);
|
||||
}
|
||||
|
||||
// A recording track is on.
|
||||
trackDataHub.loadTrack(trackId);
|
||||
trackDataHub.setRecordingStatus(recordingStatus);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (PreferencesUtils.isKey(R.string.stats_show_on_lockscreen_while_recording_key, key)) {
|
||||
setLockscreenPolicy();
|
||||
}
|
||||
if (PreferencesUtils.isKey(R.string.stats_keep_screen_on_while_recording_key, key)) {
|
||||
setScreenOnPolicy();
|
||||
}
|
||||
if (PreferencesUtils.isKey(R.string.stats_fullscreen_while_recording_key, key)) {
|
||||
setFullscreenPolicy();
|
||||
}
|
||||
if (key == null) return;
|
||||
|
||||
runOnUiThread(TrackRecordingActivity.this::invalidateOptionsMenu); //TODO Should not be necessary
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
|
||||
if (PreferencesUtils.isKey(R.string.stats_show_on_lockscreen_while_recording_key, key)) {
|
||||
setLockscreenPolicy();
|
||||
}
|
||||
if (PreferencesUtils.isKey(R.string.stats_keep_screen_on_while_recording_key, key)) {
|
||||
setScreenOnPolicy();
|
||||
}
|
||||
if (PreferencesUtils.isKey(R.string.stats_fullscreen_while_recording_key, key)) {
|
||||
setFullscreenPolicy();
|
||||
}
|
||||
if (key == null) return;
|
||||
|
||||
runOnUiThread(TrackRecordingActivity.this::invalidateOptionsMenu); //TODO Should not be necessary
|
||||
};
|
||||
|
||||
private MenuItem insertMarkerMenuItem;
|
||||
@@ -425,4 +424,20 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
|
||||
locationPermissionRequest.launch(permissions);
|
||||
}
|
||||
}
|
||||
|
||||
private void onGpsStatusChanged(GpsStatusValue gpsStatusValue) {
|
||||
if (gpsStatusValue.isGpsStarted() && snackbar != null && snackbar.isShown()) {
|
||||
snackbar.dismiss();
|
||||
return;
|
||||
}
|
||||
if (gpsStatusValue != GpsStatusValue.GPS_DISABLED) {
|
||||
return;
|
||||
}
|
||||
snackbar = Snackbar
|
||||
.make(viewBinding.trackRecordingCoordinatorLayout,
|
||||
getString(R.string.gps_recording_status, getString(gpsStatusValue.message), getString(R.string.gps_recording_without_signal)),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(getString(R.string.generic_dismiss), v -> {});
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.util.List;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.adapters.StatisticsAdapter;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.databinding.StatisticsRecordingBinding;
|
||||
import de.dennisguse.opentracks.services.RecordingData;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
@@ -45,8 +44,9 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
}
|
||||
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
|
||||
private RecordingData recordingData = TrackRecordingService.NOT_RECORDING;
|
||||
private TrackPoint latestTrackPoint;
|
||||
|
||||
private Layout layout;
|
||||
|
||||
private StatisticsRecordingBinding viewBinding;
|
||||
@@ -76,8 +76,10 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
}
|
||||
};
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> service.getRecordingDataObservable()
|
||||
.observe(StatisticsRecordingFragment.this, this::onRecordingDataChanged);
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
|
||||
service.getRecordingDataObservable()
|
||||
.observe(StatisticsRecordingFragment.this, this::onRecordingDataChanged);
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@@ -168,11 +170,6 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(null, getString(R.string.stats_rate_key));
|
||||
}
|
||||
|
||||
latestTrackPoint = recordingData.getLatestTrackPoint();
|
||||
if (latestTrackPoint != null && latestTrackPoint.hasLocation() && !latestTrackPoint.isRecent()) {
|
||||
latestTrackPoint = null;
|
||||
}
|
||||
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class GpsStatus {
|
||||
|
||||
public void stop() {
|
||||
stopped = true;
|
||||
sendStatus(gpsStatus, GpsStatusValue.GPS_NONE);
|
||||
sendStatus(gpsStatus, GpsStatusValue.GPS_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -17,22 +19,29 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/track_detail_activity_tablayout"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/track_detail_activity_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/track_detail_activity_tablayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/track_recording_coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/track_detail_activity_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/StatsScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/stats_recycler_view"
|
||||
@@ -14,4 +14,4 @@
|
||||
app:layout_constraintStart_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -11,15 +13,23 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/track_detail_activity_view_pager"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/track_recording_coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/track_detail_activity_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/controller_fragment"
|
||||
android:name="de.dennisguse.opentracks.ControllerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -42,4 +42,5 @@ limitations under the License.
|
||||
<color name="track_controller_background_activated">#3F0000</color>
|
||||
|
||||
<color name="splashscreen_background">#272727</color>
|
||||
|
||||
</resources>
|
||||
@@ -244,12 +244,15 @@ limitations under the License.
|
||||
<string name="generic_to">To</string>
|
||||
<string name="generic_today">Today</string>
|
||||
<string name="generic_yesterday">Yesterday</string>
|
||||
<string name="generic_dismiss">Dismiss</string>
|
||||
<!-- Gps -->
|
||||
<string name="gps_starting">Starting GPS</string>
|
||||
<string name="gps_wait_for_better_signal">Waiting for a better GPS signal</string>
|
||||
<string name="gps_wait_for_signal">Waiting for GPS signal</string>
|
||||
<string name="gps_disabled_msg">GPS disabled</string>
|
||||
<string name="gps_fixed_and_ready">GPS fixed and ready</string>
|
||||
<string name="gps_recording_status">%1$s: %2$s</string>
|
||||
<string name="gps_recording_without_signal">OpenTracks is recording without GPS data.</string>
|
||||
<!-- Image -->
|
||||
<string name="image_arrow">Arrow</string>
|
||||
<string name="image_marker">Marker</string>
|
||||
|
||||
@@ -333,4 +333,29 @@ limitations under the License.
|
||||
<item name="cardPreventCornerOverlap">true</item>
|
||||
<item name="cardUseCompatPadding">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Snackbar -->
|
||||
<style name="MaterialSnackbarTheme" parent="@style/Widget.MaterialComponents.Snackbar">
|
||||
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Snackbar</item>
|
||||
<item name="actionTextColorAlpha">1</item>
|
||||
|
||||
<item name="backgroundTint">@android:color/holo_red_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="MaterialSnackbarTextButtonTheme" parent="@style/Widget.MaterialComponents.Button.TextButton.Snackbar">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="MaterialSnackbarTextViewTheme" parent="@style/Widget.MaterialComponents.Snackbar.TextView">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:textAppearance">?textAppearanceLabelMedium</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.App.Snackbar" parent="">
|
||||
<item name="colorSurface">@android:color/holo_red_dark</item>
|
||||
<item name="colorOnSurface">@android:color/holo_red_dark</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -23,6 +23,12 @@ limitations under the License.
|
||||
<item name="android:activatedBackgroundIndicator">@drawable/activated_background</item>
|
||||
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
|
||||
<!-- Snackbar -->
|
||||
<item name="snackbarStyle">@style/MaterialSnackbarTheme</item>
|
||||
<item name="snackbarButtonStyle">@style/MaterialSnackbarTextButtonTheme</item>
|
||||
<item name="snackbarTextViewStyle">@style/MaterialSnackbarTextViewTheme</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="SplashTheme" parent="ThemeCustom">
|
||||
|
||||
Reference in New Issue
Block a user