From ed6daeb48b504b4cfcc25664defa5ca0c9b33047 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Mon, 10 May 2021 22:33:39 +0200 Subject: [PATCH] TrackController is now ControllerFragment. --- .../dennisguse/opentracks/EspressoUITest.java | 10 +- .../opentracks/ControllerFragment.java | 299 ++++++++++++++++++ .../opentracks/MarkerListActivity.java | 2 +- .../opentracks/TrackController.java | 260 --------------- .../opentracks/TrackListActivity.java | 36 +-- .../opentracks/TrackRecordingActivity.java | 15 +- .../opentracks/util/ActivityUtils.java | 17 +- ...ckground.xml => controller_background.xml} | 0 .../res/layout-land/controller_fragment.xml | 66 ++++ src/main/res/layout-land/track_controller.xml | 69 ---- src/main/res/layout-land/track_list.xml | 8 +- src/main/res/layout-land/track_recording.xml | 8 +- src/main/res/layout/controller_fragment.xml | 72 +++++ src/main/res/layout/track_controller.xml | 75 ----- src/main/res/layout/track_list.xml | 8 +- src/main/res/layout/track_recording.xml | 8 +- 16 files changed, 469 insertions(+), 484 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/ControllerFragment.java delete mode 100644 src/main/java/de/dennisguse/opentracks/TrackController.java rename src/main/res/drawable/{track_controller_background.xml => controller_background.xml} (100%) create mode 100644 src/main/res/layout-land/controller_fragment.xml delete mode 100644 src/main/res/layout-land/track_controller.xml create mode 100644 src/main/res/layout/controller_fragment.xml delete mode 100644 src/main/res/layout/track_controller.xml diff --git a/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java b/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java index c3322ed4d..a2453e969 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java @@ -39,13 +39,13 @@ public class EspressoUITest { public void record_pause_resume_stop() { { // TrackListActivity: start recording - ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_controller_record)); + ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record)); trackControllerRecordButton.perform(click()); } { // TrackRecordingActivity - ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_controller_record)); - ViewInteraction trackControllerStopButton = onView(withId(R.id.track_controller_stop)); + ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record)); + ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop)); // wait; stay recording trackControllerRecordButton.perform(waitFor(5000)); @@ -72,13 +72,13 @@ public class EspressoUITest { public void record_move_through_tabs() { { // TrackListActivity: start recording - ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_controller_record)); + ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record)); trackControllerRecordButton.perform(click()); } { // TrackRecordingActivity ViewInteraction tabLayout = onView(withId(R.id.track_detail_activity_tablayout)); - ViewInteraction trackControllerStopButton = onView(withId(R.id.track_controller_stop)); + ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop)); tabLayout.perform(selectTabAtIndex(1)); tabLayout.perform(waitFor(1000)); diff --git a/src/main/java/de/dennisguse/opentracks/ControllerFragment.java b/src/main/java/de/dennisguse/opentracks/ControllerFragment.java new file mode 100644 index 000000000..e1af60ad6 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/ControllerFragment.java @@ -0,0 +1,299 @@ +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package de.dennisguse.opentracks; + +import android.annotation.SuppressLint; +import android.graphics.drawable.TransitionDrawable; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import java.time.Duration; + +import de.dennisguse.opentracks.databinding.ControllerFragmentBinding; +import de.dennisguse.opentracks.services.TrackRecordingService; +import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; +import de.dennisguse.opentracks.util.ActivityUtils; +import de.dennisguse.opentracks.util.StringUtils; + +/** + * Track controller for record, pause, resume, and stop. + * + * @author Jimmy Shih + */ +//TODO Move buttons into separate components +public class ControllerFragment extends Fragment implements View.OnTouchListener { + + private static final String TAG = ControllerFragment.class.getSimpleName(); + + @Deprecated + //TODO TrackRecordingService should provide LifeData for time (replace internal timer) + private static final Duration UI_UPDATE_INTERVAL = Duration.ofSeconds(1); + @Deprecated + private Handler handlerUpdateTotalTime; + + private Runnable buttonDelay; + private int buttonDelayDuration; + + private ControllerFragmentBinding viewBinding; + private TransitionDrawable transition; + + private TrackRecordingServiceConnection trackRecordingServiceConnection; + private TrackRecordingService.RecordingStatus recordingStatus; + private Duration totalTime; + + private final Runnable bindChangedCallback = new Runnable() { + @Override + public void run() { + TrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound(); + if (service == null) { + Log.w(TAG, "could not get TrackRecordingService"); + return; + } + + service.getRecordingStatusObservable() + .observe(ControllerFragment.this, status -> onRecordingStatusChanged(status)); + } + }; + + // A runnable to update the total time. + @Deprecated + private final Runnable updateTotalTimeRunnable = new Runnable() { + public void run() { + if (isResumed() && recordingStatus.isRecordingAndNotPaused()) { + updateTotalTime(); + setTotalTime(); + handlerUpdateTotalTime.postDelayed(this, UI_UPDATE_INTERVAL.toMillis()); + } + } + }; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + buttonDelayDuration = getResources().getInteger(R.integer.buttonDelayMillis); + + trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback); + handlerUpdateTotalTime = new Handler(); + recordingStatus = TrackRecordingService.STATUS_DEFAULT; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + viewBinding = ControllerFragmentBinding.inflate(inflater, container, false); + + viewBinding.controllerRecord.setOnTouchListener(this); + viewBinding.controllerRecord.setOnClickListener((view) -> { + if (buttonDelay != null || recordingStatus.isRecordingAndNotPaused()) { + return; + } + + getCallback().recordStart(); + }); + + viewBinding.controllerStop.setOnTouchListener(this); + transition = (TransitionDrawable) viewBinding.controllerContainer.getBackground(); + + onRecordingStatusChanged(recordingStatus); + + return viewBinding.getRoot(); + } + + @Override + public void onResume() { + super.onResume(); + trackRecordingServiceConnection.startConnection(getContext()); + } + + @Override + public void onPause() { + super.onPause(); + handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable); + } + + @Override + public void onStop() { + super.onStop(); + trackRecordingServiceConnection.unbind(getContext()); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + viewBinding = null; + transition = null; + } + + @Override + public void onDestroy() { + super.onDestroy(); + trackRecordingServiceConnection = null; + handlerUpdateTotalTime = null; + recordingStatus = null; + } + + //TODO Move into a separate object + @SuppressLint("ClickableViewAccessibility") //We do accessibility manually. + @Override + public boolean onTouch(final View view, MotionEvent event) { + if (!isResumed()) { + Log.w(TAG, "The UI is already gone, no need to update anything; seen on Android 7.1.2"); + return false; + } + if (event.getAction() == MotionEvent.ACTION_MOVE) { + return false; + } + + if (buttonDelay != null && event.getAction() == MotionEvent.ACTION_UP) { + handlerUpdateTotalTime.removeCallbacks(buttonDelay); + buttonDelay = null; + view.setPressed(false); + + transition.resetTransition(); + + showStatusSetDefaultText(); + + return false; + } + + //Trigger button pressed animation + view.setPressed(true); + + //To pause a recording + if (viewBinding.controllerRecord.equals(view) + && event.getAction() == MotionEvent.ACTION_DOWN + && recordingStatus.isRecordingAndNotPaused()) { + + transition.startTransition(buttonDelayDuration); + + ActivityUtils.vibrate(getContext(), 150); + viewBinding.controllerStatus.setText(R.string.hold_to_pause); + + buttonDelay = () -> { + view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); + view.performClick(); + getCallback().recordPause(); + + transition.resetTransition(); + + ActivityUtils.vibrate(getContext(), 1000); + }; + handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration); + return true; + } + + //To stop a recording + if (viewBinding.controllerStop.equals(view) + && event.getAction() == MotionEvent.ACTION_DOWN + && recordingStatus.isRecording()) { + + + transition.startTransition(buttonDelayDuration); + + ActivityUtils.vibrate(getContext(), 150); + viewBinding.controllerStatus.setText(R.string.hold_to_stop); + + buttonDelay = () -> { + view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); + getCallback().recordStop(); + ActivityUtils.vibrate(getContext(), 1000); + + transition.resetTransition(); + }; + handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration); + return true; + } + + return false; + } + + public void hide() { + viewBinding.controllerContainer.setVisibility(View.GONE); + } + + public void show() { + viewBinding.controllerContainer.setVisibility(View.VISIBLE); + } + + private void updateTotalTime() { + TrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound(); + if (trackRecordingService != null) { + totalTime = trackRecordingService.getTotalTime(); + } + } + + private void setTotalTime() { + if (totalTime != null) { + viewBinding.controllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(totalTime)); + } + } + + private void showStatusSetDefaultText() { + viewBinding.controllerStatus.setText(recordingStatus.isPaused() ? R.string.generic_paused : R.string.generic_recording); + } + + private Callback getCallback() { + return (Callback) getActivity(); + } + + public interface Callback { + void recordStart(); + + void recordPause(); + + void recordStop(); + } + + private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) { + recordingStatus = status; + + if (!recordingStatus.isRecording()) { + handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable); + } + if (recordingStatus.isRecordingAndNotPaused()) { + handlerUpdateTotalTime.postDelayed(updateTotalTimeRunnable, UI_UPDATE_INTERVAL.toMillis()); + } + + viewBinding.controllerRecord.setImageResource(recordingStatus.isRecordingAndNotPaused() ? R.drawable.ic_button_pause : R.drawable.button_record); + viewBinding.controllerRecord.setContentDescription(getContext().getString(recordingStatus.isRecordingAndNotPaused() ? R.string.image_pause : R.string.image_record)); + + viewBinding.controllerStop.setEnabled(recordingStatus.isRecording()); + + viewBinding.controllerStatus.setVisibility(recordingStatus.isRecording() ? View.VISIBLE : View.INVISIBLE); + if (recordingStatus.isRecording()) { + viewBinding.controllerStatus.setTextColor(getContext().getResources().getColor(recordingStatus.isPaused() ? android.R.color.white : R.color.recording_text)); + showStatusSetDefaultText(); + } + + viewBinding.controllerTotalTime.setVisibility(recordingStatus.isRecording() ? View.VISIBLE : View.INVISIBLE); + + if (recordingStatus.isRecording()) { + updateTotalTime(); + setTotalTime(); + } + } +} diff --git a/src/main/java/de/dennisguse/opentracks/MarkerListActivity.java b/src/main/java/de/dennisguse/opentracks/MarkerListActivity.java index 4053334eb..a8d2bf9a9 100644 --- a/src/main/java/de/dennisguse/opentracks/MarkerListActivity.java +++ b/src/main/java/de/dennisguse/opentracks/MarkerListActivity.java @@ -175,7 +175,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker insertMarkerMenuItem = menu.findItem(R.id.marker_list_insert_marker); searchMenuItem = menu.findItem(R.id.marker_list_search); - ActivityUtils.configureSearchWidget(this, searchMenuItem, null); + ActivityUtils.configureSearchWidget(this, searchMenuItem); return super.onCreateOptionsMenu(menu); } diff --git a/src/main/java/de/dennisguse/opentracks/TrackController.java b/src/main/java/de/dennisguse/opentracks/TrackController.java deleted file mode 100644 index 82afa4817..000000000 --- a/src/main/java/de/dennisguse/opentracks/TrackController.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package de.dennisguse.opentracks; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.graphics.drawable.TransitionDrawable; -import android.os.Handler; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; - -import java.time.Duration; - -import de.dennisguse.opentracks.databinding.TrackControllerBinding; -import de.dennisguse.opentracks.services.TrackRecordingService; -import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; -import de.dennisguse.opentracks.util.ActivityUtils; -import de.dennisguse.opentracks.util.StringUtils; - -/** - * Track controller for record, pause, resume, and stop. - * - * @author Jimmy Shih - */ -//TODO Subscribe to TrackRecordingService.recordingStatus -//TODO Could be a fragment -public class TrackController implements View.OnTouchListener { - - private static final String TAG = TrackController.class.getSimpleName(); - - private static final Duration UI_UPDATE_INTERVAL = Duration.ofSeconds(1); - - private final Activity activity; - private final TrackRecordingServiceConnection trackRecordingServiceConnection; - private final Handler handlerUpdateTotalTime = new Handler(); - private final boolean alwaysShow; - - private Runnable buttonDelay; - private final int buttonDelayDuration; - - private final TrackControllerBinding viewBinding; - private final TransitionDrawable transition; - - - private TrackRecordingService.RecordingStatus recordingStatus; - private Duration totalTime; - - private final Callback callback; - - // A runnable to update the total time. - private final Runnable updateTotalTimeRunnable = new Runnable() { - public void run() { - if (isResumed() && recordingStatus.isRecordingAndNotPaused()) { - updateTotalTime(); - setTotalTime(); - handlerUpdateTotalTime.postDelayed(this, UI_UPDATE_INTERVAL.toMillis()); - } - } - }; - - @SuppressLint("ClickableViewAccessibility") - TrackController(Activity activity, TrackControllerBinding viewBinding, TrackRecordingServiceConnection trackRecordingServiceConnection, boolean alwaysShow, Callback callback) { - this.activity = activity; - this.viewBinding = viewBinding; - this.trackRecordingServiceConnection = trackRecordingServiceConnection; - this.alwaysShow = alwaysShow; - this.callback = callback; - - buttonDelayDuration = activity.getResources().getInteger(R.integer.buttonDelayMillis); - - viewBinding.trackControllerRecord.setOnTouchListener(this); - viewBinding.trackControllerRecord.setOnClickListener((view) -> { - if (buttonDelay != null || recordingStatus.isRecordingAndNotPaused()) { - return; - } - - callback.recordStart(); - }); - - viewBinding.trackControllerStop.setOnTouchListener(this); - transition = (TransitionDrawable) viewBinding.trackControllerContainer.getBackground(); - } - - @SuppressLint("ClickableViewAccessibility") //We do accessibility manually. - @Override - public boolean onTouch(final View view, MotionEvent event) { - if (!isResumed()) { - Log.w(TAG, "The UI is already gone, no need to update anything; seen on Android 7.1.2"); - return false; - } - if (event.getAction() == MotionEvent.ACTION_MOVE) { - return false; - } - - if (buttonDelay != null && event.getAction() == MotionEvent.ACTION_UP) { - handlerUpdateTotalTime.removeCallbacks(buttonDelay); - buttonDelay = null; - view.setPressed(false); - - transition.resetTransition(); - - showStatusSetDefaultText(); - - return false; - } - - //Trigger button pressed animation - view.setPressed(true); - - //To pause a recording - if (viewBinding.trackControllerRecord.equals(view) - && event.getAction() == MotionEvent.ACTION_DOWN - && recordingStatus.isRecordingAndNotPaused()) { - - transition.startTransition(buttonDelayDuration); - - ActivityUtils.vibrate(activity, 150); - viewBinding.trackControllerStatus.setText(R.string.hold_to_pause); - - buttonDelay = () -> { - view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - view.performClick(); - callback.recordPause(); - - transition.resetTransition(); - - ActivityUtils.vibrate(activity, 1000); - }; - handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration); - return true; - } - - //To stop a recording - if (viewBinding.trackControllerStop.equals(view) - && event.getAction() == MotionEvent.ACTION_DOWN - && recordingStatus.isRecording()) { - - - transition.startTransition(buttonDelayDuration); - - ActivityUtils.vibrate(activity, 150); - viewBinding.trackControllerStatus.setText(R.string.hold_to_stop); - - buttonDelay = () -> { - view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - callback.recordStop(); - ActivityUtils.vibrate(activity, 1000); - - transition.resetTransition(); - }; - handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration); - return true; - } - - return false; - } - - public void update(TrackRecordingService.RecordingStatus recordingStatus) { - if (!isResumed()) { - handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable); - return; - } - - this.recordingStatus = recordingStatus; - boolean isRecording = recordingStatus.isRecording(); - boolean isRecordingPaused = recordingStatus.isPaused(); - boolean visible = alwaysShow || isRecording; - viewBinding.trackControllerContainer.setVisibility(visible ? View.VISIBLE : View.GONE); - - if (!visible) { - handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable); - return; - } - - if (isRecording && !isRecordingPaused) { - handlerUpdateTotalTime.postDelayed(updateTotalTimeRunnable, UI_UPDATE_INTERVAL.toMillis()); - } - - viewBinding.trackControllerRecord.setImageResource(isRecording && !isRecordingPaused ? R.drawable.ic_button_pause : R.drawable.button_record); - viewBinding.trackControllerRecord.setContentDescription(activity.getString(isRecording && !isRecordingPaused ? R.string.image_pause : R.string.image_record)); - - viewBinding.trackControllerStop.setEnabled(isRecording); - - viewBinding.trackControllerStatus.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE); - if (isRecording) { - viewBinding.trackControllerStatus.setTextColor(activity.getResources().getColor(isRecordingPaused ? android.R.color.white : R.color.recording_text)); - showStatusSetDefaultText(); - } - - viewBinding.trackControllerTotalTime.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE); - - if (recordingStatus.isRecording()) { - updateTotalTime(); - setTotalTime(); - } - } - - void onResume(TrackRecordingService.RecordingStatus recordingStatus) { - this.recordingStatus = recordingStatus; - update(recordingStatus); - } - - void onPause() { - recordingStatus = null; - handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable); - } - - public void hide() { - viewBinding.trackControllerContainer.setVisibility(View.GONE); - } - - public void show() { - viewBinding.trackControllerContainer.setVisibility(View.VISIBLE); - } - - private void updateTotalTime() { - TrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound(); - if (trackRecordingService != null) { - totalTime = trackRecordingService.getTotalTime(); - } - } - - private void setTotalTime() { - if (totalTime != null) { - viewBinding.trackControllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(totalTime)); - } - } - - private void showStatusSetDefaultText() { - viewBinding.trackControllerStatus.setText(recordingStatus.isPaused() ? R.string.generic_paused : R.string.generic_recording); - } - - private boolean isResumed() { - return recordingStatus != null; - } - - public interface Callback { - void recordStart(); - - void recordPause(); - - void recordStop(); - } -} diff --git a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java index 07ea5b701..e87372e56 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java @@ -71,14 +71,13 @@ import de.dennisguse.opentracks.util.TrackIconUtils; * * @author Leif Hendrik Wilden */ -public class TrackListActivity extends AbstractListActivity implements ConfirmDeleteDialogFragment.ConfirmDeleteCaller, TrackController.Callback { +public class TrackListActivity extends AbstractListActivity implements ConfirmDeleteDialogFragment.ConfirmDeleteCaller, ControllerFragment.Callback { private static final String TAG = TrackListActivity.class.getSimpleName(); // The following are set in onCreate private SharedPreferences sharedPreferences; private TrackRecordingServiceConnection trackRecordingServiceConnection; - private TrackController trackController; private ResourceCursorAdapter resourceCursorAdapter; private TrackListBinding viewBinding; @@ -118,7 +117,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe runOnUiThread(() -> { TrackListActivity.this.invalidateOptionsMenu(); loaderCallbacks.restart(); - trackController.onResume(recordingStatus); }); } } @@ -132,9 +130,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe private final Runnable bindChangedCallback = new Runnable() { @Override public void run() { - // After binding changes (e.g., becomes available), update the total time in trackController. - runOnUiThread(() -> trackController.update(recordingStatus)); - TrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound(); if (service == null) { Log.e(TAG, "service not available to start gps or a new recording"); @@ -170,14 +165,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe sharedPreferences = PreferencesUtils.getSharedPreferences(this); trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback); - trackController = new TrackController(this, viewBinding.trackControllerContainer, trackRecordingServiceConnection, true, this); - - - // Show trackController when search dialog is dismissed - SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE); - if (searchManager != null) { - searchManager.setOnDismissListener(() -> trackController.show()); - } viewBinding.trackList.setEmptyView(viewBinding.trackListEmptyView); viewBinding.trackList.setOnItemClickListener((parent, view, position, trackId) -> { @@ -250,14 +237,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe trackRecordingServiceConnection.startConnection(this); } - @Override - protected void onPause() { - super.onPause(); - - // Update UI - trackController.onPause(); - } - @Override protected void onResume() { super.onResume(); @@ -265,7 +244,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe // Update UI this.invalidateOptionsMenu(); LoaderManager.getInstance(this).restartLoader(0, null, loaderCallbacks); - trackController.onResume(recordingStatus); } @Override @@ -298,7 +276,7 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe getMenuInflater().inflate(R.menu.track_list, menu); searchMenuItem = menu.findItem(R.id.track_list_search); - ActivityUtils.configureSearchWidget(this, searchMenuItem, trackController); + ActivityUtils.configureSearchWidget(this, searchMenuItem); startGpsMenuItem = menu.findItem(R.id.track_list_start_gps); return super.onCreateOptionsMenu(menu); @@ -396,13 +374,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe loaderCallbacks.setSearch(searchQuery); } - @Override - public boolean onSearchRequested() { - // Hide trackController when search dialog is shown - trackController.hide(); - return super.onSearchRequested(); - } - @Override protected TrackRecordingServiceConnection getTrackRecordingServiceConnection() { return trackRecordingServiceConnection; @@ -585,10 +556,7 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe updateGpsMenuItem(true, recordingStatus.isRecording()); } - private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) { recordingStatus = status; - - trackController.update(recordingStatus); } } diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java index 5c6cb2e90..f9054622d 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java @@ -43,7 +43,7 @@ import de.dennisguse.opentracks.util.TrackUtils; */ //NOTE: This activity does NOT react to preference changes of R.string.recording_track_id_key. //This mode of communication should be removed anyhow. -public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackActivityDataHubInterface, TrackController.Callback { +public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackActivityDataHubInterface, ControllerFragment.Callback { public static final String EXTRA_TRACK_ID = "track_id"; @@ -56,7 +56,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc private SharedPreferences sharedPreferences; private TrackRecordingServiceConnection trackRecordingServiceConnection; private TrackDataHub trackDataHub; - private TrackController trackController; private TrackRecordingBinding viewBinding; @@ -90,8 +89,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc // A recording track is on. trackDataHub.loadTrack(trackId); trackDataHub.setRecordingStatus(recordingStatus); - - trackController.onResume(recordingStatus); } } }; @@ -148,8 +145,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc if (savedInstanceState != null) { viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY)); } - - trackController = new TrackController(this, viewBinding.trackControllerContainer, trackRecordingServiceConnection, false, this); } @Override @@ -214,7 +209,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc //TODO Pass recordingStatus directly to them trackDataHub.loadTrack(trackId); trackDataHub.setRecordingStatus(recordingStatus); - trackController.onResume(recordingStatus); } /* @@ -233,12 +227,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc outState.putParcelable(EXTRA_TRACK_ID, trackId); } - @Override - protected void onPause() { - super.onPause(); - trackController.onPause(); - } - @Override protected void onStop() { super.onStop(); @@ -406,7 +394,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) { recordingStatus = status; - trackController.update(recordingStatus); trackDataHub.setRecordingStatus(recordingStatus); setLockscreenPolicy(); diff --git a/src/main/java/de/dennisguse/opentracks/util/ActivityUtils.java b/src/main/java/de/dennisguse/opentracks/util/ActivityUtils.java index d30b98fb9..59b4049ca 100644 --- a/src/main/java/de/dennisguse/opentracks/util/ActivityUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/ActivityUtils.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import de.dennisguse.opentracks.ContextualActionModeCallback; import de.dennisguse.opentracks.R; -import de.dennisguse.opentracks.TrackController; import static android.content.Context.VIBRATOR_SERVICE; @@ -88,7 +87,7 @@ public class ActivityUtils { }); } - public static void configureSearchWidget(Activity activity, final MenuItem menuItem, final TrackController trackController) { + public static void configureSearchWidget(Activity activity, final MenuItem menuItem) { final SearchView searchView = (SearchView) menuItem.getActionView(); SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE); if (searchManager != null) { @@ -99,16 +98,6 @@ public class ActivityUtils { } searchView.setQueryRefinementEnabled(true); searchView.setSubmitButtonEnabled(true); - searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> { - // Hide and show trackController when searchable widget has focus/no focus - if (trackController != null) { - if (hasFocus) { - trackController.hide(); - } else { - trackController.show(); - } - } - }); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override @@ -136,8 +125,8 @@ public class ActivityUtils { }); } - public static void vibrate(Activity activity, int milliseconds) { - final Vibrator vibrator = (Vibrator) activity.getSystemService(VIBRATOR_SERVICE); + public static void vibrate(Context context, int milliseconds) { + final Vibrator vibrator = (Vibrator) context.getSystemService(VIBRATOR_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE)); } else { diff --git a/src/main/res/drawable/track_controller_background.xml b/src/main/res/drawable/controller_background.xml similarity index 100% rename from src/main/res/drawable/track_controller_background.xml rename to src/main/res/drawable/controller_background.xml diff --git a/src/main/res/layout-land/controller_fragment.xml b/src/main/res/layout-land/controller_fragment.xml new file mode 100644 index 000000000..62e84afd0 --- /dev/null +++ b/src/main/res/layout-land/controller_fragment.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + diff --git a/src/main/res/layout-land/track_controller.xml b/src/main/res/layout-land/track_controller.xml deleted file mode 100644 index 74f5ec79b..000000000 --- a/src/main/res/layout-land/track_controller.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/res/layout-land/track_list.xml b/src/main/res/layout-land/track_list.xml index ea5d84572..56b71fa7a 100644 --- a/src/main/res/layout-land/track_list.xml +++ b/src/main/res/layout-land/track_list.xml @@ -27,9 +27,11 @@ limitations under the License. android:baselineAligned="false" android:orientation="horizontal"> - + - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/track_controller.xml b/src/main/res/layout/track_controller.xml deleted file mode 100644 index 716c39475..000000000 --- a/src/main/res/layout/track_controller.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/res/layout/track_list.xml b/src/main/res/layout/track_list.xml index faeac71d9..5dde0c60f 100644 --- a/src/main/res/layout/track_list.xml +++ b/src/main/res/layout/track_list.xml @@ -83,7 +83,9 @@ limitations under the License. - + \ No newline at end of file diff --git a/src/main/res/layout/track_recording.xml b/src/main/res/layout/track_recording.xml index 438ff2f57..d43d458ee 100644 --- a/src/main/res/layout/track_recording.xml +++ b/src/main/res/layout/track_recording.xml @@ -17,7 +17,9 @@ android:layout_height="0dp" android:layout_weight="1" /> - + \ No newline at end of file