mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-09-30 16:52:21 +02:00
@@ -130,6 +130,7 @@ The API can be invoked by sending an explicit Intent to start an activity.
|
||||
|
||||
`Class`:
|
||||
* **Start a recording:** `de.dennisguse.opentracks.publicapi.StartRecording`
|
||||
* **Start a recording:** `de.dennisguse.opentracks.publicapi.StopRecording`
|
||||
|
||||
For testing via adb: `adb shell am start -n "package/class"`
|
||||
|
||||
|
||||
@@ -77,14 +77,14 @@ limitations under the License.
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".publicapi.StopRecording"-->
|
||||
<!-- android:exported="true"-->
|
||||
<!-- android:theme="@style/SplashTheme">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </activity>-->
|
||||
<activity
|
||||
android:name=".publicapi.StopRecording"
|
||||
android:exported="true"
|
||||
android:theme="@style/SplashTheme">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".AboutActivity" />
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
@@ -139,7 +138,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
private MenuItem searchMenuItem;
|
||||
private MenuItem startGpsMenuItem;
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
|
||||
service.getRecordingStatusObservable()
|
||||
.observe(TrackListActivity.this, this::onRecordingStatusChanged);
|
||||
|
||||
@@ -167,16 +166,15 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
||||
|
||||
viewBinding.trackList.setEmptyView(viewBinding.trackListEmptyView);
|
||||
viewBinding.trackList.setOnItemClickListener((parent, view, position, trackId) -> {
|
||||
if (recordingStatus.isRecording() && trackId == recordingStatus.getTrackId().getId()) {
|
||||
viewBinding.trackList.setOnItemClickListener((parent, view, position, trackIdId) -> {
|
||||
Track.Id trackId = new Track.Id(trackIdId);
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
|
||||
if (recordingStatus.isRecording() && trackId.equals(recordingStatus.getTrackId())) {
|
||||
// Is recording -> open record activity.
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, new Track.Id(trackId));
|
||||
startActivity(newIntent);
|
||||
} else {
|
||||
// Not recording -> open detail activity.
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
|
||||
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, new Track.Id(trackId));
|
||||
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||
this,
|
||||
new Pair<>(view.findViewById(R.id.list_item_icon), TrackRecordedActivity.VIEW_TRACK_ICON));
|
||||
@@ -230,8 +228,15 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
|
||||
// Not Recording -> Recording
|
||||
updateGpsMenuItem(false, true);
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
|
||||
startActivity(newIntent);
|
||||
new TrackRecordingServiceConnection((service, connection) -> {
|
||||
Track.Id trackId = service.startNewTrack();
|
||||
|
||||
Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
|
||||
newIntent.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(newIntent);
|
||||
|
||||
connection.unbind(this);
|
||||
}).startAndBind(this);
|
||||
});
|
||||
viewBinding.trackListFabAction.setOnLongClickListener((view) -> {
|
||||
if (!recordingStatus.isRecording()) {
|
||||
|
||||
@@ -79,7 +79,7 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
|
||||
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindCallback = service -> service.getRecordingStatusObservable()
|
||||
private final TrackRecordingServiceConnection.Callback bindCallback = (service, unused) -> service.getRecordingStatusObservable()
|
||||
.observe(TrackRecordedActivity.this, this::onRecordingStatusChanged);
|
||||
|
||||
@Override
|
||||
@@ -203,11 +203,17 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
|
||||
}
|
||||
|
||||
if (item.getItemId() == R.id.track_detail_resume_track) {
|
||||
Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(newIntent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
finish();
|
||||
new TrackRecordingServiceConnection((service, connection) -> {
|
||||
service.resumeTrack(trackId);
|
||||
|
||||
Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
|
||||
startActivity(newIntent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
|
||||
connection.unbind(this);
|
||||
finish();
|
||||
}).startAndBind(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,6 @@ import de.dennisguse.opentracks.util.TrackUtils;
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
//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, TrackDataHubInterface {
|
||||
|
||||
public static final String EXTRA_TRACK_ID = "track_id";
|
||||
@@ -76,13 +74,11 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
|
||||
private TrackRecordingBinding viewBinding;
|
||||
|
||||
// Initialized from Intent; if a new track recording is started, a new TrackId will be provided by TrackRecordingService
|
||||
@Deprecated
|
||||
private Track.Id trackId;
|
||||
|
||||
private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT;
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
|
||||
service.getRecordingStatusObservable()
|
||||
.observe(TrackRecordingActivity.this, this::onRecordingStatusChanged);
|
||||
|
||||
@@ -90,18 +86,12 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
.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);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
trackDataHub.loadTrack(trackId);
|
||||
trackDataHub.setRecordingStatus(recordingStatus);
|
||||
};
|
||||
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
|
||||
@@ -123,17 +113,14 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
contentProviderUtils = new ContentProviderUtils(this);
|
||||
trackId = null;
|
||||
if (savedInstanceState != null) {
|
||||
//Activity was recreated.
|
||||
trackId = savedInstanceState.getParcelable(EXTRA_TRACK_ID);
|
||||
} else {
|
||||
// Resume a track
|
||||
trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
|
||||
if (trackId != null && contentProviderUtils.getTrack(trackId) == null) {
|
||||
Log.w(TAG, "TrackId does not exists; cannot continue the recording.");
|
||||
finish();
|
||||
}
|
||||
|
||||
trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
|
||||
if (trackId == null) {
|
||||
throw new RuntimeException("TrackId is mandatory");
|
||||
}
|
||||
if (contentProviderUtils.getTrack(trackId) == null) {
|
||||
Log.w(TAG, "TrackId does not exists; cannot continue the recording.");
|
||||
finish();
|
||||
}
|
||||
|
||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
||||
@@ -240,7 +227,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(CURRENT_TAB_TAG_KEY, viewBinding.trackDetailActivityViewPager.getCurrentItem());
|
||||
outState.putParcelable(EXTRA_TRACK_ID, trackId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -377,6 +363,9 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
}
|
||||
|
||||
private void onRecordingStatusChanged(RecordingStatus status) {
|
||||
if (!status.isRecording()) {
|
||||
finish();
|
||||
}
|
||||
recordingStatus = status;
|
||||
|
||||
trackDataHub.setRecordingStatus(recordingStatus);
|
||||
@@ -415,7 +404,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
.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 -> {});
|
||||
.setAction(getString(R.string.generic_dismiss), v -> {
|
||||
});
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
}
|
||||
};
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
|
||||
private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
|
||||
service.getRecordingDataObservable()
|
||||
.observe(StatisticsRecordingFragment.this, this::onRecordingDataChanged);
|
||||
};
|
||||
|
||||
@@ -16,27 +16,25 @@ public abstract class AbstractAPIActivity extends AppCompatActivity {
|
||||
|
||||
private final String TAG = AbstractAPIActivity.class.getSimpleName();
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback serviceConnectedCallback = service -> {
|
||||
private final TrackRecordingServiceConnection.Callback serviceConnectedCallback = (service, connection) -> {
|
||||
if (!isFinishing() && !isDestroyed()) {
|
||||
execute(service);
|
||||
}
|
||||
if (isPostExecuteStopService()) {
|
||||
AbstractAPIActivity.this.trackRecordingServiceConnection.unbindAndStop(AbstractAPIActivity.this);
|
||||
connection.unbindAndStop(AbstractAPIActivity.this);
|
||||
} else {
|
||||
AbstractAPIActivity.this.trackRecordingServiceConnection.unbind(AbstractAPIActivity.this);
|
||||
connection.unbind(AbstractAPIActivity.this);
|
||||
}
|
||||
finish();
|
||||
};
|
||||
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (PreferencesUtils.isPublicAPIenabled()) {
|
||||
Log.i(TAG, "Received and trying to execute requested action.");
|
||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(serviceConnectedCallback);
|
||||
trackRecordingServiceConnection.startAndBind(this);
|
||||
new TrackRecordingServiceConnection(serviceConnectedCallback)
|
||||
.startAndBind(this);
|
||||
} else {
|
||||
Toast.makeText(this, getString(R.string.settings_public_api_disabled_toast), Toast.LENGTH_LONG).show();
|
||||
Log.w(TAG, "Public API is disabled; ignoring request.");
|
||||
@@ -44,12 +42,6 @@ public abstract class AbstractAPIActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
trackRecordingServiceConnection = null;
|
||||
}
|
||||
|
||||
protected abstract void execute(TrackRecordingService service);
|
||||
|
||||
protected abstract boolean isPostExecuteStopService();
|
||||
|
||||
+4
-8
@@ -92,15 +92,10 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
|
||||
return;
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.onConnected(trackRecordingService);
|
||||
callback.onConnected(trackRecordingService, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes the track recording service connection.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public void startConnection(@NonNull Context context) {
|
||||
if (trackRecordingService != null) {
|
||||
// Service is already started and bound.
|
||||
@@ -115,6 +110,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
|
||||
/**
|
||||
* Unbinds the service (but leave it running).
|
||||
*/
|
||||
//TODO This is often called for one-shot operations and should be refactored as unbinding is required.
|
||||
public void unbind(Context context) {
|
||||
try {
|
||||
context.unbindService(this);
|
||||
@@ -141,7 +137,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
|
||||
trackRecordingService = value;
|
||||
if (callback != null) {
|
||||
if (value != null) {
|
||||
callback.onConnected(value);
|
||||
callback.onConnected(value, this);
|
||||
} else {
|
||||
callback.onDisconnected();
|
||||
}
|
||||
@@ -214,7 +210,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onConnected(TrackRecordingService service);
|
||||
void onConnected(TrackRecordingService service, TrackRecordingServiceConnection connection);
|
||||
|
||||
default void onDisconnected() {
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class MainSettingsFragment extends PreferenceFragmentCompat {
|
||||
private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT;
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
private final TrackRecordingServiceConnection.Callback bindServiceCallback =
|
||||
service -> service.getRecordingStatusObservable()
|
||||
(service, unused) -> service.getRecordingStatusObservable()
|
||||
.observe(MainSettingsFragment.this, this::onRecordingStatusChanged);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,7 +71,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
|
||||
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
|
||||
private final TrackRecordingServiceConnection.Callback bindCallback = service -> service.getRecordingStatusObservable()
|
||||
private final TrackRecordingServiceConnection.Callback bindCallback = (service, unused) -> service.getRecordingStatusObservable()
|
||||
.observe(MarkerListActivity.this, this::onRecordingStatusChanged);
|
||||
|
||||
// Callback when an item is selected in the contextual action mode
|
||||
|
||||
Reference in New Issue
Block a user