forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -256,7 +256,7 @@ limitations under the License.
|
|||||||
<data android:mimeType="vnd.android.cursor.item/vnd.google.track" />
|
<data android:mimeType="vnd.android.cursor.item/vnd.google.track" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.google.android.apps.mytracks.TrackList" >
|
<activity android:name="com.google.android.apps.mytracks.TrackListActivity" >
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.app.default_searchable"
|
android:name="android.app.default_searchable"
|
||||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright 2010 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.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apl/res/com.google.android.apps.mytracks"
|
|
||||||
android:id="@+id/tracklist_root"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/list_bar"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:padding="3dp">
|
|
||||||
<TextView android:id="@+id/message"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="16dp"
|
|
||||||
android:textColor="#fff"
|
|
||||||
android:text="@string/track_list_pick_one"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
</LinearLayout>
|
|
||||||
<ListView android:id="@android:id/list"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
<LinearLayout style="@style/ButtonLayout">
|
|
||||||
<LinearLayout style="@style/ButtonSpacer"/>
|
|
||||||
<Button android:id="@+id/tracklist_btn_import_all"
|
|
||||||
android:layout_gravity="left"
|
|
||||||
android:text="@string/track_list_import_all"
|
|
||||||
style="@style/Button"/>
|
|
||||||
<Button android:id="@+id/tracklist_btn_export_all"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:text="@string/track_list_export_all"
|
|
||||||
style="@style/Button"/>
|
|
||||||
<Button android:id="@+id/tracklist_btn_delete_all"
|
|
||||||
android:layout_gravity="right"
|
|
||||||
android:text="@string/track_list_delete_all"
|
|
||||||
style="@style/Button"/>
|
|
||||||
<LinearLayout style="@style/ButtonSpacer"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2010 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.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/track_list"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_width="fill_parent" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp" >
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
<TextView
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:id="@+id/track_list_item_name"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Large" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_list_item_category"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Small" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_list_item_time"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="@color/green"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Small" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_list_item_distance"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="@color/green"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Small" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_list_item_start"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="@color/green"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Small" />
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_list_item_description"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:singleLine="false"
|
||||||
|
style="@android:style/TextAppearance.DeviceDefault.Small" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item
|
||||||
|
android:icon="@drawable/menu_record_track"
|
||||||
|
android:id="@+id/menu_record_track"
|
||||||
|
android:showAsAction="always"
|
||||||
|
android:title="@string/menu_record_track"/>
|
||||||
|
<item
|
||||||
|
android:icon="@drawable/menu_stop_recording"
|
||||||
|
android:id="@+id/menu_stop_recording"
|
||||||
|
android:showAsAction="always"
|
||||||
|
android:title="@string/menu_stop_recording"/>
|
||||||
|
<item
|
||||||
|
android:actionViewClass="android.widget.SearchView"
|
||||||
|
android:icon="@drawable/menu_search"
|
||||||
|
android:id="@+id/menu_search"
|
||||||
|
android:showAsAction="always|collapseActionView"
|
||||||
|
android:title="@string/menu_search"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_import_all"
|
||||||
|
android:title="@string/menu_import_all"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_export_all"
|
||||||
|
android:title="@string/menu_export_all"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_delete_all"
|
||||||
|
android:title="@string/menu_delete_all"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_aggregated_statistics"
|
||||||
|
android:title="@string/menu_aggregated_statistics"/>
|
||||||
|
<item
|
||||||
|
android:icon="@drawable/menu_settings"
|
||||||
|
android:id="@+id/menu_settings"
|
||||||
|
android:title="@string/menu_settings"/>
|
||||||
|
<item
|
||||||
|
android:icon="@drawable/menu_help"
|
||||||
|
android:id="@+id/menu_help"
|
||||||
|
android:title="@string/menu_help"/>
|
||||||
|
</menu>
|
||||||
@@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="blue">#FF0000FF</color>
|
<color name="blue">#FF0000FF</color>
|
||||||
|
<color name="green">#FF00FF00</color>
|
||||||
<color name="gray">#FFAAAAAA</color>
|
<color name="gray">#FFAAAAAA</color>
|
||||||
<color name="red">#FFFF0000</color>
|
<color name="red">#FFFF0000</color>
|
||||||
<color name="stat_label_background">#FFF0F0F0</color>
|
<color name="stat_label_background">#FFF0F0F0</color>
|
||||||
|
|||||||
@@ -973,10 +973,22 @@ limitations under the License.
|
|||||||
translation_description="In the menu, to change the chart settings.">
|
translation_description="In the menu, to change the chart settings.">
|
||||||
Chart settings
|
Chart settings
|
||||||
</string>
|
</string>
|
||||||
|
<string name="menu_delete_all"
|
||||||
|
translation_description="In the menu, to delete all the tracks.">
|
||||||
|
Delete all
|
||||||
|
</string>
|
||||||
|
<string name="menu_export_all"
|
||||||
|
translation_description="In the menu, to export all the tracks to the SD card.">
|
||||||
|
Export all
|
||||||
|
</string>
|
||||||
<string name="menu_help"
|
<string name="menu_help"
|
||||||
translation_description="In the menu, to go to the help page.">
|
translation_description="In the menu, to go to the help page.">
|
||||||
Help
|
Help
|
||||||
</string>
|
</string>
|
||||||
|
<string name="menu_import_all"
|
||||||
|
translation_description="In the menu, to import all the tracks from the SD card.">
|
||||||
|
Import all
|
||||||
|
</string>
|
||||||
<string name="menu_map_mode"
|
<string name="menu_map_mode"
|
||||||
translation_description="In the menu, to switch the display to the map mode.">
|
translation_description="In the menu, to switch the display to the map mode.">
|
||||||
Map mode
|
Map mode
|
||||||
@@ -2277,12 +2289,6 @@ limitations under the License.
|
|||||||
Screenshot: track_list_context_menu.png">
|
Screenshot: track_list_context_menu.png">
|
||||||
This track
|
This track
|
||||||
</string>
|
</string>
|
||||||
<string name="track_list_delete_all"
|
|
||||||
translation_description="In the 'Tracks' page, the button on the bottom to delete all tracks.
|
|
||||||
|
|
||||||
Screenshot: track_list.png">
|
|
||||||
Delete all
|
|
||||||
</string>
|
|
||||||
<string name="track_list_delete_all_confirm_message"
|
<string name="track_list_delete_all_confirm_message"
|
||||||
translation_description="In the 'Tracks' page, when pressing the 'Delete all' button, the
|
translation_description="In the 'Tracks' page, when pressing the 'Delete all' button, the
|
||||||
confirmation dialog message informing the user that all tracks and markers will be permanently
|
confirmation dialog message informing the user that all tracks and markers will be permanently
|
||||||
@@ -2313,12 +2319,6 @@ limitations under the License.
|
|||||||
Screenshot: track_list_context_menu.png">
|
Screenshot: track_list_context_menu.png">
|
||||||
Edit
|
Edit
|
||||||
</string>
|
</string>
|
||||||
<string name="track_list_export_all"
|
|
||||||
translation_description="In the 'Tracks' page, the button on the bottom to export all tracks.
|
|
||||||
|
|
||||||
Screenshot: track_list.png">
|
|
||||||
Export all
|
|
||||||
</string>
|
|
||||||
<string name="track_list_export_file"
|
<string name="track_list_export_file"
|
||||||
translation_description="In the 'Tracks' page, after pressing the 'Export all' button, the menu
|
translation_description="In the 'Tracks' page, after pressing the 'Export all' button, the menu
|
||||||
option to export all the tracks as a certain file format
|
option to export all the tracks as a certain file format
|
||||||
@@ -2327,19 +2327,6 @@ limitations under the License.
|
|||||||
Screenshot: track_list_export_file.png">
|
Screenshot: track_list_export_file.png">
|
||||||
Export as %1$s
|
Export as %1$s
|
||||||
</string>
|
</string>
|
||||||
<string name="track_list_import_all"
|
|
||||||
translation_description="In the 'Tracks' page, the button on the bottom to import all tracks.
|
|
||||||
|
|
||||||
Screenshot: track_list.png">
|
|
||||||
Import all
|
|
||||||
</string>
|
|
||||||
<string name="track_list_pick_one"
|
|
||||||
translation_description="In the 'Tracks' page, the instruction at the top of the page informing
|
|
||||||
the user he can press and hold a track for more options.
|
|
||||||
|
|
||||||
Screenshot: track_list.png">
|
|
||||||
Pick a track. Press & hold for more options.
|
|
||||||
</string>
|
|
||||||
<string name="track_list_play"
|
<string name="track_list_play"
|
||||||
translation_description="In the context menu for a track, the menu option to play the track.">
|
translation_description="In the context menu for a track, the menu option to play the track.">
|
||||||
Play
|
Play
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class MenuManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.menu_tracks: {
|
case R.id.menu_tracks: {
|
||||||
activity.startActivityForResult(new Intent(activity, TrackList.class),
|
activity.startActivityForResult(new Intent(activity, TrackListActivity.class),
|
||||||
Constants.SHOW_TRACK);
|
Constants.SHOW_TRACK);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,462 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2008 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 com.google.android.apps.mytracks;
|
|
||||||
|
|
||||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
|
||||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
|
||||||
import com.google.android.apps.mytracks.io.file.SaveActivity;
|
|
||||||
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
|
|
||||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
|
||||||
import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActivity;
|
|
||||||
import com.google.android.apps.mytracks.services.ServiceUtils;
|
|
||||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
|
||||||
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
|
||||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
|
||||||
import com.google.android.apps.mytracks.util.PlayTrackUtils;
|
|
||||||
import com.google.android.apps.mytracks.util.StringUtils;
|
|
||||||
import com.google.android.maps.mytracks.R;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.SharedPreferences.Editor;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.SubMenu;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnCreateContextMenuListener;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.SimpleCursorAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list activity displaying all the recorded tracks. There's a context
|
|
||||||
* menu (via long press) displaying various options such as showing, editing,
|
|
||||||
* deleting, sending to Google, or writing to SD card.
|
|
||||||
*
|
|
||||||
* @author Leif Hendrik Wilden
|
|
||||||
*/
|
|
||||||
public class TrackList extends ListActivity
|
|
||||||
implements SharedPreferences.OnSharedPreferenceChangeListener,
|
|
||||||
View.OnClickListener {
|
|
||||||
|
|
||||||
private static final int DIALOG_INSTALL_EARTH_ID = 0;
|
|
||||||
private static final int DIALOG_EXPORT_ALL_ID = 1;
|
|
||||||
private static final int DIALOG_DELETE_ALL_ID = 2;
|
|
||||||
private static final int DIALOG_DELETE_CURRENT_ID = 3;
|
|
||||||
|
|
||||||
private int contextPosition = -1;
|
|
||||||
private long trackId = -1;
|
|
||||||
private ListView listView = null;
|
|
||||||
private boolean metricUnits = true;
|
|
||||||
|
|
||||||
private Cursor tracksCursor = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The id of the currently recording track.
|
|
||||||
*/
|
|
||||||
private long recordingTrackId = -1;
|
|
||||||
|
|
||||||
private final OnCreateContextMenuListener contextMenuListener =
|
|
||||||
new OnCreateContextMenuListener() {
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
|
||||||
menu.setHeaderTitle(R.string.track_list_context_menu_title);
|
|
||||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
|
||||||
contextPosition = info.position;
|
|
||||||
trackId = TrackList.this.listView.getAdapter().getItemId(contextPosition);
|
|
||||||
menu.add(Menu.NONE, Constants.MENU_SHOW, Menu.NONE, R.string.track_list_show_on_map);
|
|
||||||
menu.add(Menu.NONE, Constants.MENU_EDIT, Menu.NONE, R.string.track_list_edit_track);
|
|
||||||
if (!isRecording() || trackId != recordingTrackId) {
|
|
||||||
String saveFileFormat = getString(R.string.track_list_save_file);
|
|
||||||
String shareFileFormat = getString(R.string.track_list_share_file);
|
|
||||||
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
|
||||||
|
|
||||||
menu.add(Menu.NONE, Constants.MENU_PLAY, Menu.NONE, R.string.track_list_play);
|
|
||||||
menu.add(Menu.NONE, Constants.MENU_SEND_TO_GOOGLE, Menu.NONE,
|
|
||||||
R.string.track_list_send_google);
|
|
||||||
SubMenu share = menu.addSubMenu(
|
|
||||||
Menu.NONE, Constants.MENU_SHARE, Menu.NONE, R.string.track_list_share_track);
|
|
||||||
share.add(
|
|
||||||
Menu.NONE, Constants.MENU_SHARE_MAP, Menu.NONE, R.string.track_list_share_map);
|
|
||||||
share.add(Menu.NONE, Constants.MENU_SHARE_FUSION_TABLE, Menu.NONE,
|
|
||||||
R.string.track_list_share_fusion_table);
|
|
||||||
share.add(Menu.NONE, Constants.MENU_SHARE_GPX_FILE, Menu.NONE,
|
|
||||||
String.format(shareFileFormat, fileTypes[0]));
|
|
||||||
share.add(Menu.NONE, Constants.MENU_SHARE_KML_FILE, Menu.NONE,
|
|
||||||
String.format(shareFileFormat, fileTypes[1]));
|
|
||||||
share.add(Menu.NONE, Constants.MENU_SHARE_CSV_FILE, Menu.NONE,
|
|
||||||
String.format(shareFileFormat, fileTypes[2]));
|
|
||||||
share.add(Menu.NONE, Constants.MENU_SHARE_TCX_FILE, Menu.NONE,
|
|
||||||
String.format(shareFileFormat, fileTypes[3]));
|
|
||||||
SubMenu save = menu.addSubMenu(
|
|
||||||
Menu.NONE, Constants.MENU_WRITE_TO_SD_CARD, Menu.NONE, R.string.track_list_save_sd);
|
|
||||||
save.add(Menu.NONE, Constants.MENU_SAVE_GPX_FILE, Menu.NONE,
|
|
||||||
String.format(saveFileFormat, fileTypes[0]));
|
|
||||||
save.add(Menu.NONE, Constants.MENU_SAVE_KML_FILE, Menu.NONE,
|
|
||||||
String.format(saveFileFormat, fileTypes[1]));
|
|
||||||
save.add(Menu.NONE, Constants.MENU_SAVE_CSV_FILE, Menu.NONE,
|
|
||||||
String.format(saveFileFormat, fileTypes[2]));
|
|
||||||
save.add(Menu.NONE, Constants.MENU_SAVE_TCX_FILE, Menu.NONE,
|
|
||||||
String.format(saveFileFormat, fileTypes[3]));
|
|
||||||
menu.add(Menu.NONE, Constants.MENU_DELETE, Menu.NONE, R.string.track_list_delete_track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Runnable serviceBindingChanged = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updateButtonsEnabled();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private TrackRecordingServiceConnection serviceConnection;
|
|
||||||
private SharedPreferences preferences;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(
|
|
||||||
SharedPreferences sharedPreferences, String key) {
|
|
||||||
if (key == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (key.equals(getString(R.string.metric_units_key))) {
|
|
||||||
metricUnits = sharedPreferences.getBoolean(
|
|
||||||
getString(R.string.metric_units_key), true);
|
|
||||||
if (tracksCursor != null && !tracksCursor.isClosed()) {
|
|
||||||
tracksCursor.requery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (key.equals(getString(R.string.recording_track_key))) {
|
|
||||||
recordingTrackId = sharedPreferences.getLong(
|
|
||||||
getString(R.string.recording_track_key), -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
|
||||||
Intent result = new Intent();
|
|
||||||
result.putExtra("trackid", id);
|
|
||||||
setResult(Constants.SHOW_TRACK, result);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
|
||||||
Intent intent;
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case Constants.MENU_SHOW: {
|
|
||||||
onListItemClick(null, null, 0, trackId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case Constants.MENU_EDIT: {
|
|
||||||
intent = new Intent(this, TrackDetail.class).putExtra(TrackDetail.TRACK_ID, trackId);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case Constants.MENU_PLAY:
|
|
||||||
if (PlayTrackUtils.isEarthInstalled(this)) {
|
|
||||||
PlayTrackUtils.playTrack(this, trackId);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
showDialog(DIALOG_INSTALL_EARTH_ID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case Constants.MENU_SEND_TO_GOOGLE:
|
|
||||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
|
||||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, true, true));
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_MAP:
|
|
||||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
|
||||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, false, false));
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_FUSION_TABLE:
|
|
||||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
|
||||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, false, true, false));
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_GPX_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.GPX, true);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_KML_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.KML, true);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_CSV_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.CSV, true);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SHARE_TCX_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.TCX, true);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SAVE_GPX_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.GPX, false);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SAVE_KML_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.KML, false);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SAVE_CSV_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.CSV, false);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_SAVE_TCX_FILE:
|
|
||||||
startSaveActivity(TrackFileFormat.TCX, false);
|
|
||||||
return true;
|
|
||||||
case Constants.MENU_DELETE:
|
|
||||||
showDialog(DIALOG_DELETE_CURRENT_ID);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
Log.w(TAG, "Unknown menu item: " + item.getItemId() + "(" + item.getTitle() + ")");
|
|
||||||
return super.onMenuItemSelected(featureId, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the {@link SaveActivity} to save trackId.
|
|
||||||
*
|
|
||||||
* @param trackFileFormat the track file format
|
|
||||||
* @param shareTrack true to share the track after saving
|
|
||||||
*/
|
|
||||||
private void startSaveActivity(TrackFileFormat trackFileFormat, boolean shareTrack) {
|
|
||||||
Intent intent = new Intent(this, SaveActivity.class)
|
|
||||||
.putExtra(SaveActivity.EXTRA_TRACK_ID, trackId)
|
|
||||||
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat)
|
|
||||||
.putExtra(SaveActivity.EXTRA_SHARE_TRACK, shareTrack);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
switch (v.getId()) {
|
|
||||||
case R.id.tracklist_btn_delete_all:
|
|
||||||
showDialog(DIALOG_DELETE_ALL_ID);
|
|
||||||
break;
|
|
||||||
case R.id.tracklist_btn_export_all:
|
|
||||||
showDialog(DIALOG_EXPORT_ALL_ID);
|
|
||||||
break;
|
|
||||||
case R.id.tracklist_btn_import_all:
|
|
||||||
Intent intent = new Intent(this, ImportActivity.class)
|
|
||||||
.putExtra(ImportActivity.EXTRA_IMPORT_ALL, true);
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// We don't need a window title bar:
|
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
|
|
||||||
setContentView(R.layout.mytracks_list);
|
|
||||||
|
|
||||||
listView = getListView();
|
|
||||||
listView.setOnCreateContextMenuListener(contextMenuListener);
|
|
||||||
|
|
||||||
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
||||||
serviceConnection = new TrackRecordingServiceConnection(this, serviceBindingChanged);
|
|
||||||
|
|
||||||
View deleteAll = findViewById(R.id.tracklist_btn_delete_all);
|
|
||||||
deleteAll.setOnClickListener(this);
|
|
||||||
|
|
||||||
View exportAll = findViewById(R.id.tracklist_btn_export_all);
|
|
||||||
exportAll.setOnClickListener(this);
|
|
||||||
|
|
||||||
updateButtonsEnabled();
|
|
||||||
|
|
||||||
findViewById(R.id.tracklist_btn_import_all).setOnClickListener(this);
|
|
||||||
|
|
||||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
|
||||||
metricUnits =
|
|
||||||
preferences.getBoolean(getString(R.string.metric_units_key), true);
|
|
||||||
recordingTrackId =
|
|
||||||
preferences.getLong(getString(R.string.recording_track_key), -1);
|
|
||||||
|
|
||||||
tracksCursor = getContentResolver().query(
|
|
||||||
TracksColumns.CONTENT_URI, null, null, null, "_id DESC");
|
|
||||||
startManagingCursor(tracksCursor);
|
|
||||||
setListAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
serviceConnection.bindIfRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
serviceConnection.unbind();
|
|
||||||
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.search_only, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.menu_search:
|
|
||||||
onSearchRequested();
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Dialog onCreateDialog(int id) {
|
|
||||||
switch (id) {
|
|
||||||
case DIALOG_INSTALL_EARTH_ID:
|
|
||||||
return PlayTrackUtils.createInstallEarthDialog(this);
|
|
||||||
case DIALOG_EXPORT_ALL_ID:
|
|
||||||
String exportFileFormat = getString(R.string.track_list_export_file);
|
|
||||||
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
|
||||||
String[] choices = new String[fileTypes.length];
|
|
||||||
for (int i = 0; i < fileTypes.length; i++) {
|
|
||||||
choices[i] = String.format(exportFileFormat, fileTypes[i]);
|
|
||||||
}
|
|
||||||
return new AlertDialog.Builder(this)
|
|
||||||
.setNegativeButton(R.string.generic_cancel, null)
|
|
||||||
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
int index = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
|
||||||
Intent intent = new Intent(TrackList.this, ExportActivity.class).putExtra(
|
|
||||||
ExportActivity.EXTRA_TRACK_FILE_FORMAT,
|
|
||||||
(Parcelable) TrackFileFormat.values()[index]);
|
|
||||||
TrackList.this.startActivity(intent);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setSingleChoiceItems(choices, 0, null)
|
|
||||||
.setTitle(R.string.track_list_export_all)
|
|
||||||
.create();
|
|
||||||
case DIALOG_DELETE_ALL_ID:
|
|
||||||
return DialogUtils.createConfirmationDialog(this,
|
|
||||||
R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
MyTracksProviderUtils.Factory.get(TrackList.this).deleteAllTracks();
|
|
||||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
||||||
Editor editor = sharedPreferences.edit();
|
|
||||||
// TODO: Go through data manager
|
|
||||||
editor.putLong(getString(R.string.selected_track_key), -1L);
|
|
||||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
case DIALOG_DELETE_CURRENT_ID:
|
|
||||||
return DialogUtils.createConfirmationDialog(this,
|
|
||||||
R.string.track_list_delete_track_confirm_message,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
MyTracksProviderUtils.Factory.get(TrackList.this).deleteTrack(trackId);
|
|
||||||
// If the deleted track was selected, unselect it.
|
|
||||||
String selectedTrackKey = getString(R.string.selected_track_key);
|
|
||||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
||||||
if (sharedPreferences.getLong(selectedTrackKey, -1L) == trackId) {
|
|
||||||
Editor editor = sharedPreferences.edit().putLong(selectedTrackKey, -1L);
|
|
||||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateButtonsEnabled() {
|
|
||||||
View deleteAll = findViewById(R.id.tracklist_btn_delete_all);
|
|
||||||
View exportAll = findViewById(R.id.tracklist_btn_export_all);
|
|
||||||
|
|
||||||
boolean notRecording = !isRecording();
|
|
||||||
deleteAll.setEnabled(notRecording);
|
|
||||||
exportAll.setEnabled(notRecording);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setListAdapter() {
|
|
||||||
// Get a cursor with all tracks
|
|
||||||
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
|
|
||||||
this,
|
|
||||||
R.layout.mytracks_list_item,
|
|
||||||
tracksCursor,
|
|
||||||
new String[] { TracksColumns.NAME, TracksColumns.STARTTIME,
|
|
||||||
TracksColumns.TOTALDISTANCE, TracksColumns.DESCRIPTION,
|
|
||||||
TracksColumns.CATEGORY },
|
|
||||||
new int[] { R.id.track_list_item_name, R.id.track_list_item_time,
|
|
||||||
R.id.track_list_item_stats, R.id.track_list_item_description,
|
|
||||||
R.id.track_list_item_category });
|
|
||||||
|
|
||||||
final int startTimeIdx =
|
|
||||||
tracksCursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
|
|
||||||
final int totalTimeIdx =
|
|
||||||
tracksCursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
|
|
||||||
final int totalDistanceIdx =
|
|
||||||
tracksCursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
|
|
||||||
|
|
||||||
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
|
|
||||||
@Override
|
|
||||||
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
|
|
||||||
TextView textView = (TextView) view;
|
|
||||||
if (columnIndex == startTimeIdx) {
|
|
||||||
long time = cursor.getLong(startTimeIdx);
|
|
||||||
textView.setText(StringUtils.formatDateTime(TrackList.this, time));
|
|
||||||
} else if (columnIndex == totalDistanceIdx) {
|
|
||||||
double totalDistance = cursor.getDouble(totalDistanceIdx);
|
|
||||||
long totalTime = cursor.getLong(totalTimeIdx);
|
|
||||||
String totalDistanceStr = StringUtils.formatTimeDistance(
|
|
||||||
TrackList.this, totalTime, totalDistance, metricUnits);
|
|
||||||
textView.setText(totalDistanceStr);
|
|
||||||
} else {
|
|
||||||
textView.setText(cursor.getString(columnIndex));
|
|
||||||
if (textView.getText().length() < 1) {
|
|
||||||
textView.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
textView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
setListAdapter(adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRecording() {
|
|
||||||
return ServiceUtils.isRecording(TrackList.this, serviceConnection.getServiceIfBound(), preferences);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,395 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 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 com.google.android.apps.mytracks;
|
||||||
|
|
||||||
|
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||||
|
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||||
|
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
|
||||||
|
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||||
|
import com.google.android.apps.mytracks.services.ServiceUtils;
|
||||||
|
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
||||||
|
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
||||||
|
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||||
|
import com.google.android.apps.mytracks.util.StringUtils;
|
||||||
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.ResourceCursorAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An activity displaying a list of tracks.
|
||||||
|
*
|
||||||
|
* @author Leif Hendrik Wilden
|
||||||
|
*/
|
||||||
|
public class TrackListActivity extends Activity {
|
||||||
|
|
||||||
|
private static final String TAG = TrackListActivity.class.getSimpleName();
|
||||||
|
private static final int DIALOG_EXPORT_ALL_ID = 0;
|
||||||
|
private static final int DIALOG_DELETE_ALL_ID = 1;
|
||||||
|
|
||||||
|
// Callback when the trackRecordingServiceConnection binding changes
|
||||||
|
private final Runnable bindChangedCallback = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (trackRecordingServiceConnection) {
|
||||||
|
if (startNewRecording) {
|
||||||
|
startRecording();
|
||||||
|
} else {
|
||||||
|
updateMenu();
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
private boolean metricUnits;
|
||||||
|
private long recordingTrackId;
|
||||||
|
private ListView listView;
|
||||||
|
private ResourceCursorAdapter adapter;
|
||||||
|
|
||||||
|
// True to start a new recording
|
||||||
|
private boolean startNewRecording = false;
|
||||||
|
|
||||||
|
private MenuItem recordTrack;
|
||||||
|
private MenuItem stopRecording;
|
||||||
|
private MenuItem search;
|
||||||
|
private MenuItem importAll;
|
||||||
|
private MenuItem exportAll;
|
||||||
|
private MenuItem deleteAll;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.track_list);
|
||||||
|
|
||||||
|
trackRecordingServiceConnection = new TrackRecordingServiceConnection(
|
||||||
|
this, bindChangedCallback);
|
||||||
|
|
||||||
|
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
|
sharedPreferences.registerOnSharedPreferenceChangeListener(
|
||||||
|
new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
|
if (key == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key.equals(getString(R.string.metric_units_key))) {
|
||||||
|
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
|
||||||
|
}
|
||||||
|
if (key.equals(getString(R.string.recording_track_key))) {
|
||||||
|
recordingTrackId = sharedPreferences.getLong(
|
||||||
|
getString(R.string.recording_track_key), -1L);
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true);
|
||||||
|
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
|
||||||
|
|
||||||
|
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
|
||||||
|
Cursor trackCursor = myTracksProviderUtils.getTracksCursor(
|
||||||
|
null, null, TracksColumns._ID + " DESC");
|
||||||
|
startManagingCursor(trackCursor);
|
||||||
|
listView = (ListView) findViewById(R.id.track_list);
|
||||||
|
listView.setOnItemClickListener(new OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
setResult(Constants.SHOW_TRACK, new Intent().putExtra("trackid", id));
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, trackCursor, true) {
|
||||||
|
@Override
|
||||||
|
public void bindView(View view, Context context, Cursor cursor) {
|
||||||
|
int idIndex = cursor.getColumnIndex(TracksColumns._ID);
|
||||||
|
int nameIndex = cursor.getColumnIndex(TracksColumns.NAME);
|
||||||
|
int categoryIndex = cursor.getColumnIndex(TracksColumns.CATEGORY);
|
||||||
|
int timeIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
|
||||||
|
int distanceIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
|
||||||
|
int startIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
|
||||||
|
int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION);
|
||||||
|
|
||||||
|
boolean isRecording = cursor.getLong(idIndex) == recordingTrackId;
|
||||||
|
|
||||||
|
TextView name = (TextView) view.findViewById(R.id.track_list_item_name);
|
||||||
|
name.setText(cursor.getString(nameIndex));
|
||||||
|
name.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
isRecording ? R.drawable.menu_record_track : R.drawable.track, 0, 0, 0);
|
||||||
|
|
||||||
|
TextView category = (TextView) view.findViewById(R.id.track_list_item_category);
|
||||||
|
category.setText(cursor.getString(categoryIndex));
|
||||||
|
|
||||||
|
TextView time = (TextView) view.findViewById(R.id.track_list_item_time);
|
||||||
|
time.setText(StringUtils.formatElapsedTime(cursor.getLong(timeIndex)));
|
||||||
|
time.setVisibility(isRecording ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
TextView distance = (TextView) view.findViewById(R.id.track_list_item_distance);
|
||||||
|
distance.setText(StringUtils.formatDistance(
|
||||||
|
TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits));
|
||||||
|
distance.setVisibility(isRecording ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
TextView start = (TextView) view.findViewById(R.id.track_list_item_start);
|
||||||
|
start.setText(
|
||||||
|
StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex)));
|
||||||
|
start.setVisibility(start.getText().equals(name.getText()) ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
TextView description = (TextView) view.findViewById(R.id.track_list_item_description);
|
||||||
|
description.setText(cursor.getString(descriptionIndex));
|
||||||
|
description.setVisibility(description.getText().length() == 0 ? View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
listView.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
trackRecordingServiceConnection.bindIfRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
trackRecordingServiceConnection.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.track_list, menu);
|
||||||
|
|
||||||
|
recordTrack = menu.findItem(R.id.menu_record_track);
|
||||||
|
stopRecording = menu.findItem(R.id.menu_stop_recording);
|
||||||
|
search = menu.findItem(R.id.menu_search);
|
||||||
|
importAll = menu.findItem(R.id.menu_import_all);
|
||||||
|
exportAll = menu.findItem(R.id.menu_export_all);
|
||||||
|
deleteAll = menu.findItem(R.id.menu_delete_all);
|
||||||
|
|
||||||
|
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, search);
|
||||||
|
updateMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the menu based on whether My Tracks is recording or not.
|
||||||
|
*/
|
||||||
|
private void updateMenu() {
|
||||||
|
boolean isRecording = ServiceUtils.isRecording(
|
||||||
|
this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences);
|
||||||
|
updateMenuItems(isRecording);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the menu items.
|
||||||
|
*
|
||||||
|
* @param isRecording true if recording
|
||||||
|
*/
|
||||||
|
private void updateMenuItems(boolean isRecording) {
|
||||||
|
if (recordTrack != null) {
|
||||||
|
recordTrack.setVisible(!isRecording);
|
||||||
|
}
|
||||||
|
if (stopRecording != null) {
|
||||||
|
stopRecording.setVisible(isRecording);
|
||||||
|
}
|
||||||
|
if (importAll != null) {
|
||||||
|
importAll.setVisible(!isRecording);
|
||||||
|
}
|
||||||
|
if (exportAll != null) {
|
||||||
|
exportAll.setVisible(!isRecording);
|
||||||
|
}
|
||||||
|
if (deleteAll != null) {
|
||||||
|
deleteAll.setVisible(!isRecording);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.menu_record_track:
|
||||||
|
updateMenuItems(true);
|
||||||
|
synchronized (trackRecordingServiceConnection) {
|
||||||
|
startNewRecording = true;
|
||||||
|
trackRecordingServiceConnection.startAndBind();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the binding has happened, then invoke the callback to start a
|
||||||
|
* new recording. If the binding hasn't happened, then invoking the
|
||||||
|
* callback will have no effect. But when the binding occurs, the
|
||||||
|
* callback will get invoked.
|
||||||
|
*/
|
||||||
|
bindChangedCallback.run();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case R.id.menu_stop_recording:
|
||||||
|
updateMenuItems(false);
|
||||||
|
stopRecording();
|
||||||
|
trackRecordingServiceConnection.stop();
|
||||||
|
return true;
|
||||||
|
case R.id.menu_search:
|
||||||
|
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
|
||||||
|
case R.id.menu_import_all:
|
||||||
|
startActivity(new Intent(this, ImportActivity.class)
|
||||||
|
.putExtra(ImportActivity.EXTRA_IMPORT_ALL, true));
|
||||||
|
return true;
|
||||||
|
case R.id.menu_export_all:
|
||||||
|
showDialog(DIALOG_EXPORT_ALL_ID);
|
||||||
|
return true;
|
||||||
|
case R.id.menu_delete_all:
|
||||||
|
showDialog(DIALOG_DELETE_ALL_ID);
|
||||||
|
return true;
|
||||||
|
case R.id.menu_aggregated_statistics:
|
||||||
|
startActivity(new Intent(this, AggregatedStatsActivity.class));
|
||||||
|
return true;
|
||||||
|
case R.id.menu_settings:
|
||||||
|
startActivity(new Intent(this, SettingsActivity.class));
|
||||||
|
return true;
|
||||||
|
case R.id.menu_help:
|
||||||
|
startActivity(new Intent(this, WelcomeActivity.class));
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new recording.
|
||||||
|
*/
|
||||||
|
private void startRecording() {
|
||||||
|
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
|
||||||
|
if (service != null) {
|
||||||
|
try {
|
||||||
|
recordingTrackId = service.startNewTrack();
|
||||||
|
startNewRecording = false;
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
Toast.makeText(TrackListActivity.this, R.string.track_record_success, Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
Log.d(TAG, "Started a new recording");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Toast.makeText(TrackListActivity.this, R.string.track_record_error, Toast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
Log.d(TAG, "Unable to start a new recording.", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "service not available to start a new recording");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the current recording.
|
||||||
|
*/
|
||||||
|
private void stopRecording() {
|
||||||
|
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
|
||||||
|
if (service != null) {
|
||||||
|
try {
|
||||||
|
service.endCurrentTrack();
|
||||||
|
if (recordingTrackId != -1L) {
|
||||||
|
Intent intent = new Intent(this, TrackDetail.class)
|
||||||
|
.putExtra(TrackDetail.SHOW_CANCEL, false)
|
||||||
|
.putExtra(TrackDetail.TRACK_ID, recordingTrackId);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
recordingTrackId = -1L;
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "Unable to stop recording.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Dialog onCreateDialog(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case DIALOG_EXPORT_ALL_ID:
|
||||||
|
return createExportAllDialog();
|
||||||
|
case DIALOG_DELETE_ALL_ID:
|
||||||
|
return DialogUtils.createConfirmationDialog(this,
|
||||||
|
R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
MyTracksProviderUtils.Factory.get(TrackListActivity.this).deleteAllTracks();
|
||||||
|
/*
|
||||||
|
* TODO Verify that selected_track_key is still needed with the
|
||||||
|
* ICS navigation design
|
||||||
|
*/
|
||||||
|
Editor editor = sharedPreferences.edit();
|
||||||
|
// TODO: Go through data manager
|
||||||
|
editor.putLong(getString(R.string.selected_track_key), -1L);
|
||||||
|
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an export all dialog.
|
||||||
|
*/
|
||||||
|
private AlertDialog createExportAllDialog() {
|
||||||
|
String exportFileFormat = getString(R.string.track_list_export_file);
|
||||||
|
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
||||||
|
String[] choices = new String[fileTypes.length];
|
||||||
|
for (int i = 0; i < fileTypes.length; i++) {
|
||||||
|
choices[i] = String.format(exportFileFormat, fileTypes[i]);
|
||||||
|
}
|
||||||
|
return new AlertDialog.Builder(this).setNegativeButton(R.string.generic_cancel, null)
|
||||||
|
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
int index = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
|
||||||
|
Intent intent = new Intent(TrackListActivity.this, ExportActivity.class).putExtra(
|
||||||
|
ExportActivity.EXTRA_TRACK_FILE_FORMAT,
|
||||||
|
(Parcelable) TrackFileFormat.values()[index]);
|
||||||
|
TrackListActivity.this.startActivity(intent);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setSingleChoiceItems(choices, 0, null)
|
||||||
|
.setTitle(R.string.track_list_export_all)
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||||
|
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(search)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,18 +16,37 @@
|
|||||||
|
|
||||||
package com.google.android.apps.mytracks.util;
|
package com.google.android.apps.mytracks.util;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.SearchManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
import android.widget.SearchView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API level 11 specific implementation of the {@link ApiAdapter}.
|
* API level 11 specific implementation of the {@link ApiAdapter}.
|
||||||
*
|
*
|
||||||
* @author Jimmy Shih
|
* @author Jimmy Shih
|
||||||
*/
|
*/
|
||||||
public class Api11Adapter extends Api9Adapter {
|
@TargetApi(11)
|
||||||
|
public class Api11Adapter extends Api10Adapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showActionBar(Activity activity) {
|
public void showActionBar(Activity activity) {
|
||||||
activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
|
activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureSearchWidget(Activity activity, MenuItem menuItem) {
|
||||||
|
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
|
||||||
|
SearchView searchView = (SearchView) menuItem.getActionView();
|
||||||
|
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.getComponentName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleSearchMenuSelection(Activity activity) {
|
||||||
|
// Returns false to allow the platform to expand the search widget.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.google.android.apps.mytracks.util;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API level 14 specific implementation of the {@link ApiAdapter}.
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
@TargetApi(14)
|
||||||
|
public class Api14Adapter extends Api11Adapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleSearchKey(MenuItem menuItem) {
|
||||||
|
menuItem.expandActionView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ import android.content.Context;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -108,4 +109,21 @@ public class Api7Adapter implements ApiAdapter {
|
|||||||
// via the regular menu.
|
// via the regular menu.
|
||||||
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureSearchWidget(Activity activity, MenuItem menuItem) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleSearchMenuSelection(Activity activity) {
|
||||||
|
activity.onSearchRequested();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleSearchKey(MenuItem menuItem) {
|
||||||
|
// Return false and allow the framework to handle the search key.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.bluetooth.BluetoothSocket;
|
import android.bluetooth.BluetoothSocket;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -110,4 +111,31 @@ public interface ApiAdapter {
|
|||||||
*/
|
*/
|
||||||
public void showActionBar(Activity activity);
|
public void showActionBar(Activity activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the search widget.
|
||||||
|
*
|
||||||
|
* Due to changes in API level 11.
|
||||||
|
*
|
||||||
|
* @param activity the activity
|
||||||
|
* @param menuItem the search menu item
|
||||||
|
*/
|
||||||
|
public void configureSearchWidget(Activity activity, MenuItem menuItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the search menu selection. Returns true if handled.
|
||||||
|
*
|
||||||
|
* Due to changes in API level 11.
|
||||||
|
*
|
||||||
|
* @param activity the activity
|
||||||
|
*/
|
||||||
|
public boolean handleSearchMenuSelection(Activity activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the search key press. Returns true if handled.
|
||||||
|
*
|
||||||
|
* Due to changes in API level 14.
|
||||||
|
*
|
||||||
|
* @param menu the search menu
|
||||||
|
*/
|
||||||
|
public boolean handleSearchKey(MenuItem menu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ public class ApiAdapterFactory {
|
|||||||
*/
|
*/
|
||||||
public static ApiAdapter getApiAdapter() {
|
public static ApiAdapter getApiAdapter() {
|
||||||
if (apiAdapter == null) {
|
if (apiAdapter == null) {
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
if (Build.VERSION.SDK_INT >= 14) {
|
||||||
|
apiAdapter = new Api14Adapter();
|
||||||
|
return apiAdapter;
|
||||||
|
} else if (Build.VERSION.SDK_INT >= 11) {
|
||||||
apiAdapter = new Api11Adapter();
|
apiAdapter = new Api11Adapter();
|
||||||
return apiAdapter;
|
return apiAdapter;
|
||||||
} else if (Build.VERSION.SDK_INT >= 10) {
|
} else if (Build.VERSION.SDK_INT >= 10) {
|
||||||
|
|||||||
Reference in New Issue
Block a user