forked from upstream-mirrors/OpenTracks
Add a "Shared with me" section.
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/track_list_header"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:paddingBottom="2dp"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:text="@string/track_list_shared_with_me"
|
||||||
|
style="?android:attr/listSeparatorTextViewStyle" />
|
||||||
@@ -2424,7 +2424,12 @@ limitations under the License.
|
|||||||
success.">
|
success.">
|
||||||
Now recording a new track.
|
Now recording a new track.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="track_list_shared_with_me"
|
||||||
|
translation_description="The section header for ‘Shared with me’ tracks from Google
|
||||||
|
Drive.">
|
||||||
|
Shared with me
|
||||||
|
</string>
|
||||||
|
|
||||||
<!-- Track Widget -->
|
<!-- Track Widget -->
|
||||||
<string name="track_widget_config_title"
|
<string name="track_widget_config_title"
|
||||||
translation_description="Title of the page to configure the My Tracks widget items.">
|
translation_description="Title of the page to configure the My Tracks widget items.">
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||||
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
|
import android.support.v4.widget.ResourceCursorAdapter;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A section based resource cursor adapter. Currently only supports one
|
||||||
|
* additional section header, "Shared with me".
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
public abstract class SectionResourceCursorAdapter extends ResourceCursorAdapter {
|
||||||
|
|
||||||
|
private enum ItemType {
|
||||||
|
TRACK, HEADER
|
||||||
|
}
|
||||||
|
|
||||||
|
private final LayoutInflater layoutInflater;
|
||||||
|
private int sharedWithMeIndex = -1;
|
||||||
|
|
||||||
|
public SectionResourceCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
|
||||||
|
super(context, layout, cursor, flags);
|
||||||
|
this.layoutInflater = LayoutInflater.from(context);
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
sharedWithMeIndex = getSharedWithMeIndex();
|
||||||
|
cursor.registerDataSetObserver(dataSetObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataSetObserver dataSetObserver = new DataSetObserver() {
|
||||||
|
@Override
|
||||||
|
public void onChanged() {
|
||||||
|
sharedWithMeIndex = getSharedWithMeIndex();
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInvalidated() {
|
||||||
|
sharedWithMeIndex = -1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
|
||||||
|
return super.getView(getCursorPosition(position), convertView, parent);
|
||||||
|
} else {
|
||||||
|
TextView textView;
|
||||||
|
if (convertView == null) {
|
||||||
|
textView = (TextView) layoutInflater.inflate(R.layout.track_list_header, parent, false);
|
||||||
|
} else {
|
||||||
|
textView = (TextView) convertView;
|
||||||
|
}
|
||||||
|
return textView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewTypeCount() {
|
||||||
|
return ItemType.values().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
int count = super.getCount();
|
||||||
|
return count != 0 && sharedWithMeIndex != -1 ? count + 1 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(int position) {
|
||||||
|
return getItemViewType(position) == ItemType.TRACK.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
|
||||||
|
return super.getItem(getCursorPosition(position));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
if (getItemViewType(position) == ItemType.TRACK.ordinal()) {
|
||||||
|
return super.getItemId(getCursorPosition(position));
|
||||||
|
}
|
||||||
|
return -1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
if (sharedWithMeIndex != -1 && sharedWithMeIndex == position) {
|
||||||
|
return ItemType.HEADER.ordinal();
|
||||||
|
}
|
||||||
|
return ItemType.TRACK.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor swapCursor(Cursor newCursor) {
|
||||||
|
if (getCursor() != null) {
|
||||||
|
getCursor().unregisterDataSetObserver(dataSetObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor oldCursor = super.swapCursor(newCursor);
|
||||||
|
if (newCursor != null) {
|
||||||
|
sharedWithMeIndex = getSharedWithMeIndex();
|
||||||
|
newCursor.registerDataSetObserver(dataSetObserver);
|
||||||
|
}
|
||||||
|
return oldCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Shared with me header index.
|
||||||
|
*/
|
||||||
|
private int getSharedWithMeIndex() {
|
||||||
|
int i = 0;
|
||||||
|
Cursor cursor = getCursor();
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
int index = cursor.getColumnIndex(TracksColumns.SHAREDWITHME);
|
||||||
|
do {
|
||||||
|
int sharedWithMe = cursor.getInt(index);
|
||||||
|
if (sharedWithMe == 1) {
|
||||||
|
// Returns the index where sharedWithMe == 1
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (cursor.moveToNext());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the underlying cursor position.
|
||||||
|
*
|
||||||
|
* @param position the requested position
|
||||||
|
*/
|
||||||
|
private int getCursorPosition(int position) {
|
||||||
|
if (sharedWithMeIndex != -1 && position > sharedWithMeIndex) {
|
||||||
|
return position - 1;
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,7 +66,6 @@ import android.support.v4.app.FragmentActivity;
|
|||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.support.v4.content.CursorLoader;
|
import android.support.v4.content.CursorLoader;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.widget.ResourceCursorAdapter;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
@@ -97,7 +96,8 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
private static final int GOOGLE_PLAY_SERVICES_REQUEST_CODE = 0;
|
private static final int GOOGLE_PLAY_SERVICES_REQUEST_CODE = 0;
|
||||||
private static final String[] PROJECTION = new String[] { TracksColumns._ID, TracksColumns.NAME,
|
private static final String[] PROJECTION = new String[] { TracksColumns._ID, TracksColumns.NAME,
|
||||||
TracksColumns.DESCRIPTION, TracksColumns.CATEGORY, TracksColumns.STARTTIME,
|
TracksColumns.DESCRIPTION, TracksColumns.CATEGORY, TracksColumns.STARTTIME,
|
||||||
TracksColumns.TOTALDISTANCE, TracksColumns.TOTALTIME, TracksColumns.ICON };
|
TracksColumns.TOTALDISTANCE, TracksColumns.TOTALTIME, TracksColumns.ICON,
|
||||||
|
TracksColumns.SHAREDWITHME};
|
||||||
|
|
||||||
// Callback when the trackRecordingServiceConnection binding changes.
|
// Callback when the trackRecordingServiceConnection binding changes.
|
||||||
private final Runnable bindChangedCallback = new Runnable() {
|
private final Runnable bindChangedCallback = new Runnable() {
|
||||||
@@ -180,7 +180,7 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
boolean isRecording = recordingTrackId
|
boolean isRecording = recordingTrackId
|
||||||
!= PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
!= PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
||||||
updateMenuItems(isRecording);
|
updateMenuItems(isRecording);
|
||||||
resourceCursorAdapter.notifyDataSetChanged();
|
sectionResourceCursorAdapter.notifyDataSetChanged();
|
||||||
trackController.update(isRecording, recordingTrackPaused);
|
trackController.update(isRecording, recordingTrackPaused);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -333,7 +333,7 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||||
private TrackController trackController;
|
private TrackController trackController;
|
||||||
private ListView listView;
|
private ListView listView;
|
||||||
private ResourceCursorAdapter resourceCursorAdapter;
|
private SectionResourceCursorAdapter sectionResourceCursorAdapter;
|
||||||
private TrackDataHub trackDataHub;
|
private TrackDataHub trackDataHub;
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
@@ -379,7 +379,7 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) {
|
sectionResourceCursorAdapter = new SectionResourceCursorAdapter(this, R.layout.list_item, null, 0) {
|
||||||
@Override
|
@Override
|
||||||
public void bindView(View view, Context context, Cursor cursor) {
|
public void bindView(View view, Context context, Cursor cursor) {
|
||||||
int idIndex = cursor.getColumnIndex(TracksColumns._ID);
|
int idIndex = cursor.getColumnIndex(TracksColumns._ID);
|
||||||
@@ -406,7 +406,7 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
totalDistance, startTimeDisplay, cursor.getString(descriptionIndex));
|
totalDistance, startTimeDisplay, cursor.getString(descriptionIndex));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
listView.setAdapter(resourceCursorAdapter);
|
listView.setAdapter(sectionResourceCursorAdapter);
|
||||||
ApiAdapterFactory.getApiAdapter()
|
ApiAdapterFactory.getApiAdapter()
|
||||||
.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
|
.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
|
||||||
|
|
||||||
@@ -414,17 +414,17 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
|
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
|
||||||
return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, null,
|
return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, null,
|
||||||
null, TracksColumns._ID + " DESC");
|
null, TracksColumns.SHAREDWITHME + " ASC, " + TracksColumns._ID + " DESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||||
resourceCursorAdapter.swapCursor(cursor);
|
sectionResourceCursorAdapter.swapCursor(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<Cursor> loader) {
|
public void onLoaderReset(Loader<Cursor> loader) {
|
||||||
resourceCursorAdapter.swapCursor(null);
|
sectionResourceCursorAdapter.swapCursor(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
trackDataHub = TrackDataHub.newInstance(this);
|
trackDataHub = TrackDataHub.newInstance(this);
|
||||||
@@ -462,7 +462,7 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
|
|||||||
// Update UI
|
// Update UI
|
||||||
boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
||||||
updateMenuItems(isRecording);
|
updateMenuItems(isRecording);
|
||||||
resourceCursorAdapter.notifyDataSetChanged();
|
sectionResourceCursorAdapter.notifyDataSetChanged();
|
||||||
trackController.update(isRecording, recordingTrackPaused);
|
trackController.update(isRecording, recordingTrackPaused);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,14 +161,18 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
context, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
|
context, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
|
||||||
String deletedIds[] = TextUtils.split(driveDeletedList, ";");
|
String deletedIds[] = TextUtils.split(driveDeletedList, ";");
|
||||||
for (String id : deletedIds) {
|
for (String id : deletedIds) {
|
||||||
File driveFile = drive.files().get(id).execute();
|
try {
|
||||||
if (SyncUtils.isInFolder(driveFile, folderId)) {
|
File driveFile = drive.files().get(id).execute();
|
||||||
if (!driveFile.getLabels().getTrashed()) {
|
if (SyncUtils.isInFolder(driveFile, folderId)) {
|
||||||
drive.files().trash(id).execute();
|
if (!driveFile.getLabels().getTrashed()) {
|
||||||
|
drive.files().trash(id).execute();
|
||||||
|
}
|
||||||
|
// if trashed, ignore
|
||||||
|
} else if (SyncUtils.isSharedWithMe(driveFile)) {
|
||||||
|
drive.files().delete(id).execute();
|
||||||
}
|
}
|
||||||
// if trashed, ignore
|
} catch (IOException e) {
|
||||||
} else if (SyncUtils.isSharedWithMe(driveFile)) {
|
// safe to ignore
|
||||||
drive.files().delete(id).execute();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PreferencesUtils.setString(
|
PreferencesUtils.setString(
|
||||||
|
|||||||
Reference in New Issue
Block a user