forked from upstream-mirrors/OpenTracks
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bd4ba489c | |||
| dd55b50dad | |||
| 1719d21a5b | |||
| 75ef8d99d4 | |||
| ae06fd1680 | |||
| 2b03f7dea8 | |||
| 7591b012b4 | |||
| 0e089f49f3 | |||
| 5ad1856b13 | |||
| 965dbbe829 | |||
| 262c9886df | |||
| ac5a9ea65d | |||
| ed9b4c8f3d | |||
| 209aa6a8a5 | |||
| 81ee6ac1fa | |||
| 024dd603cb |
+2
-2
@@ -8,5 +8,5 @@
|
|||||||
4. Create changelog (`_version code_.txt`)
|
4. Create changelog (`_version code_.txt`)
|
||||||
5. Create commit with all changes
|
5. Create commit with all changes
|
||||||
6. Push commits
|
6. Push commits
|
||||||
7. Tag newly create commit with _version name_
|
7. Tag newly create commit with _version name_ (e.g., v3.2.1)
|
||||||
8. Push the tagged to public repository
|
8. Push the tagged commit to public repository
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
v3.2.2: OpenTracks
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Removed aggregated stats
|
||||||
|
- Migrated to Material Design
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Fixed export of sensor data
|
||||||
|
- Fixed import of incomplete sensor data
|
||||||
|
|
||||||
|
Developer:
|
||||||
|
- Replaced actionbar with toolbar
|
||||||
|
- Migrated to androidx appcompat (incl. Material Design)
|
||||||
@@ -16,8 +16,8 @@ limitations under the License.
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="de.dennisguse.opentracks"
|
package="de.dennisguse.opentracks"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="3063"
|
android:versionCode="3079"
|
||||||
android:versionName="v3.2.1"> <!-- For FDroid. -->
|
android:versionName="v3.2.2"> <!-- For FDroid. -->
|
||||||
<!-- Permission to initialize services -->
|
<!-- Permission to initialize services -->
|
||||||
<application
|
<application
|
||||||
android:name=".Startup"
|
android:name=".Startup"
|
||||||
@@ -30,10 +30,6 @@ limitations under the License.
|
|||||||
<!-- Activities -->
|
<!-- Activities -->
|
||||||
<activity android:name=".AboutActivity" />
|
<activity android:name=".AboutActivity" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".AggregatedStatsActivity"
|
|
||||||
android:label="@string/menu_aggregated_statistics" />
|
|
||||||
|
|
||||||
<activity android:name=".DeleteActivity" />
|
<activity android:name=".DeleteActivity" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ package de.dennisguse.opentracks;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.speech.tts.TextToSpeech;
|
import android.speech.tts.TextToSpeech;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jimmy Shih
|
* @author Jimmy Shih
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractActivity extends FragmentActivity {
|
public abstract class AbstractActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -34,6 +35,9 @@ public abstract class AbstractActivity extends FragmentActivity {
|
|||||||
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
||||||
|
|
||||||
setContentView(getLayoutResId());
|
setContentView(getLayoutResId());
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,24 +16,7 @@
|
|||||||
|
|
||||||
package de.dennisguse.opentracks;
|
package de.dennisguse.opentracks;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.SearchManager;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
|
||||||
import android.util.SparseBooleanArray;
|
|
||||||
import android.view.ActionMode;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.SearchView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
||||||
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment.ConfirmDeleteCaller;
|
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment.ConfirmDeleteCaller;
|
||||||
@@ -58,115 +41,6 @@ public abstract class AbstractListActivity extends AbstractActivity implements C
|
|||||||
protected static final int GPS_REQUEST_CODE = 6;
|
protected static final int GPS_REQUEST_CODE = 6;
|
||||||
private static final int DELETE_REQUEST_CODE = 3;
|
private static final int DELETE_REQUEST_CODE = 3;
|
||||||
|
|
||||||
public static void configureListViewContextualMenu(final ListView listView, final ContextualActionModeCallback contextualActionModeCallback) {
|
|
||||||
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
|
||||||
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
||||||
mode.getMenuInflater().inflate(R.menu.list_context_menu, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
|
||||||
contextualActionModeCallback.onPrepare(menu, getCheckedPositions(listView), listView.getCheckedItemIds(), true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyActionMode(ActionMode mode) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
|
||||||
mode.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
|
||||||
if (contextualActionModeCallback.onClick(item.getItemId(), getCheckedPositions(listView), listView.getCheckedItemIds())) {
|
|
||||||
mode.finish();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the checked positions in a list view.
|
|
||||||
*
|
|
||||||
* @param list the list view
|
|
||||||
*/
|
|
||||||
private int[] getCheckedPositions(ListView list) {
|
|
||||||
SparseBooleanArray positions = list.getCheckedItemPositions();
|
|
||||||
ArrayList<Integer> arrayList = new ArrayList<>();
|
|
||||||
for (int i = 0; i < positions.size(); i++) {
|
|
||||||
int key = positions.keyAt(i);
|
|
||||||
if (positions.valueAt(i)) {
|
|
||||||
arrayList.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int[] result = new int[arrayList.size()];
|
|
||||||
for (int i = 0; i < arrayList.size(); i++) {
|
|
||||||
result[i] = arrayList.get(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void configureSearchWidget(Activity activity, final MenuItem menuItem, final TrackController trackController) {
|
|
||||||
final SearchView searchView = (SearchView) menuItem.getActionView();
|
|
||||||
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
|
|
||||||
if (searchManager != null) {
|
|
||||||
//NOTE: for some reason activity.getComponentName() did not trigger the SearchListActivity
|
|
||||||
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(activity, SearchListActivity.class)));
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Could not retrieve SearchManager.");
|
|
||||||
}
|
|
||||||
searchView.setQueryRefinementEnabled(true);
|
|
||||||
searchView.setSubmitButtonEnabled(true);
|
|
||||||
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFocusChange(View v, boolean 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
|
|
||||||
public boolean onQueryTextSubmit(String query) {
|
|
||||||
menuItem.collapseActionView();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onQueryTextChange(String newText) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onSuggestionSelect(int position) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSuggestionClick(int position) {
|
|
||||||
menuItem.collapseActionView();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
if (requestCode == DELETE_REQUEST_CODE) {
|
if (requestCode == DELETE_REQUEST_CODE) {
|
||||||
@@ -208,10 +82,9 @@ public abstract class AbstractListActivity extends AbstractActivity implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the track recording service connection. For stopping the current
|
* Gets the track recording service connection.
|
||||||
* recording if need to delete the current recording track.
|
* For stopping the current recording if need to delete the current recording track.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
abstract protected TrackRecordingServiceConnection getTrackRecordingServiceConnection();
|
abstract protected TrackRecordingServiceConnection getTrackRecordingServiceConnection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,62 +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.os.Bundle;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
|
||||||
import de.dennisguse.opentracks.content.Track;
|
|
||||||
import de.dennisguse.opentracks.stats.TripStatistics;
|
|
||||||
import de.dennisguse.opentracks.util.StatsUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An activity to view aggregated stats from all recorded tracks.
|
|
||||||
*
|
|
||||||
* @author Fergus Nelson
|
|
||||||
*/
|
|
||||||
public class AggregatedStatsActivity extends AbstractActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
StatsUtils.setTripStatisticsValues(this, getTripStatistics(), null);
|
|
||||||
StatsUtils.setLocationValues(this, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getLayoutResId() {
|
|
||||||
return R.layout.stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the aggregated trip statistics for all the recorded tracks or null if
|
|
||||||
* there is no track.
|
|
||||||
*/
|
|
||||||
private TripStatistics getTripStatistics() {
|
|
||||||
List<Track> tracks = ContentProviderUtils.Factory.get(this).getAllTracks();
|
|
||||||
TripStatistics tripStatistics = null;
|
|
||||||
if (!tracks.isEmpty()) {
|
|
||||||
tripStatistics = new TripStatistics(tracks.iterator().next().getTripStatistics());
|
|
||||||
for (int i = 1; i < tracks.size(); i++) {
|
|
||||||
tripStatistics.merge(tracks.get(i).getTripStatistics());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tripStatistics;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,14 +22,11 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
@@ -46,6 +43,7 @@ import de.dennisguse.opentracks.content.Waypoint.WaypointType;
|
|||||||
import de.dennisguse.opentracks.content.WaypointsColumns;
|
import de.dennisguse.opentracks.content.WaypointsColumns;
|
||||||
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment;
|
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment;
|
||||||
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
|
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
|
||||||
|
import de.dennisguse.opentracks.util.ActivityUtils;
|
||||||
import de.dennisguse.opentracks.util.IntentUtils;
|
import de.dennisguse.opentracks.util.IntentUtils;
|
||||||
import de.dennisguse.opentracks.util.ListItemUtils;
|
import de.dennisguse.opentracks.util.ListItemUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
@@ -175,7 +173,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
listView.setAdapter(resourceCursorAdapter);
|
listView.setAdapter(resourceCursorAdapter);
|
||||||
AbstractListActivity.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
ActivityUtils.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
||||||
|
|
||||||
LoaderManager.getInstance(this).initLoader(0, null, new LoaderCallbacks<Cursor>() {
|
LoaderManager.getInstance(this).initLoader(0, null, new LoaderCallbacks<Cursor>() {
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -234,7 +232,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
|
|||||||
insertMarkerMenuItem = menu.findItem(R.id.marker_list_insert_marker);
|
insertMarkerMenuItem = menu.findItem(R.id.marker_list_insert_marker);
|
||||||
|
|
||||||
searchMenuItem = menu.findItem(R.id.marker_list_search);
|
searchMenuItem = menu.findItem(R.id.marker_list_search);
|
||||||
AbstractListActivity.configureSearchWidget(this, searchMenuItem, null);
|
ActivityUtils.configureSearchWidget(this, searchMenuItem, null);
|
||||||
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
@@ -256,24 +254,6 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
getMenuInflater().inflate(R.menu.list_context_menu, menu);
|
|
||||||
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
|
||||||
contextualActionModeCallback.onPrepare(menu, new int[]{info.position}, new long[]{info.id}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
|
|
||||||
if (handleContextItem(item.getItemId(), new long[]{info.id})) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a context item selection.
|
* Handles a context item selection.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,14 +22,11 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
@@ -55,10 +52,12 @@ import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment;
|
|||||||
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
|
import de.dennisguse.opentracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
|
||||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||||
import de.dennisguse.opentracks.stats.TripStatistics;
|
import de.dennisguse.opentracks.stats.TripStatistics;
|
||||||
|
import de.dennisguse.opentracks.util.ActivityUtils;
|
||||||
import de.dennisguse.opentracks.util.IntentUtils;
|
import de.dennisguse.opentracks.util.IntentUtils;
|
||||||
import de.dennisguse.opentracks.util.ListItemUtils;
|
import de.dennisguse.opentracks.util.ListItemUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
import de.dennisguse.opentracks.util.ToolbarUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,26 +110,31 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
|||||||
public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) {
|
public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) {
|
||||||
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
||||||
boolean isSingleSelection = positions.length == 1;
|
boolean isSingleSelection = positions.length == 1;
|
||||||
|
|
||||||
boolean isSingleSelectionTrack;
|
boolean isSingleSelectionTrack;
|
||||||
if (isSingleSelection) {
|
if (isSingleSelection) {
|
||||||
Map<String, Object> item = arrayAdapter.getItem(positions[0]);
|
Map<String, Object> item = arrayAdapter.getItem(positions[0]);
|
||||||
Long trackId = (Long) item.get(TRACK_ID_FIELD);
|
|
||||||
Track track = contentProviderUtils.getTrack(trackId);
|
|
||||||
|
|
||||||
isSingleSelectionTrack = item.get(MARKER_ID_FIELD) == null;
|
isSingleSelectionTrack = item.get(MARKER_ID_FIELD) == null;
|
||||||
} else {
|
} else {
|
||||||
isSingleSelectionTrack = false;
|
isSingleSelectionTrack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not recording, one item, item is a track
|
// Not recording, one item, item is a track
|
||||||
menu.findItem(R.id.list_context_menu_share).setVisible(!isRecording && isSingleSelection && isSingleSelectionTrack);
|
MenuItem shareMenuItem = menu.findItem(R.id.list_context_menu_share);
|
||||||
//TODO Setup shareIntent.
|
if (isSingleSelectionTrack) {
|
||||||
|
shareMenuItem.setVisible(!isRecording);
|
||||||
|
Map<String, Object> item = arrayAdapter.getItem(positions[0]);
|
||||||
|
Long trackId = (Long) item.get(TRACK_ID_FIELD);
|
||||||
|
|
||||||
|
ToolbarUtils.setupShareActionProvider(SearchListActivity.this, shareMenuItem, new long[]{trackId});
|
||||||
|
}
|
||||||
|
|
||||||
// One item, item is a marker
|
// One item, item is a marker
|
||||||
menu.findItem(R.id.list_context_menu_show_on_map).setVisible(isSingleSelection && !isSingleSelectionTrack);
|
menu.findItem(R.id.list_context_menu_show_on_map).setVisible(isSingleSelection && !isSingleSelectionTrack);
|
||||||
// One item, can be a track or a marker
|
// One item, can be a track or a marker
|
||||||
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
|
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
|
||||||
// One item. If track, no restriction.
|
// One item. If track, no restriction.
|
||||||
menu.findItem(R.id.list_context_menu_delete).setVisible(isSingleSelection && (isSingleSelectionTrack));
|
menu.findItem(R.id.list_context_menu_delete).setVisible(isSingleSelection && isSingleSelectionTrack);
|
||||||
// Disable select all, no action is available for multiple selection
|
// Disable select all, no action is available for multiple selection
|
||||||
menu.findItem(R.id.list_context_menu_select_all).setVisible(false);
|
menu.findItem(R.id.list_context_menu_select_all).setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -222,7 +226,7 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AbstractListActivity.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
ActivityUtils.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
||||||
handleIntent(getIntent());
|
handleIntent(getIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,24 +263,6 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
|||||||
handleIntent(intent);
|
handleIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
getMenuInflater().inflate(R.menu.list_context_menu, menu);
|
|
||||||
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
|
||||||
contextualActionModeCallback.onPrepare(menu, new int[]{info.position}, new long[]{info.id}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
|
|
||||||
if (handleContextItem(item.getItemId(), new int[]{info.position})) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||||
@@ -301,10 +287,6 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
|
|||||||
Long markerId = (Long) item.get(MARKER_ID_FIELD);
|
Long markerId = (Long) item.get(MARKER_ID_FIELD);
|
||||||
Intent intent;
|
Intent intent;
|
||||||
switch (itemId) {
|
switch (itemId) {
|
||||||
case R.id.list_context_menu_share:
|
|
||||||
//TODO
|
|
||||||
Log.e(TAG, "Not implemented");
|
|
||||||
return true;
|
|
||||||
case R.id.list_context_menu_show_on_map:
|
case R.id.list_context_menu_show_on_map:
|
||||||
IntentUtils.showCoordinateOnMap(this, (double) item.get(MARKER_LATITUDE_FIELD), (double) item.get(MARKER_LONGITUDE_FIELD), item.get(NAME_FIELD) + "");
|
IntentUtils.showCoordinateOnMap(this, (double) item.get(MARKER_LATITUDE_FIELD), (double) item.get(MARKER_LONGITUDE_FIELD), item.get(NAME_FIELD) + "");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -130,11 +130,11 @@ public class TrackController {
|
|||||||
handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
|
handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hide() {
|
public void hide() {
|
||||||
containerView.setVisibility(View.GONE);
|
containerView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show() {
|
public void show() {
|
||||||
containerView.setVisibility(View.VISIBLE);
|
containerView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ShareActionProvider;
|
|
||||||
import android.widget.TabHost;
|
import android.widget.TabHost;
|
||||||
import android.widget.TabHost.TabSpec;
|
import android.widget.TabHost.TabSpec;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -56,6 +55,7 @@ import de.dennisguse.opentracks.settings.SettingsActivity;
|
|||||||
import de.dennisguse.opentracks.util.FileUtils;
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
import de.dennisguse.opentracks.util.IntentUtils;
|
import de.dennisguse.opentracks.util.IntentUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
|
import de.dennisguse.opentracks.util.ToolbarUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackUtils;
|
import de.dennisguse.opentracks.util.TrackUtils;
|
||||||
|
|
||||||
@@ -318,8 +318,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
|||||||
insertPhotoMenuItem.setVisible(new Intent(MediaStore.ACTION_IMAGE_CAPTURE).resolveActivity(getPackageManager()) != null);
|
insertPhotoMenuItem.setVisible(new Intent(MediaStore.ACTION_IMAGE_CAPTURE).resolveActivity(getPackageManager()) != null);
|
||||||
|
|
||||||
shareMenuItem = menu.findItem(R.id.track_detail_share);
|
shareMenuItem = menu.findItem(R.id.track_detail_share);
|
||||||
ShareActionProvider shareActionProvider = (ShareActionProvider) shareMenuItem.getActionProvider();
|
ToolbarUtils.setupShareActionProviderCompat(this, shareMenuItem, new long[]{trackId});
|
||||||
shareActionProvider.setShareIntent(IntentUtils.newShareFileIntent(this, new long[]{trackId}));
|
|
||||||
|
|
||||||
voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency);
|
voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency);
|
||||||
splitFrequencyMenuItem = menu.findItem(R.id.track_detail_split_frequency);
|
splitFrequencyMenuItem = menu.findItem(R.id.track_detail_split_frequency);
|
||||||
@@ -392,6 +391,7 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import android.location.LocationManager;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -37,14 +35,12 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.SearchView;
|
|
||||||
import android.widget.ShareActionProvider;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.cursoradapter.widget.ResourceCursorAdapter;
|
import androidx.cursoradapter.widget.ResourceCursorAdapter;
|
||||||
import androidx.loader.app.LoaderManager;
|
import androidx.loader.app.LoaderManager;
|
||||||
@@ -60,10 +56,12 @@ import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
|||||||
import de.dennisguse.opentracks.services.ITrackRecordingService;
|
import de.dennisguse.opentracks.services.ITrackRecordingService;
|
||||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||||
|
import de.dennisguse.opentracks.util.ActivityUtils;
|
||||||
import de.dennisguse.opentracks.util.IntentUtils;
|
import de.dennisguse.opentracks.util.IntentUtils;
|
||||||
import de.dennisguse.opentracks.util.ListItemUtils;
|
import de.dennisguse.opentracks.util.ListItemUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
import de.dennisguse.opentracks.util.ToolbarUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackUtils;
|
import de.dennisguse.opentracks.util.TrackUtils;
|
||||||
|
|
||||||
@@ -118,8 +116,7 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
boolean isSingleSelection = trackIds.length == 1;
|
boolean isSingleSelection = trackIds.length == 1;
|
||||||
|
|
||||||
MenuItem shareMenuItem = menu.findItem(R.id.list_context_menu_share);
|
MenuItem shareMenuItem = menu.findItem(R.id.list_context_menu_share);
|
||||||
ShareActionProvider shareActionProvider = (ShareActionProvider) shareMenuItem.getActionProvider();
|
ToolbarUtils.setupShareActionProvider(TrackListActivity.this, shareMenuItem, trackIds);
|
||||||
shareActionProvider.setShareIntent(trackIds.length == 0 ? null : IntentUtils.newShareFileIntent(TrackListActivity.this, trackIds));
|
|
||||||
|
|
||||||
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
|
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
|
||||||
menu.findItem(R.id.list_context_menu_select_all).setVisible(showSelectAll);
|
menu.findItem(R.id.list_context_menu_select_all).setVisible(showSelectAll);
|
||||||
@@ -175,7 +172,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
// Menu items
|
// Menu items
|
||||||
private MenuItem searchMenuItem;
|
private MenuItem searchMenuItem;
|
||||||
private MenuItem startGpsMenuItem;
|
private MenuItem startGpsMenuItem;
|
||||||
private MenuItem aggregatedStatisticsMenuItem;
|
|
||||||
private MenuItem deleteAllMenuItem;
|
private MenuItem deleteAllMenuItem;
|
||||||
|
|
||||||
private final OnClickListener stopListener = new OnClickListener() {
|
private final OnClickListener stopListener = new OnClickListener() {
|
||||||
@@ -317,7 +313,8 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
listView.setAdapter(resourceCursorAdapter);
|
listView.setAdapter(resourceCursorAdapter);
|
||||||
AbstractListActivity.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
|
||||||
|
ActivityUtils.configureListViewContextualMenu(listView, contextualActionModeCallback);
|
||||||
|
|
||||||
LoaderManager.getInstance(this).initLoader(0, null, loaderCallbacks);
|
LoaderManager.getInstance(this).initLoader(0, null, loaderCallbacks);
|
||||||
showStartupDialogs();
|
showStartupDialogs();
|
||||||
@@ -379,10 +376,9 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
getMenuInflater().inflate(R.menu.track_list, menu);
|
getMenuInflater().inflate(R.menu.track_list, menu);
|
||||||
|
|
||||||
searchMenuItem = menu.findItem(R.id.track_list_search);
|
searchMenuItem = menu.findItem(R.id.track_list_search);
|
||||||
AbstractListActivity.configureSearchWidget(this, searchMenuItem, trackController);
|
ActivityUtils.configureSearchWidget(this, searchMenuItem, trackController);
|
||||||
|
|
||||||
startGpsMenuItem = menu.findItem(R.id.track_list_start_gps);
|
startGpsMenuItem = menu.findItem(R.id.track_list_start_gps);
|
||||||
aggregatedStatisticsMenuItem = menu.findItem(R.id.track_list_aggregated_statistics);
|
|
||||||
deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all);
|
deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all);
|
||||||
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
@@ -394,10 +390,9 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
boolean isRecording = PreferencesUtils.isRecording(recordingTrackId);
|
||||||
updateMenuItems(isGpsStarted, isRecording);
|
updateMenuItems(isGpsStarted, isRecording);
|
||||||
|
|
||||||
View searchView = searchMenuItem.getActionView();
|
SearchView searchView = (SearchView) searchMenuItem.getActionView();
|
||||||
if (searchView instanceof SearchView) {
|
searchView.setQuery("", false);
|
||||||
((SearchView) searchView).setQuery("", false);
|
|
||||||
}
|
|
||||||
return super.onPrepareOptionsMenu(menu);
|
return super.onPrepareOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,10 +433,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
intent = IntentUtils.newIntent(this, MarkerListActivity.class);
|
intent = IntentUtils.newIntent(this, MarkerListActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
case R.id.track_list_aggregated_statistics:
|
|
||||||
intent = IntentUtils.newIntent(this, AggregatedStatsActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case R.id.track_list_delete_all:
|
case R.id.track_list_delete_all:
|
||||||
deleteTracks(new long[]{-1L});
|
deleteTracks(new long[]{-1L});
|
||||||
return true;
|
return true;
|
||||||
@@ -453,24 +444,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
getMenuInflater().inflate(R.menu.list_context_menu, menu);
|
|
||||||
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
|
||||||
contextualActionModeCallback.onPrepare(menu, new int[]{info.position}, new long[]{info.id}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
|
||||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
|
|
||||||
if (handleContextItem(item.getItemId(), new long[]{info.id})) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_SEARCH && searchMenuItem != null) {
|
if (keyCode == KeyEvent.KEYCODE_SEARCH && searchMenuItem != null) {
|
||||||
@@ -530,9 +503,6 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
|
|||||||
startGpsMenuItem.setIcon(isGpsStarted ? R.drawable.ic_gps_fixed_24dp : R.drawable.ic_gps_off_24dp);
|
startGpsMenuItem.setIcon(isGpsStarted ? R.drawable.ic_gps_fixed_24dp : R.drawable.ic_gps_off_24dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aggregatedStatisticsMenuItem != null) {
|
|
||||||
aggregatedStatisticsMenuItem.setVisible(hasTrack);
|
|
||||||
}
|
|
||||||
if (deleteAllMenuItem != null) {
|
if (deleteAllMenuItem != null) {
|
||||||
deleteAllMenuItem.setVisible(hasTrack && !isRecording);
|
deleteAllMenuItem.setVisible(hasTrack && !isRecording);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package de.dennisguse.opentracks.content.sensor;
|
|||||||
|
|
||||||
public final class SensorDataSet {
|
public final class SensorDataSet {
|
||||||
|
|
||||||
public static final float DATA_UNAVAILABLE = Integer.MAX_VALUE;
|
public static final float DATA_UNAVAILABLE = Float.NaN;
|
||||||
|
|
||||||
//TODO It might be necessary to consider: sensor if sensor was connected as well.
|
//TODO It might be necessary to consider: sensor if sensor was connected as well.
|
||||||
public String sensorName;
|
public String sensorName;
|
||||||
@@ -40,7 +40,7 @@ public final class SensorDataSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasHeartRate() {
|
public boolean hasHeartRate() {
|
||||||
return heartRate != DATA_UNAVAILABLE;
|
return !Float.isNaN(heartRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getHeartRate() {
|
public float getHeartRate() {
|
||||||
@@ -48,7 +48,7 @@ public final class SensorDataSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCadence() {
|
public boolean hasCadence() {
|
||||||
return cadence != DATA_UNAVAILABLE;
|
return !Float.isNaN(cadence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCadence() {
|
public float getCadence() {
|
||||||
@@ -56,7 +56,7 @@ public final class SensorDataSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPower() {
|
public boolean hasPower() {
|
||||||
return power != DATA_UNAVAILABLE;
|
return !Float.isNaN(power);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getPower() {
|
public float getPower() {
|
||||||
@@ -77,7 +77,7 @@ public final class SensorDataSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasBatteryLevel() {
|
public boolean hasBatteryLevel() {
|
||||||
return batteryLevel != DATA_UNAVAILABLE;
|
return !Float.isNaN(batteryLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getBatteryLevel() {
|
public float getBatteryLevel() {
|
||||||
|
|||||||
@@ -49,9 +49,10 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
private static final String END_STYLE = "end";
|
private static final String END_STYLE = "end";
|
||||||
private static final String TRACK_STYLE = "track";
|
private static final String TRACK_STYLE = "track";
|
||||||
private static final String SCHEMA_ID = "schema";
|
private static final String SCHEMA_ID = "schema";
|
||||||
private static final String CADENCE = "cadence";
|
|
||||||
private static final String HEART_RATE = "heart_rate";
|
private static final String SENSOR_TYPE_CADENCE = "cadence";
|
||||||
private static final String POWER = "power";
|
private static final String SENSOR_TYPE_HEART_RATE = "heart_rate";
|
||||||
|
private static final String SENSOR_TYPE_POWER = "power";
|
||||||
|
|
||||||
private static final String WAYPOINT_ICON = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
|
private static final String WAYPOINT_ICON = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
|
||||||
private static final String STATISTICS_ICON = "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";
|
private static final String STATISTICS_ICON = "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";
|
||||||
@@ -71,9 +72,6 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
private List<Float> powerList = new ArrayList<>();
|
private List<Float> powerList = new ArrayList<>();
|
||||||
private List<Float> cadenceList = new ArrayList<>();
|
private List<Float> cadenceList = new ArrayList<>();
|
||||||
private List<Float> heartRateList = new ArrayList<>();
|
private List<Float> heartRateList = new ArrayList<>();
|
||||||
private boolean hasPower;
|
|
||||||
private boolean hasCadence;
|
|
||||||
private boolean hasHeartRate;
|
|
||||||
|
|
||||||
private Location startLocation;
|
private Location startLocation;
|
||||||
|
|
||||||
@@ -132,9 +130,9 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
printWriter.println("<Schema id=\"" + SCHEMA_ID + "\">");
|
printWriter.println("<Schema id=\"" + SCHEMA_ID + "\">");
|
||||||
|
|
||||||
if (exportSensorData) {
|
if (exportSensorData) {
|
||||||
writeSensorStyle(POWER, context.getString(R.string.description_sensor_power));
|
writeSensorStyle(SENSOR_TYPE_POWER, context.getString(R.string.description_sensor_power));
|
||||||
writeSensorStyle(CADENCE, context.getString(R.string.description_sensor_cadence));
|
writeSensorStyle(SENSOR_TYPE_CADENCE, context.getString(R.string.description_sensor_cadence));
|
||||||
writeSensorStyle(HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
|
writeSensorStyle(SENSOR_TYPE_HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
|
||||||
}
|
}
|
||||||
printWriter.println("</Schema>");
|
printWriter.println("</Schema>");
|
||||||
}
|
}
|
||||||
@@ -235,9 +233,6 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
public void writeOpenSegment() {
|
public void writeOpenSegment() {
|
||||||
if (printWriter != null) {
|
if (printWriter != null) {
|
||||||
printWriter.println("<gx:Track>");
|
printWriter.println("<gx:Track>");
|
||||||
hasPower = false;
|
|
||||||
hasCadence = false;
|
|
||||||
hasHeartRate = false;
|
|
||||||
powerList.clear();
|
powerList.clear();
|
||||||
cadenceList.clear();
|
cadenceList.clear();
|
||||||
heartRateList.clear();
|
heartRateList.clear();
|
||||||
@@ -250,14 +245,14 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
printWriter.println("<ExtendedData>");
|
printWriter.println("<ExtendedData>");
|
||||||
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
|
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
|
||||||
if (exportSensorData) {
|
if (exportSensorData) {
|
||||||
if (hasPower) {
|
if (powerList.size() > 0) {
|
||||||
writeSensorData(powerList, POWER);
|
writeSensorData(powerList, SENSOR_TYPE_POWER);
|
||||||
}
|
}
|
||||||
if (hasCadence) {
|
if (cadenceList.size() > 0) {
|
||||||
writeSensorData(cadenceList, CADENCE);
|
writeSensorData(cadenceList, SENSOR_TYPE_CADENCE);
|
||||||
}
|
}
|
||||||
if (hasHeartRate) {
|
if (heartRateList.size() > 0) {
|
||||||
writeSensorData(heartRateList, HEART_RATE);
|
writeSensorData(heartRateList, SENSOR_TYPE_HEART_RATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printWriter.println("</SchemaData>");
|
printWriter.println("</SchemaData>");
|
||||||
@@ -466,11 +461,11 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
* Writes a sensor style.
|
* Writes a sensor style.
|
||||||
*
|
*
|
||||||
* @param name the name of the sesnor
|
* @param name the name of the sesnor
|
||||||
* @param displayName the sensor display name
|
* @param sensorType the sensor display name
|
||||||
*/
|
*/
|
||||||
private void writeSensorStyle(String name, String displayName) {
|
private void writeSensorStyle(String name, String sensorType) {
|
||||||
printWriter.println("<gx:SimpleArrayField name=\"" + name + "\" type=\"int\">");
|
printWriter.println("<gx:SimpleArrayField name=\"" + name + "\" type=\"float\">");
|
||||||
printWriter.println("<displayName>" + StringUtils.formatCData(displayName) + "</displayName>");
|
printWriter.println("<displayName>" + StringUtils.formatCData(sensorType) + "</displayName>");
|
||||||
printWriter.println("</gx:SimpleArrayField>");
|
printWriter.println("</gx:SimpleArrayField>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -384,8 +384,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
* @param message the message
|
* @param message the message
|
||||||
*/
|
*/
|
||||||
protected String createErrorMessage(String message) {
|
protected String createErrorMessage(String message) {
|
||||||
return String.format(Locale.US, "Parsing error at line: %d column: %d. %s",
|
return String.format(Locale.US, "Parsing error at line: %d column: %d. %s", locator.getLineNumber(), locator.getColumnNumber(), message);
|
||||||
locator.getLineNumber(), locator.getColumnNumber(), message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package de.dennisguse.opentracks.io.file.importer;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
@@ -39,6 +40,8 @@ import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
|||||||
*/
|
*/
|
||||||
public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
||||||
|
|
||||||
|
private static final String TAG = KmlFileTrackImporter.class.getSimpleName();
|
||||||
|
|
||||||
private static final String CADENCE = "cadence";
|
private static final String CADENCE = "cadence";
|
||||||
private static final String HEART_RATE = "heart_rate";
|
private static final String HEART_RATE = "heart_rate";
|
||||||
private static final String POWER = "power";
|
private static final String POWER = "power";
|
||||||
@@ -65,11 +68,11 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
|||||||
private static final String ATTRIBUTE_NAME = "name";
|
private static final String ATTRIBUTE_NAME = "name";
|
||||||
|
|
||||||
private boolean trackStarted = false;
|
private boolean trackStarted = false;
|
||||||
private String sensorName;
|
private String sensorType;
|
||||||
private ArrayList<Location> locationList;
|
private ArrayList<Location> locationList;
|
||||||
private ArrayList<Integer> cadenceList;
|
private ArrayList<Float> cadenceList;
|
||||||
private ArrayList<Integer> heartRateList;
|
private ArrayList<Float> heartRateList;
|
||||||
private ArrayList<Integer> powerList;
|
private ArrayList<Float> powerList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -229,20 +232,30 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
|||||||
*/
|
*/
|
||||||
private void onTrackSegmentEnd() {
|
private void onTrackSegmentEnd() {
|
||||||
// Close a track segment by inserting the segment locations
|
// Close a track segment by inserting the segment locations
|
||||||
boolean hasHeartRate = heartRateList.size() == locationList.size();
|
|
||||||
boolean hasCadence = cadenceList.size() == locationList.size();
|
|
||||||
boolean hasPower = powerList.size() == locationList.size();
|
|
||||||
|
|
||||||
for (int i = 0; i < locationList.size(); i++) {
|
for (int i = 0; i < locationList.size(); i++) {
|
||||||
Location location = locationList.get(i);
|
Location location = locationList.get(i);
|
||||||
|
|
||||||
if (!hasPower && !hasCadence && !hasHeartRate) {
|
boolean hasSensorData = false;
|
||||||
|
float heartrate = SensorDataSet.DATA_UNAVAILABLE;
|
||||||
|
float cadence = SensorDataSet.DATA_UNAVAILABLE;
|
||||||
|
float power = SensorDataSet.DATA_UNAVAILABLE;
|
||||||
|
|
||||||
|
if (i < heartRateList.size()) {
|
||||||
|
heartrate = heartRateList.get(i);
|
||||||
|
hasSensorData = true;
|
||||||
|
}
|
||||||
|
if (i < cadenceList.size()) {
|
||||||
|
cadence = cadenceList.get(i);
|
||||||
|
hasSensorData = true;
|
||||||
|
}
|
||||||
|
if (i < powerList.size()) {
|
||||||
|
power = powerList.get(i);
|
||||||
|
hasSensorData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasSensorData) {
|
||||||
insertTrackPoint(location);
|
insertTrackPoint(location);
|
||||||
} else {
|
} else {
|
||||||
float heartrate = hasHeartRate ? heartRateList.get(i) : SensorDataSet.DATA_UNAVAILABLE;
|
|
||||||
float cadence = hasHeartRate ? cadenceList.get(i) : SensorDataSet.DATA_UNAVAILABLE;
|
|
||||||
float power = hasHeartRate ? powerList.get(i) : SensorDataSet.DATA_UNAVAILABLE;
|
|
||||||
|
|
||||||
SensorDataSetLocation sensorDataSetLocation = new SensorDataSetLocation(location, new SensorDataSet(heartrate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, location.getTime()));
|
SensorDataSetLocation sensorDataSetLocation = new SensorDataSetLocation(location, new SensorDataSet(heartrate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, location.getTime()));
|
||||||
insertTrackPoint(sensorDataSetLocation);
|
insertTrackPoint(sensorDataSetLocation);
|
||||||
}
|
}
|
||||||
@@ -277,7 +290,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
|||||||
* On sensor data start. gx:SimpleArrayData start tag.
|
* On sensor data start. gx:SimpleArrayData start tag.
|
||||||
*/
|
*/
|
||||||
private void onSensorDataStart(Attributes attributes) {
|
private void onSensorDataStart(Attributes attributes) {
|
||||||
sensorName = attributes.getValue(ATTRIBUTE_NAME);
|
sensorType = attributes.getValue(ATTRIBUTE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,18 +304,24 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
|||||||
if (content.equals("")) {
|
if (content.equals("")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int value;
|
float value;
|
||||||
try {
|
try {
|
||||||
value = Integer.parseInt(content);
|
value = Float.valueOf(content);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new SAXException(createErrorMessage("Unable to parse gx:value:" + content), e);
|
throw new SAXException(createErrorMessage("Unable to parse gx:value:" + content), e);
|
||||||
}
|
}
|
||||||
if (POWER.equals(sensorName)) {
|
switch (sensorType) {
|
||||||
powerList.add(value);
|
case POWER:
|
||||||
} else if (HEART_RATE.equals(sensorName)) {
|
powerList.add(value);
|
||||||
heartRateList.add(value);
|
break;
|
||||||
} else if (CADENCE.equals(sensorName)) {
|
case HEART_RATE:
|
||||||
cadenceList.add(value);
|
heartRateList.add(value);
|
||||||
|
break;
|
||||||
|
case CADENCE:
|
||||||
|
cadenceList.add(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(TAG, "Data from sensor " + sensorType + " is not (yet) supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -853,7 +853,7 @@ public class TrackRecordingService extends Service {
|
|||||||
*/
|
*/
|
||||||
private void insertLocation(Track track, Location location, Location lastValidTrackPoint) {
|
private void insertLocation(Track track, Location location, Location lastValidTrackPoint) {
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
Log.w(TAG, "Ignore insertLocation. loation is null.");
|
Log.w(TAG, "Ignore insertLocation. location is null.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do not insert if inserted already
|
// Do not insert if inserted already
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ import android.widget.ArrayAdapter;
|
|||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.preference.DialogPreference;
|
import androidx.preference.DialogPreference;
|
||||||
import androidx.preference.PreferenceDialogFragment;
|
import androidx.preference.PreferenceDialogFragmentCompat;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||||
@@ -67,7 +66,7 @@ public class ActivityTypePreference extends DialogPreference {
|
|||||||
return R.layout.preference_activity_type;
|
return R.layout.preference_activity_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ActivityPreferenceDialog extends PreferenceDialogFragment {
|
public static class ActivityPreferenceDialog extends PreferenceDialogFragmentCompat {
|
||||||
|
|
||||||
private AutoCompleteTextView textView;
|
private AutoCompleteTextView textView;
|
||||||
private Spinner spinner;
|
private Spinner spinner;
|
||||||
@@ -75,7 +74,7 @@ public class ActivityTypePreference extends DialogPreference {
|
|||||||
static ActivityPreferenceDialog newInstance(String preferenceKey) {
|
static ActivityPreferenceDialog newInstance(String preferenceKey) {
|
||||||
ActivityTypePreference.ActivityPreferenceDialog dialog = new ActivityTypePreference.ActivityPreferenceDialog();
|
ActivityTypePreference.ActivityPreferenceDialog dialog = new ActivityTypePreference.ActivityPreferenceDialog();
|
||||||
final Bundle bundle = new Bundle(1);
|
final Bundle bundle = new Bundle(1);
|
||||||
bundle.putString(PreferenceDialogFragment.ARG_KEY, preferenceKey);
|
bundle.putString(PreferenceDialogFragmentCompat.ARG_KEY, preferenceKey);
|
||||||
dialog.setArguments(bundle);
|
dialog.setArguments(bundle);
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
@@ -134,10 +133,7 @@ public class ActivityTypePreference extends DialogPreference {
|
|||||||
|
|
||||||
private void showIconSelectDialog() {
|
private void showIconSelectDialog() {
|
||||||
String category = PreferencesUtils.getString(getActivity(), R.string.default_activity_key, PreferencesUtils.DEFAULT_ACTIVITY_DEFAULT);
|
String category = PreferencesUtils.getString(getActivity(), R.string.default_activity_key, PreferencesUtils.DEFAULT_ACTIVITY_DEFAULT);
|
||||||
|
ChooseActivityTypeDialogFragment.showDialog(getActivity().getSupportFragmentManager(), category);
|
||||||
// TODO Remove casting when upgrading to new Androidx compat.
|
|
||||||
FragmentActivity fragmentActivity = (androidx.fragment.app.FragmentActivity) getActivity();
|
|
||||||
ChooseActivityTypeDialogFragment.showDialog(fragmentActivity.getSupportFragmentManager(), category);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import android.util.AttributeSet;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.preference.DialogPreference;
|
import androidx.preference.DialogPreference;
|
||||||
import androidx.preference.PreferenceDialogFragment;
|
import androidx.preference.PreferenceDialogFragmentCompat;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
@@ -17,12 +17,12 @@ public class ResetDialogPreference extends DialogPreference {
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResetPreferenceDialog extends PreferenceDialogFragment {
|
public static class ResetPreferenceDialog extends PreferenceDialogFragmentCompat {
|
||||||
|
|
||||||
static PreferenceDialogFragment newInstance(String preferenceKey) {
|
static PreferenceDialogFragmentCompat newInstance(String preferenceKey) {
|
||||||
ResetPreferenceDialog dialog = new ResetPreferenceDialog();
|
ResetPreferenceDialog dialog = new ResetPreferenceDialog();
|
||||||
final Bundle bundle = new Bundle(1);
|
final Bundle bundle = new Bundle(1);
|
||||||
bundle.putString(PreferenceDialogFragment.ARG_KEY, preferenceKey);
|
bundle.putString(PreferenceDialogFragmentCompat.ARG_KEY, preferenceKey);
|
||||||
dialog.setArguments(bundle);
|
dialog.setArguments(bundle);
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
package de.dennisguse.opentracks.settings;
|
package de.dennisguse.opentracks.settings;
|
||||||
|
|
||||||
import android.app.DialogFragment;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceFragment;
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
public class SettingsActivity extends FragmentActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
|
public class SettingsActivity extends AppCompatActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
|
||||||
|
|
||||||
private PrefsFragment prefsFragment = new PrefsFragment();
|
private PrefsFragment prefsFragment = new PrefsFragment();
|
||||||
|
|
||||||
@@ -22,7 +23,13 @@ public class SettingsActivity extends FragmentActivity implements ChooseActivity
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
getFragmentManager().beginTransaction().replace(android.R.id.content, prefsFragment).commit();
|
setContentView(R.layout.settings);
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
toolbar.setTitle(R.string.menu_settings);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.settings_fragment, prefsFragment).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -30,7 +37,7 @@ public class SettingsActivity extends FragmentActivity implements ChooseActivity
|
|||||||
prefsFragment.setDefaultActivity(iconValue);
|
prefsFragment.setDefaultActivity(iconValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PrefsFragment extends PreferenceFragment {
|
public static class PrefsFragment extends PreferenceFragmentCompat {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that sharedPreferenceChangeListener cannot be an anonymous inner class.
|
* Note that sharedPreferenceChangeListener cannot be an anonymous inner class.
|
||||||
@@ -62,7 +69,7 @@ public class SettingsActivity extends FragmentActivity implements ChooseActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||||
addPreferencesFromResource(R.xml.settings);
|
setPreferencesFromResource(R.xml.settings, rootKey);
|
||||||
updateUnits();
|
updateUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package de.dennisguse.opentracks.util;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.SearchManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
|
import android.view.ActionMode;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AbsListView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.SearchView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.ContextualActionModeCallback;
|
||||||
|
import de.dennisguse.opentracks.R;
|
||||||
|
import de.dennisguse.opentracks.SearchListActivity;
|
||||||
|
import de.dennisguse.opentracks.TrackController;
|
||||||
|
|
||||||
|
public class ActivityUtils {
|
||||||
|
|
||||||
|
private static final String TAG = ActivityUtils.class.getSimpleName();
|
||||||
|
|
||||||
|
public static void configureListViewContextualMenu(final ListView listView, final ContextualActionModeCallback contextualActionModeCallback) {
|
||||||
|
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
||||||
|
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
|
mode.getMenuInflater().inflate(R.menu.list_context_menu, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||||
|
contextualActionModeCallback.onPrepare(menu, getCheckedPositions(listView), listView.getCheckedItemIds(), true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyActionMode(ActionMode mode) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
||||||
|
mode.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
|
if (contextualActionModeCallback.onClick(item.getItemId(), getCheckedPositions(listView), listView.getCheckedItemIds())) {
|
||||||
|
mode.finish();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the checked positions in a list view.
|
||||||
|
*
|
||||||
|
* @param list the list view
|
||||||
|
*/
|
||||||
|
private int[] getCheckedPositions(ListView list) {
|
||||||
|
SparseBooleanArray positions = list.getCheckedItemPositions();
|
||||||
|
ArrayList<Integer> arrayList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < positions.size(); i++) {
|
||||||
|
int key = positions.keyAt(i);
|
||||||
|
if (positions.valueAt(i)) {
|
||||||
|
arrayList.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] result = new int[arrayList.size()];
|
||||||
|
for (int i = 0; i < arrayList.size(); i++) {
|
||||||
|
result[i] = arrayList.get(i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void configureSearchWidget(Activity activity, final MenuItem menuItem, final TrackController trackController) {
|
||||||
|
final SearchView searchView = (SearchView) menuItem.getActionView();
|
||||||
|
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
|
||||||
|
if (searchManager != null) {
|
||||||
|
//NOTE: for some reason activity.getComponentName() did not trigger the SearchListActivity
|
||||||
|
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(activity, SearchListActivity.class)));
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Could not retrieve SearchManager.");
|
||||||
|
}
|
||||||
|
searchView.setQueryRefinementEnabled(true);
|
||||||
|
searchView.setSubmitButtonEnabled(true);
|
||||||
|
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFocusChange(View v, boolean 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
|
||||||
|
public boolean onQueryTextSubmit(String query) {
|
||||||
|
menuItem.collapseActionView();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextChange(String newText) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onSuggestionSelect(int position) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSuggestionClick(int position) {
|
||||||
|
menuItem.collapseActionView();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package de.dennisguse.opentracks.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.ShareActionProvider;
|
||||||
|
import androidx.core.internal.view.SupportMenuItem;
|
||||||
|
import androidx.core.view.MenuItemCompat;
|
||||||
|
|
||||||
|
public class ToolbarUtils {
|
||||||
|
|
||||||
|
private ToolbarUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Compat is not working as the AbsListView.MultiChoiceModeListener; instantiating it manually using the non-compat is a workaround.
|
||||||
|
@Deprecated
|
||||||
|
public static void setupShareActionProvider(@NonNull Context context, @NonNull MenuItem shareMenuItem, @NonNull long[] trackIds) {
|
||||||
|
android.widget.ShareActionProvider shareActionProvider = new android.widget.ShareActionProvider(context);
|
||||||
|
shareActionProvider.setShareIntent(trackIds.length == 0 ? null : IntentUtils.newShareFileIntent(context, trackIds));
|
||||||
|
shareMenuItem.setActionProvider(shareActionProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param shareMenuItem Should be a {@link SupportMenuItem}.
|
||||||
|
*/
|
||||||
|
public static void setupShareActionProviderCompat(@NonNull Context context, @NonNull MenuItem shareMenuItem, @NonNull long[] trackIds) {
|
||||||
|
ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareMenuItem);
|
||||||
|
shareActionProvider.setShareIntent(trackIds.length == 0 ? null : IntentUtils.newShareFileIntent(context, trackIds));
|
||||||
|
MenuItemCompat.setActionProvider(shareMenuItem, shareActionProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 199 B |
Binary file not shown.
|
Before Width: | Height: | Size: 154 B |
Binary file not shown.
|
Before Width: | Height: | Size: 260 B |
@@ -16,7 +16,10 @@ limitations under the License.
|
|||||||
<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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:baselineAligned="false">
|
android:baselineAligned="false"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<include layout="@layout/track_controller" />
|
<include layout="@layout/track_controller" />
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager.widget.ViewPager
|
||||||
android:id="@+id/maker_detail_activity_view_pager"
|
android:id="@+id/maker_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ScrollView style="@style/ScrollView.WithBottomButtons">
|
<ScrollView style="@style/ScrollView.WithBottomButtons">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -13,9 +13,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<merge 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_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/marker_list"
|
android:id="@+id/marker_list"
|
||||||
@@ -26,4 +29,4 @@ limitations under the License.
|
|||||||
android:id="@+id/marker_list_empty"
|
android:id="@+id/marker_list_empty"
|
||||||
style="@style/ListEmptyTextView"
|
style="@style/ListEmptyTextView"
|
||||||
android:text="@string/marker_list_empty_message" />
|
android:text="@string/marker_list_empty_message" />
|
||||||
</merge>
|
</LinearLayout>
|
||||||
@@ -13,9 +13,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<merge 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_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/search_list"
|
android:id="@+id/search_list"
|
||||||
@@ -26,4 +29,4 @@ limitations under the License.
|
|||||||
android:id="@+id/search_list_empty"
|
android:id="@+id/search_list_empty"
|
||||||
style="@style/ListEmptyTextView"
|
style="@style/ListEmptyTextView"
|
||||||
android:text="@string/search_list_empty_message" />
|
android:text="@string/search_list_empty_message" />
|
||||||
</merge>
|
</LinearLayout>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settings_fragment"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
android:minHeight="?attr/actionBarSize"
|
||||||
|
app:navigationIcon="@drawable/ic_logo_color_24dp" />
|
||||||
|
</merge>
|
||||||
@@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<TabHost
|
<TabHost
|
||||||
android:id="@+id/tackdetail_tabhost"
|
android:id="@+id/tackdetail_tabhost"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ScrollView style="@style/ScrollView.WithBottomButtons">
|
<ScrollView style="@style/ScrollView.WithBottomButtons">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/track_list"
|
android:id="@+id/track_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -13,30 +13,31 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/list_context_menu_share"
|
android:id="@+id/list_context_menu_share"
|
||||||
android:actionProviderClass="android.widget.ShareActionProvider"
|
android:title="@string/menu_share"
|
||||||
android:showAsAction="ifRoom"
|
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"
|
||||||
android:title="@string/menu_share" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/list_context_menu_show_on_map"
|
android:id="@+id/list_context_menu_show_on_map"
|
||||||
android:icon="@drawable/ic_map_24dp"
|
android:icon="@drawable/ic_map_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_show_on_map"
|
||||||
android:title="@string/menu_show_on_map" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/list_context_menu_edit"
|
android:id="@+id/list_context_menu_edit"
|
||||||
android:icon="@drawable/ic_edit_24dp"
|
android:icon="@drawable/ic_edit_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_edit"
|
||||||
android:title="@string/menu_edit" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/list_context_menu_delete"
|
android:id="@+id/list_context_menu_delete"
|
||||||
android:icon="@drawable/ic_delete_forever_24dp"
|
android:icon="@drawable/ic_delete_forever_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_delete"
|
||||||
android:title="@string/menu_delete" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/list_context_menu_select_all"
|
android:id="@+id/list_context_menu_select_all"
|
||||||
android:icon="@drawable/ic_select_all_24dp"
|
android:icon="@drawable/ic_select_all_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_select_all"
|
||||||
android:title="@string/menu_select_all" />
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -13,20 +13,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/marker_detail_show_on_map"
|
android:id="@+id/marker_detail_show_on_map"
|
||||||
android:icon="@drawable/ic_map_24dp"
|
android:icon="@drawable/ic_map_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_show_on_map"
|
||||||
android:title="@string/menu_show_on_map" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/marker_detail_edit"
|
android:id="@+id/marker_detail_edit"
|
||||||
android:icon="@drawable/ic_edit_24dp"
|
android:icon="@drawable/ic_edit_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_edit"
|
||||||
android:title="@string/menu_edit" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/marker_detail_delete"
|
android:id="@+id/marker_detail_delete"
|
||||||
android:icon="@drawable/ic_delete_forever_24dp"
|
android:icon="@drawable/ic_delete_forever_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_delete"
|
||||||
android:title="@string/menu_delete" />
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -13,15 +13,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/marker_list_insert_marker"
|
android:id="@+id/marker_list_insert_marker"
|
||||||
android:icon="@drawable/ic_marker_show_24dp"
|
android:icon="@drawable/ic_marker_show_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_insert_marker"
|
||||||
android:title="@string/menu_insert_marker" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/marker_list_search"
|
android:id="@+id/marker_list_search"
|
||||||
android:actionViewClass="android.widget.SearchView"
|
android:title="@string/menu_search"
|
||||||
android:showAsAction="ifRoom"
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
android:title="@string/menu_search" />
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -13,29 +13,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_detail_insert_marker"
|
android:id="@+id/track_detail_insert_marker"
|
||||||
android:icon="@drawable/ic_marker_add_24dp"
|
android:icon="@drawable/ic_marker_add_24dp"
|
||||||
android:orderInCategory="1"
|
android:orderInCategory="1"
|
||||||
android:showAsAction="ifRoom"
|
app:showAsAction="ifRoom"
|
||||||
android:title="@string/menu_insert_marker" />
|
android:title="@string/menu_insert_marker" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_detail_insert_photo"
|
android:id="@+id/track_detail_insert_photo"
|
||||||
android:icon="@drawable/ic_camera_24dp"
|
android:icon="@drawable/ic_camera_24dp"
|
||||||
android:orderInCategory="2"
|
android:orderInCategory="2"
|
||||||
android:showAsAction="ifRoom"
|
app:showAsAction="ifRoom"
|
||||||
android:title="@string/menu_insert_photo" />
|
android:title="@string/menu_insert_photo" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_detail_menu_show_on_map"
|
android:id="@+id/track_detail_menu_show_on_map"
|
||||||
android:icon="@drawable/ic_map_24dp"
|
android:icon="@drawable/ic_map_24dp"
|
||||||
android:showAsAction="ifRoom"
|
app:showAsAction="ifRoom"
|
||||||
android:title="@string/menu_show_on_map" />
|
android:title="@string/menu_show_on_map" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_detail_share"
|
android:id="@+id/track_detail_share"
|
||||||
android:actionProviderClass="android.widget.ShareActionProvider"
|
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"
|
||||||
android:orderInCategory="4"
|
android:orderInCategory="4"
|
||||||
android:showAsAction="ifRoom"
|
app:showAsAction="ifRoom"
|
||||||
android:title="@string/menu_share" />
|
android:title="@string/menu_share" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_detail_markers"
|
android:id="@+id/track_detail_markers"
|
||||||
|
|||||||
@@ -13,27 +13,24 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_list_search"
|
android:id="@+id/track_list_search"
|
||||||
android:actionViewClass="android.widget.SearchView"
|
android:title="@string/menu_search"
|
||||||
android:showAsAction="ifRoom"
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
android:title="@string/menu_search" />
|
app:showAsAction="ifRoom" />
|
||||||
<!-- Icon and title is overwritten by TrackListActivity -->
|
<!-- Icon and title is overwritten by TrackListActivity -->
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_list_start_gps"
|
android:id="@+id/track_list_start_gps"
|
||||||
android:icon="@drawable/ic_gps_off_24dp"
|
android:icon="@drawable/ic_gps_off_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_start_gps"
|
||||||
android:title="@string/menu_start_gps" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_list_markers"
|
android:id="@+id/track_list_markers"
|
||||||
android:icon="@drawable/ic_marker_show_24dp"
|
android:icon="@drawable/ic_marker_show_24dp"
|
||||||
android:showAsAction="ifRoom"
|
android:title="@string/menu_markers"
|
||||||
android:title="@string/menu_markers" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
|
||||||
android:id="@+id/track_list_aggregated_statistics"
|
|
||||||
android:icon="@drawable/ic_statistics_24dp"
|
|
||||||
android:title="@string/menu_aggregated_statistics" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/track_list_delete_all"
|
android:id="@+id/track_list_delete_all"
|
||||||
android:icon="@drawable/ic_delete_forever_24dp"
|
android:icon="@drawable/ic_delete_forever_24dp"
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<style name="ActionBarStyleCustom" parent="@android:style/Widget.Holo.ActionBar">
|
|
||||||
<!-- Same image as the source except using a grey line instead of a blue line -->
|
|
||||||
<item name="android:background">@drawable/ab_transparent_dark_holo</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="BottomButton" parent="@android:style/Widget.Holo.Button.Borderless">
|
<style name="BottomButton" parent="@android:style/Widget.Holo.Button.Borderless">
|
||||||
<!-- Same as BottomButton in values/styles.xml except inheriting from Widget.Holo.Button.Borderles. -->
|
<!-- Same as BottomButton in values/styles.xml except inheriting from Widget.Holo.Button.Borderles. -->
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<style name="ThemeCustom" parent="android:Theme.Holo">
|
<style name="ThemeCustom" parent="Theme.AppCompat.NoActionBar">
|
||||||
|
<!-- TODO Cleanup necessary due to change to appcompat -->
|
||||||
<!-- Auto generated -->
|
<!-- Auto generated -->
|
||||||
<item name="android:activatedBackgroundIndicator">@drawable/activated_background_holo_dark
|
<item name="android:activatedBackgroundIndicator">@drawable/activated_background_holo_dark
|
||||||
</item>
|
</item>
|
||||||
@@ -26,11 +27,12 @@ limitations under the License.
|
|||||||
<item name="android:listChoiceIndicatorMultiple">@drawable/btn_check_holo_dark</item>
|
<item name="android:listChoiceIndicatorMultiple">@drawable/btn_check_holo_dark</item>
|
||||||
<item name="android:listChoiceIndicatorSingle">@drawable/btn_radio_holo_dark</item>
|
<item name="android:listChoiceIndicatorSingle">@drawable/btn_radio_holo_dark</item>
|
||||||
<item name="android:progressBarStyleHorizontal">@style/ProgressBarCustom</item>
|
<item name="android:progressBarStyleHorizontal">@style/ProgressBarCustom</item>
|
||||||
<!-- Manually added -->
|
|
||||||
<item name="android:actionBarStyle">@style/ActionBarStyleCustom</item>
|
<!-- <item name="colorPrimary">TODO</item>-->
|
||||||
<item name="android:actionModeBackground">@drawable/custom_action_mode_background</item>
|
<!-- <item name="colorPrimaryDark">TODO</item>-->
|
||||||
<item name="android:alertDialogTheme">@style/CustomAlertDialogTheme</item>
|
|
||||||
<item name="android:colorAccent">@color/holo_orange_dark</item>
|
<item name="android:colorAccent">@color/holo_orange_dark</item>
|
||||||
|
<item name="windowActionModeOverlay">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ThemeCustomTransparent" parent="ThemeCustom">
|
<style name="ThemeCustomTransparent" parent="ThemeCustom">
|
||||||
@@ -42,23 +44,4 @@ limitations under the License.
|
|||||||
<item name="android:windowIsFloating">true</item>
|
<item name="android:windowIsFloating">true</item>
|
||||||
<item name="android:backgroundDimEnabled">false</item>
|
<item name="android:backgroundDimEnabled">false</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="CustomAlertDialogTheme" parent="@android:style/Theme.Holo.Dialog">
|
|
||||||
<!-- From auto generated -->
|
|
||||||
<item name="android:activatedBackgroundIndicator">@drawable/activated_background_holo_dark
|
|
||||||
</item>
|
|
||||||
<item name="android:autoCompleteTextViewStyle">@style/AutoCompleteTextViewCustom</item>
|
|
||||||
<item name="android:dropDownSpinnerStyle">@style/SpinnerCustom</item>
|
|
||||||
<item name="android:editTextBackground">@drawable/edit_text_holo_dark</item>
|
|
||||||
<item name="android:listChoiceBackgroundIndicator">@drawable/list_selector_holo_dark</item>
|
|
||||||
<item name="android:listChoiceIndicatorMultiple">@drawable/btn_check_holo_dark</item>
|
|
||||||
<item name="android:listChoiceIndicatorSingle">@drawable/btn_radio_holo_dark</item>
|
|
||||||
<item name="android:progressBarStyleHorizontal">@style/ProgressBarCustom</item>
|
|
||||||
<!-- From Theme.Holo.Dialog.Alert -->
|
|
||||||
<item name="android:textColor">@color/holo_orange_dark</item>
|
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
|
||||||
<item name="android:windowContentOverlay">@null</item>
|
|
||||||
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
|
|
||||||
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user