From 47c189409ef7475663cb9d793ed5b54160f50ad9 Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Sun, 24 Nov 2013 12:56:42 -0800 Subject: [PATCH] Add menu option for merge and play --- MyTracks/res/drawable-hdpi/ic_menu_merge.png | Bin 0 -> 536 bytes MyTracks/res/drawable-mdpi/ic_menu_merge.png | Bin 0 -> 403 bytes MyTracks/res/drawable-xhdpi/ic_menu_merge.png | Bin 0 -> 647 bytes MyTracks/res/menu/map.xml | 2 +- MyTracks/res/menu/track_detail.xml | 25 ++-- MyTracks/res/menu/track_list.xml | 4 + MyTracks/res/values/strings.xml | 6 + .../AbstractSendToGoogleActivity.java | 133 +++++++++-------- .../apps/mytracks/TrackDetailActivity.java | 5 + .../apps/mytracks/TrackListActivity.java | 9 +- .../fragments/MergeDialogFragment.java | 136 ++++++++++++++++++ .../apps/mytracks/util/TrackUtils.java | 4 + 12 files changed, 248 insertions(+), 76 deletions(-) create mode 100644 MyTracks/res/drawable-hdpi/ic_menu_merge.png create mode 100644 MyTracks/res/drawable-mdpi/ic_menu_merge.png create mode 100644 MyTracks/res/drawable-xhdpi/ic_menu_merge.png create mode 100644 MyTracks/src/com/google/android/apps/mytracks/fragments/MergeDialogFragment.java diff --git a/MyTracks/res/drawable-hdpi/ic_menu_merge.png b/MyTracks/res/drawable-hdpi/ic_menu_merge.png new file mode 100644 index 0000000000000000000000000000000000000000..c79743a70d2a1e9615064cf19fe8bb131b7b4992 GIT binary patch literal 536 zcmV+z0_XjSP)TR1ZanE>9hJ}$O>b^ivjrk6N$-9T9P}8hu6>u?BOPT&=7%jFfK&O=L3{~ zj|a@L#+3u*V<=xM0UK#tr%_16wyxys9+0t+D9tq~dq0I^bW|__Ccp&zKzAp^lORAx zXmTc3uG7e1(A*BnhWeJ5?3jNa{?$E`;?BU%Mw#KQoc0Q0XiHgwJ86T01~;) zz)bX8T1`^eBy_^kWimqnb0E1UxiJ(tJ0kHs3IQC2ee(ZL7wPF@(i&TuQ+p#Yz}Fv1 zkxEl9Ke&#Kp{I~(cUt&#^<$?#+6s)ZS;N|esx!|fN9=rSm>xkZNuwzhJRI~rLgiO!X4o1f3c55kHKIt82=w{ a0t^7KPR@x)oe#AD0000P)gbz!Dn96cxq5P}q!AzJG@LXgQunN*YpC{T!&)m!g6K)Y<`+`=As~Onnb+ xCpJL!_)?{`BB!-OZVPF&E*NzH-2p&=0RS~yg}+Cf|J?up002ovPDHLkV1gr^o74aR literal 0 HcmV?d00001 diff --git a/MyTracks/res/drawable-xhdpi/ic_menu_merge.png b/MyTracks/res/drawable-xhdpi/ic_menu_merge.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7979b21acbf4a965358b142e707b6e71190dee GIT binary patch literal 647 zcmV;20(kw2P)^@RCwC#TFY_5Fc7u5QvfNz4bT7u zKmjIqd=CWxcgP*z6AGXJQb1^c0zv^4KvtQT8RBuU^+87Fy_p>|STfqTAMZ*;5kU|H zK@bE%5WaCfpSwyPnSiyDCfCquQ2B{m`bzM*5yTBCuM{s@ejLZ~q4fkH=HEqng2fjjJ zDw1f7PcSEZ0>qLk=7$DThnO2~4iE*N9h4R1oU>Rfxi1l^j z{@;9nXSJphT%!jl!(QAydx&P}UO)m!00|%gB!C2v0Ix_4?}bl*RDq+4-k|HF18l4m z7Ui~4`F`Lfj#3VfTIT_1XnHk<_HNnyG(rGeUuUy3#hma%0E(DycP}Iyw!snrSGL{e z-Utb+pa{T@uCltTjQ#;{INdz~IQO&N3M+j(h|GnA{aq3Ot4}mteu1k_j@XFguDl_3 zq`XRWFB(?=bNXZ8HERB=iv$@vaQAu5_xq(QPm4!iI67MyJj*I9Yzf$EF8Bb;pRR<_ zTC*pxsvK<#p^IdlR=x&BK1Fu7Y+~>`JN(vtD1WiI)W@G1@aM`jA_#&Y h2!bF8!Uo?03;;i=^bw1mFTel*002ovPDHLkV1g^17A61y literal 0 HcmV?d00001 diff --git a/MyTracks/res/menu/map.xml b/MyTracks/res/menu/map.xml index a9e39fadf..1d6e34430 100644 --- a/MyTracks/res/menu/map.xml +++ b/MyTracks/res/menu/map.xml @@ -17,7 +17,7 @@ limitations under the License. diff --git a/MyTracks/res/menu/track_detail.xml b/MyTracks/res/menu/track_detail.xml index 702160288..8b29cce1f 100644 --- a/MyTracks/res/menu/track_detail.xml +++ b/MyTracks/res/menu/track_detail.xml @@ -44,50 +44,55 @@ limitations under the License. android:id="@+id/track_detail_markers" android:orderInCategory="5" android:title="@string/menu_markers"/> - + + \ No newline at end of file diff --git a/MyTracks/res/menu/track_list.xml b/MyTracks/res/menu/track_list.xml index b3f3938ce..ae1a3ab1c 100644 --- a/MyTracks/res/menu/track_list.xml +++ b/MyTracks/res/menu/track_list.xml @@ -26,6 +26,10 @@ limitations under the License. android:id="@+id/track_list_start_gps" android:showAsAction="ifRoom" android:title="@string/menu_start_gps"/> + Markers + + Merge & play + onCreateLoader(int arg0, Bundle arg1) { return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, null, - null, - "IFNULL(" + TracksColumns.SHAREDWITHME + ",0) ASC, " + TracksColumns.STARTTIME + " DESC"); + null, TrackUtils.TRACK_SORT_ORDER); } @Override @@ -531,6 +532,10 @@ public class TrackListActivity extends AbstractSendToGoogleActivity } myTracksLocationManager.close(); return true; + case R.id.track_list_merge: + MergeDialogFragment.newInstance(-1L) + .show(getSupportFragmentManager(), MergeDialogFragment.MERGE_DIALOG_TAG); + return true; case R.id.track_list_refresh: if (driveSync) { SyncUtils.syncNow(this); diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/MergeDialogFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/MergeDialogFragment.java new file mode 100644 index 000000000..09602f6c2 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/MergeDialogFragment.java @@ -0,0 +1,136 @@ +/* + * Copyright 2013 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.fragments; + +import com.google.android.apps.mytracks.content.MyTracksProviderUtils; +import com.google.android.apps.mytracks.content.Track; +import com.google.android.apps.mytracks.util.TrackUtils; +import com.google.android.maps.mytracks.R; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.database.Cursor; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.util.SparseBooleanArray; + +import java.util.ArrayList; + +/** + * A DialogFragment to merge and play tracks. + * + * @author Jimmy Shih + */ +public class MergeDialogFragment extends DialogFragment { + + public static final String MERGE_DIALOG_TAG = "mergeDialog"; + + /** + * Interface for caller of this dialog fragment. + * + * @author Jimmy Shih + */ + public interface MergeCaller { + + /** + * Called when merge is done. + */ + public void onMergeDone(long[] trackIds); + } + + private static final String KEY_TRACK_ID = "trackId"; + + public static MergeDialogFragment newInstance(long trackId) { + Bundle bundle = new Bundle(); + bundle.putLong(KEY_TRACK_ID, trackId); + + MergeDialogFragment fragment = new MergeDialogFragment(); + fragment.setArguments(bundle); + return fragment; + } + + private MergeCaller caller; + private String[] items; + private boolean[] checkedItems; + private long[] trackIds; + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + caller = (MergeCaller) activity; + } catch (ClassCastException e) { + throw new ClassCastException( + activity.toString() + " must implement " + MergeCaller.class.getSimpleName()); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + loadData(); + return new AlertDialog.Builder(getActivity()).setMultiChoiceItems(items, checkedItems, null) + .setNegativeButton(R.string.generic_cancel, null) + .setPositiveButton(R.string.menu_play, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SparseBooleanArray array = ((AlertDialog) dialog).getListView() + .getCheckedItemPositions(); + caller.onMergeDone(getChecked(array)); + } + }).setTitle(R.string.menu_merge).create(); + } + + private long[] getChecked(SparseBooleanArray array) { + ArrayList checked = new ArrayList(); + for (int i = 0; i < array.size(); i++) { + if (array.valueAt(i)) { + checked.add(trackIds[i]); + } + } + long[] result = new long[checked.size()]; + for (int i = 0; i < checked.size(); i++) { + result[i] = checked.get(i).longValue(); + } + return result; + } + + private void loadData() { + long trackId = getArguments().getLong(KEY_TRACK_ID); + MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(getActivity()); + Cursor cursor = myTracksProviderUtils.getTrackCursor(null, null, TrackUtils.TRACK_SORT_ORDER); + + if (cursor == null) { + items = new String[] {}; + checkedItems = new boolean[] {}; + trackIds = new long[] {}; + } else { + int count = cursor.getCount(); + items = new String[count]; + checkedItems = new boolean[count]; + trackIds = new long[count]; + for (int i = 0; i < count; i++) { + cursor.moveToPosition(i); + Track track = myTracksProviderUtils.createTrack(cursor); + items[i] = track.getName(); + checkedItems[i] = trackId != -1L && track.getId() == trackId; + trackIds[i] = track.getId(); + } + } + } +} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/TrackUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/TrackUtils.java index d59825404..c1a96955c 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/TrackUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/TrackUtils.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.util; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; +import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.maps.mytracks.R; @@ -32,6 +33,9 @@ public class TrackUtils { private TrackUtils() {} + public static String TRACK_SORT_ORDER = "IFNULL(" + TracksColumns.SHAREDWITHME + ",0) ASC, " + + TracksColumns.STARTTIME + " DESC"; + public static void updateTrack(Context context, Track track, String name, String category, String description, MyTracksProviderUtils myTracksProviderUtils, TrackRecordingServiceConnection trackRecordingServiceConnection, boolean newWeight) {