Update dependencies and removed integration code.

This commit is contained in:
Dennis Guse
2019-06-21 20:59:30 +02:00
parent 09798c95c2
commit 078533dd3f
57 changed files with 250 additions and 1189 deletions
Generated
-1
View File
@@ -1 +0,0 @@
MyTracks
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.4.0' classpath 'com.android.tools.build:gradle:3.4.1'
} }
} }
+1 -7
View File
@@ -21,14 +21,8 @@ android {
} }
dependencies { dependencies {
compile project(':myTracksLib') implementation project(':myTracksLib')
compile files('libs/antlib.jar') compile files('libs/antlib.jar')
compile files('libs/google-api-client-1.12.0-beta.jar')
compile files('libs/google-api-client-android-1.12.0-beta.jar')
compile files('libs/google-api-services-drive-v2-rev30-1.12.0-beta.jar')
compile files('libs/google-http-client-1.12.0-beta.jar')
compile files('libs/google-http-client-android-1.12.0-beta.jar')
compile files('libs/google-http-client-gson-1.12.0-beta.jar')
androidTestCompile files('libs/AndroidMockGenerator.jar') androidTestCompile files('libs/AndroidMockGenerator.jar')
androidTestCompile files('libs/robotium-solo-5.0.1.jar') androidTestCompile files('libs/robotium-solo-5.0.1.jar')
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,8 +15,6 @@
*/ */
package com.google.android.apps.mytracks.io.backup; package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
@@ -23,7 +23,6 @@ import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType; import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.content.WaypointCreationRequest; import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.GoogleLocationUtils; import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
@@ -1,10 +1,11 @@
package com.google.android.apps.mytracks.services.sensors; package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.util.Arrays;
public class PolarMessageParserTest extends TestCase { public class PolarMessageParserTest extends TestCase {
PolarMessageParser parser = new PolarMessageParser(); PolarMessageParser parser = new PolarMessageParser();
@@ -16,7 +17,7 @@ public class PolarMessageParserTest extends TestCase {
private byte[] buf; private byte[] buf;
public void setUp() { public void setUp() {
buf = ApiAdapterFactory.getApiAdapter().copyByteArray(originalBuf, 0, originalBuf.length); buf = Arrays.copyOfRange(originalBuf, 0, originalBuf.length);
} }
public void testIsValid() { public void testIsValid() {
@@ -1,7 +1,6 @@
package com.google.android.apps.mytracks.services.sensors; package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
@@ -16,9 +16,9 @@
package com.google.android.apps.mytracks; package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.TrackIconUtils; import com.google.android.apps.mytracks.util.TrackIconUtils;
import android.app.ActionBar;
import android.os.Bundle; import android.os.Bundle;
import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
@@ -39,26 +39,18 @@ public abstract class AbstractMyTracksActivity extends FragmentActivity {
// Set volume control stream for text to speech // Set volume control stream for text to speech
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM); setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
// Hide title must be before setContentView
if (hideTitle()) {
ApiAdapterFactory.getApiAdapter().hideTitle(this);
}
setContentView(getLayoutResId()); setContentView(getLayoutResId());
// Configure action bar must be after setContentView // Configure action bar must be after setContentView
if (configureActionBarHomeAsUp()) { if (configureActionBarHomeAsUp()) {
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this); ActionBar actionBar = this.getActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
} }
} }
/**
* Returns true to hide the title. Be default, do not hide the title.
*/
protected boolean hideTitle() {
return false;
}
/** /**
* Gets the layout resource id. * Gets the layout resource id.
*/ */
@@ -24,9 +24,22 @@ import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils; import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
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 android.widget.Toast; import android.widget.Toast;
import java.util.ArrayList;
/** /**
* An abstract class for the following common tasks across * An abstract class for the following common tasks across
* {@link TrackListActivity}, {@link TrackDetailActivity}, and * {@link TrackListActivity}, {@link TrackDetailActivity}, and
@@ -54,14 +67,115 @@ public abstract class AbstractSendToGoogleActivity extends AbstractMyTracksActiv
} }
} }
/** public static void configureListViewContextualMenu(final Activity activity, final ListView listView,
* Call when not able to get permission for a google service. final ContextualActionModeCallback contextualActionModeCallback) {
*/ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
private void onPermissionFailure() { listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
Toast.makeText(this, R.string.send_google_no_account_permission, Toast.LENGTH_LONG).show();
@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<Integer>();
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) {
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.getComponentName()));
searchView.setQueryRefinementEnabled(true);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// Hide and show trackController when search 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;
}
});
}
/**
* Delete tracks. * Delete tracks.
* *
* @param trackIds the track ids * @param trackIds the track ids
@@ -22,7 +22,6 @@ import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.content.WaypointsColumns; import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment; import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller; import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils; import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
@@ -119,7 +118,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
ApiAdapterFactory.getApiAdapter().invalidMenu(MarkerListActivity.this); MarkerListActivity.this.invalidateOptionsMenu();
} }
}); });
} }
@@ -192,8 +191,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
} }
}; };
listView.setAdapter(resourceCursorAdapter); listView.setAdapter(resourceCursorAdapter);
ApiAdapterFactory.getApiAdapter() AbstractSendToGoogleActivity.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
final long firstWaypointId = myTracksProviderUtils.getFirstWaypointId(trackId); final long firstWaypointId = myTracksProviderUtils.getFirstWaypointId(trackId);
getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() { getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@@ -226,7 +224,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
ApiAdapterFactory.getApiAdapter().invalidMenu(this); this.invalidateOptionsMenu();
} }
@Override @Override
@@ -245,7 +243,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
getMenuInflater().inflate(R.menu.marker_list, menu); getMenuInflater().inflate(R.menu.marker_list, menu);
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);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem, null); AbstractSendToGoogleActivity.configureSearchWidget(this, searchMenuItem, null);
return super.onCreateOptionsMenu(menu); return super.onCreateOptionsMenu(menu);
} }
@@ -266,7 +264,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.marker_list_search: case R.id.marker_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this); return false;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@@ -336,9 +334,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
@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) {
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(searchMenuItem)) { return true;
return true;
}
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
@@ -29,7 +29,6 @@ import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment.Del
import com.google.android.apps.mytracks.services.MyTracksLocationManager; import com.google.android.apps.mytracks.services.MyTracksLocationManager;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils; import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
@@ -39,7 +38,6 @@ import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtil
import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.accounts.Account;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -244,8 +242,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
} }
}; };
listView.setAdapter(arrayAdapter); listView.setAdapter(arrayAdapter);
ApiAdapterFactory.getApiAdapter() AbstractSendToGoogleActivity.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
handleIntent(getIntent()); handleIntent(getIntent());
} }
@@ -285,7 +282,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_list, menu); getMenuInflater().inflate(R.menu.search_list, menu);
searchMenuItem = menu.findItem(R.id.search_list_search); searchMenuItem = menu.findItem(R.id.search_list_search);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem, null); AbstractSendToGoogleActivity.configureSearchWidget(this, searchMenuItem, null);
return super.onCreateOptionsMenu(menu); return super.onCreateOptionsMenu(menu);
} }
@@ -293,7 +290,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.search_list_search: case R.id.search_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this); return false;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@@ -321,9 +318,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
@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) {
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(searchMenuItem)) { return true;
return true;
}
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
@@ -427,7 +422,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
@Override @Override
public void run() { public void run() {
arrayAdapter.clear(); arrayAdapter.clear();
ApiAdapterFactory.getApiAdapter().addAllToArrayAdapter(arrayAdapter, displayResults); arrayAdapter.addAll(displayResults);
} }
}); });
@@ -34,7 +34,6 @@ import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.exporter.SaveActivity; import com.google.android.apps.mytracks.io.file.exporter.SaveActivity;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.settings.SettingsActivity;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.CalorieUtils; import com.google.android.apps.mytracks.util.CalorieUtils;
import com.google.android.apps.mytracks.util.CalorieUtils.ActivityType; import com.google.android.apps.mytracks.util.CalorieUtils.ActivityType;
import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.FileUtils;
@@ -171,7 +170,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
ApiAdapterFactory.getApiAdapter().invalidMenu(TrackDetailActivity.this); TrackDetailActivity.this.invalidateOptionsMenu();
boolean isRecording = trackId == recordingTrackId; boolean isRecording = trackId == recordingTrackId;
trackController.update(isRecording, recordingTrackPaused); trackController.update(isRecording, recordingTrackPaused);
} }
@@ -246,8 +245,10 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
} }
// Set the background after all three tabs are added // Set the background after all three tabs are added
ApiAdapterFactory.getApiAdapter().setTabBackground(tabHost.getTabWidget()); for (int i = 0; i < tabHost.getTabWidget().getChildCount(); i++) {
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab_indicator_mytracks);
}
trackController = new TrackController( trackController = new TrackController(
this, trackRecordingServiceConnection, false, recordListener, stopListener); this, trackRecordingServiceConnection, false, recordListener, stopListener);
} }
@@ -269,7 +270,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
trackDataHub.loadTrack(trackId); trackDataHub.loadTrack(trackId);
// Update UI // Update UI
ApiAdapterFactory.getApiAdapter().invalidMenu(this); this.invalidateOptionsMenu();
boolean isRecording = trackId == recordingTrackId; boolean isRecording = trackId == recordingTrackId;
trackController.onResume(isRecording, recordingTrackPaused); trackController.onResume(isRecording, recordingTrackPaused);
} }
@@ -315,11 +316,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
return R.layout.track_detail; return R.layout.track_detail;
} }
@Override
protected boolean hideTitle() {
return true;
}
@Override @Override
protected void onHomeSelected() { protected void onHomeSelected() {
/* /*
@@ -347,9 +343,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
boolean isSharedWithMe = track != null ? track.isSharedWithMe() : true; boolean isSharedWithMe = track != null ? track.isSharedWithMe() : true;
menu.findItem(R.id.track_detail_edit).setVisible(!isSharedWithMe); menu.findItem(R.id.track_detail_edit).setVisible(!isSharedWithMe);
menu.findItem(R.id.track_detail_help_feedback).setTitle(
ApiAdapterFactory.getApiAdapter().isGoogleFeedbackAvailable() ? R.string.menu_help_feedback
: R.string.menu_help);
insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker); insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
insertPhotoMenuItem = menu.findItem(R.id.track_detail_insert_photo); insertPhotoMenuItem = menu.findItem(R.id.track_detail_insert_photo);
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks; package com.google.android.apps.mytracks;
import android.accounts.Account;
import android.app.Dialog; import android.app.Dialog;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.Context; import android.content.Context;
@@ -29,6 +28,7 @@ import android.os.Bundle;
import android.os.Looper; import android.os.Looper;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.StrictMode;
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;
@@ -59,7 +59,6 @@ import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.MyTracksLocationManager; import com.google.android.apps.mytracks.services.MyTracksLocationManager;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.settings.SettingsActivity;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.GoogleLocationUtils; import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils; import com.google.android.apps.mytracks.util.ListItemUtils;
@@ -173,7 +172,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
ApiAdapterFactory.getApiAdapter().invalidMenu(TrackListActivity.this); TrackListActivity.this.invalidateOptionsMenu();
getSupportLoaderManager().restartLoader(0, null, loaderCallbacks); getSupportLoaderManager().restartLoader(0, null, loaderCallbacks);
boolean isRecording = recordingTrackId boolean isRecording = recordingTrackId
!= PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
@@ -296,7 +295,15 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
ApiAdapterFactory.getApiAdapter().enableStrictMode(); Log.d(TAG, "Enabling strict mode");
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
} }
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
@@ -361,8 +368,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
} }
}; };
listView.setAdapter(sectionResourceCursorAdapter); listView.setAdapter(sectionResourceCursorAdapter);
ApiAdapterFactory.getApiAdapter() AbstractSendToGoogleActivity.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
.configureListViewContextualMenu(this, listView, contextualActionModeCallback);
getSupportLoaderManager().initLoader(0, null, loaderCallbacks); getSupportLoaderManager().initLoader(0, null, loaderCallbacks);
showStartupDialogs(); showStartupDialogs();
@@ -387,7 +393,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
super.onResume(); super.onResume();
// Update UI // Update UI
ApiAdapterFactory.getApiAdapter().invalidMenu(this); this.invalidateOptionsMenu();
getSupportLoaderManager().restartLoader(0, null, loaderCallbacks); getSupportLoaderManager().restartLoader(0, null, loaderCallbacks);
boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
trackController.onResume(isRecording, recordingTrackPaused); trackController.onResume(isRecording, recordingTrackPaused);
@@ -435,7 +441,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
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);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem, trackController); AbstractSendToGoogleActivity.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); aggregatedStatisticsMenuItem = menu.findItem(R.id.track_list_aggregated_statistics);
@@ -459,7 +465,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
Intent intent; Intent intent;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.track_list_search: case R.id.track_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this); return false;
case R.id.track_list_start_gps: case R.id.track_list_start_gps:
MyTracksLocationManager myTracksLocationManager = new MyTracksLocationManager( MyTracksLocationManager myTracksLocationManager = new MyTracksLocationManager(
this, Looper.myLooper(), false); this, Looper.myLooper(), false);
@@ -494,7 +500,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
} }
// Update menu after starting or stopping gps // Update menu after starting or stopping gps
ApiAdapterFactory.getApiAdapter().invalidMenu(this); this.invalidateOptionsMenu();
} }
myTracksLocationManager.close(); myTracksLocationManager.close();
return true; return true;
@@ -546,9 +552,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity implements F
@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) {
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(searchMenuItem)) { return true;
return true;
}
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.io.backup; package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.content.ContentTypeIds; import com.google.android.apps.mytracks.content.ContentTypeIds;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -133,7 +132,7 @@ public class PreferenceBackupHelper {
byte typeId = reader.readByte(); byte typeId = reader.readByte();
readAndSetPreference(name, typeId, reader, editor); readAndSetPreference(name, typeId, reader, editor);
} }
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -18,7 +18,6 @@ package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Sensor.SensorState; import com.google.android.apps.mytracks.content.Sensor.SensorState;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
@@ -161,11 +160,21 @@ public class BluetoothConnectionManager {
setName("ConnectThread-" + device.getName()); setName("ConnectThread-" + device.getName());
this.bluetoothDevice = device; this.bluetoothDevice = device;
BluetoothSocket tmp = null; BluetoothSocket tmp = null;
try { try {
tmp = ApiAdapterFactory.getApiAdapter().getBluetoothSocket(device); tmp = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(BluetoothConnectionManager.MY_TRACKS_UUID);
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Unable to get blueooth socket.", e); Log.d(TAG, "Unable to create insecure connection", e);
} }
if (tmp == null) {
try {
tmp = bluetoothDevice.createRfcommSocketToServiceRecord(BluetoothConnectionManager.MY_TRACKS_UUID);
} catch (IOException e) {
Log.e(TAG, "Unable to get blueooth socket.", e);
}
}
bluetoothSocket = tmp; bluetoothSocket = tmp;
} }
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.services.sensors; package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import java.util.Arrays; import java.util.Arrays;
@@ -62,7 +61,7 @@ public class ZephyrMessageParser implements MessageParser {
// 0x1A00316550003162 produces erroneous values for Cadence and needs // 0x1A00316550003162 produces erroneous values for Cadence and needs
// a workaround based on the stride counter. // a workaround based on the stride counter.
// Firmware values range from field 3 to 10 (inclusive) of the byte buffer. // Firmware values range from field 3 to 10 (inclusive) of the byte buffer.
byte[] hardwareFirmwareId = ApiAdapterFactory.getApiAdapter().copyByteArray(buffer, 3, 11); byte[] hardwareFirmwareId = Arrays.copyOfRange(buffer, 3, 11);
Sensor.SensorData.Builder cadence = Sensor.SensorData.newBuilder(); Sensor.SensorData.Builder cadence = Sensor.SensorData.newBuilder();
if (Arrays.equals(hardwareFirmwareId, CADENCE_BUG_FW_ID)) { if (Arrays.equals(hardwareFirmwareId, CADENCE_BUG_FW_ID)) {
@@ -18,9 +18,9 @@ package com.google.android.apps.mytracks.settings;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener; import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.ActionBar;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.preference.ListPreference; import android.preference.ListPreference;
@@ -45,7 +45,12 @@ public class AbstractSettingsActivity extends PreferenceActivity {
protected void onCreate(Bundle bundle) { protected void onCreate(Bundle bundle) {
super.onCreate(bundle); super.onCreate(bundle);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM); setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
ActionBar actionBar = this.getActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
PreferenceManager preferenceManager = getPreferenceManager(); PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setSharedPreferencesName(Constants.SETTINGS_NAME); preferenceManager.setSharedPreferencesName(Constants.SETTINGS_NAME);
@@ -1,47 +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 com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.services.sensors.BluetoothConnectionManager;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import java.io.IOException;
/**
* API level 10 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(10)
public class Api10Adapter extends Api9Adapter {
private static final String TAG = Api10Adapter.class.getSimpleName();
@Override
public BluetoothSocket getBluetoothSocket(BluetoothDevice bluetoothDevice) throws IOException {
try {
return bluetoothDevice.createInsecureRfcommSocketToServiceRecord(
BluetoothConnectionManager.MY_TRACKS_UUID);
} catch (IOException e) {
Log.d(TAG, "Unable to create insecure connection", e);
}
return bluetoothDevice.createRfcommSocketToServiceRecord(BluetoothConnectionManager.MY_TRACKS_UUID);
};
}
@@ -1,182 +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 com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.ContextualActionModeCallback;
import com.google.android.apps.mytracks.TrackController;
import com.google.android.maps.mytracks.R;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TabWidget;
import java.util.ArrayList;
import java.util.List;
/**
* API level 11 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(11)
public class Api11Adapter extends Api10Adapter {
@Override
public void hideTitle(Activity activity) {
// Do nothing
}
@Override
public void configureActionBarHomeAsUp(Activity activity) {
ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
@Override
public void configureListViewContextualMenu(final Activity activity, final ListView listView,
final ContextualActionModeCallback contextualActionModeCallback) {
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new 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<Integer>();
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;
}
});
}
@Override
public void configureSearchWidget(
Activity activity, MenuItem menuItem, final TrackController trackController) {
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.getComponentName()));
searchView.setQueryRefinementEnabled(true);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// Hide and show trackController when search widget has focus/no focus
if (trackController != null) {
if (hasFocus) {
trackController.hide();
} else {
trackController.show();
}
}
}
});
}
@Override
public boolean handleSearchMenuSelection(Activity activity) {
// Returns false to allow the platform to expand the search widget.
return false;
}
@Override
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items) {
arrayAdapter.addAll(items);
}
@Override
public void invalidMenu(Activity activity) {
activity.invalidateOptionsMenu();
}
@Override
public void setTabBackground(TabWidget tabWidget) {
for (int i = 0; i < tabWidget.getChildCount(); i++) {
tabWidget.getChildAt(i).setBackgroundResource(R.drawable.tab_indicator_mytracks);
}
}
@Override
public boolean hasDialogTitleDivider() {
return true;
}
@Override
public void setTitleAndSubtitle(Activity activity, String title, String subtitle) {
ActionBar actionBar = activity.getActionBar();
actionBar.setTitle(title);
actionBar.setSubtitle(subtitle);
}
}
@@ -1,85 +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 com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.TrackController;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.view.MenuItem;
import android.widget.SearchView;
/**
* API level 14 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(14)
public class Api14Adapter extends Api11Adapter {
@Override
public void configureActionBarHomeAsUp(Activity activity) {
ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
@Override
public void configureSearchWidget(
Activity activity, final MenuItem menuItem, TrackController trackController) {
super.configureSearchWidget(activity, menuItem, trackController);
SearchView searchView = (SearchView) menuItem.getActionView();
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
public boolean handleSearchKey(MenuItem menuItem) {
menuItem.expandActionView();
return true;
}
@Override
public boolean isGoogleFeedbackAvailable() {
return true;
}
}
@@ -1,60 +0,0 @@
/*
* 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.util;
import com.google.android.apps.mytracks.widgets.TrackWidgetProvider;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
/**
* API level 16 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(16)
public class Api16Adapter extends Api14Adapter {
private static final String APP_WIDGET_SIZE_KEY = "app_widget_size_key";
@Override
public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) {
Bundle bundle = appWidgetManager.getAppWidgetOptions(appWidgetId);
return bundle.getInt(APP_WIDGET_SIZE_KEY, getAppWidgetSizeDefault(bundle));
}
@SuppressWarnings("unused")
protected int getAppWidgetSizeDefault(Bundle bundle) {
return TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE;
}
@Override
public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) {
Bundle bundle = new Bundle();
bundle.putInt(APP_WIDGET_SIZE_KEY, size);
appWidgetManager.updateAppWidgetOptions(appWidgetId, bundle);
}
@Override
public void removeGlobalLayoutListener(
ViewTreeObserver observer, OnGlobalLayoutListener listener) {
observer.removeOnGlobalLayoutListener(listener);
}
}
@@ -1,41 +0,0 @@
/*
* 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.util;
import com.google.android.apps.mytracks.widgets.TrackWidgetProvider;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.os.Bundle;
/**
* API level 17 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(17)
public class Api17Adapter extends Api16Adapter {
@Override
protected int getAppWidgetSizeDefault(Bundle bundle) {
boolean isKeyguard = bundle.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1)
== AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
return isKeyguard ? TrackWidgetProvider.KEYGUARD_DEFAULT_SIZE
: TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE;
}
}
@@ -1,33 +0,0 @@
/*
* 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.util;
import android.annotation.TargetApi;
/**
* API level 19 specific implementation of the {@link ApiAdapter}.
*
* @author Jimmy Shih
*/
@TargetApi(19)
public class Api19Adapter extends Api17Adapter {
@Override
public boolean hasLocationMode() {
return true;
}
}
@@ -1,195 +0,0 @@
/*
* 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.
*/
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.ContextualActionModeCallback;
import com.google.android.apps.mytracks.TrackController;
import com.google.android.apps.mytracks.services.sensors.BluetoothConnectionManager;
import com.google.android.apps.mytracks.widgets.TrackWidgetProvider;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.ApacheHttpTransport;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences.Editor;
import android.util.Log;
import android.view.MenuItem;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TabWidget;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
/**
* API level 8 specific implementation of the {@link ApiAdapter}.
*
* @author Bartlomiej Niechwiej
*/
public class Api8Adapter implements ApiAdapter {
private static final String TAG = Api8Adapter.class.getSimpleName();
@Override
public void applyPreferenceChanges(Editor editor) {
editor.commit();
}
@Override
public void enableStrictMode() {
// Not supported
}
@Override
public byte[] copyByteArray(byte[] input, int start, int end) {
int length = end - start;
byte[] output = new byte[length];
System.arraycopy(input, start, output, 0, length);
return output;
}
@Override
public HttpTransport getHttpTransport() {
return new ApacheHttpTransport();
}
@Override
public boolean isGeoCoderPresent() {
return true;
}
@Override
public boolean revertMenuIconColor() {
return true;
}
@Override
public BluetoothSocket getBluetoothSocket(BluetoothDevice bluetoothDevice) throws IOException {
try {
Class<? extends BluetoothDevice> c = bluetoothDevice.getClass();
Method insecure = c.getMethod("createInsecureRfcommSocket", Integer.class);
insecure.setAccessible(true);
return (BluetoothSocket) insecure.invoke(bluetoothDevice, 1);
} catch (SecurityException e) {
Log.d(TAG, "Unable to create insecure connection", e);
} catch (NoSuchMethodException e) {
Log.d(TAG, "Unable to create insecure connection", e);
} catch (IllegalArgumentException e) {
Log.d(TAG, "Unable to create insecure connection", e);
} catch (IllegalAccessException e) {
Log.d(TAG, "Unable to create insecure connection", e);
} catch (InvocationTargetException e) {
Log.d(TAG, "Unable to create insecure connection", e);
}
return bluetoothDevice.createRfcommSocketToServiceRecord(
BluetoothConnectionManager.MY_TRACKS_UUID);
}
@Override
public void hideTitle(Activity activity) {
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
@Override
public void configureActionBarHomeAsUp(Activity activity) {
// Do nothing
}
@Override
public void configureListViewContextualMenu(Activity activity, ListView listView,
ContextualActionModeCallback contextualActionModeCallback) {
activity.registerForContextMenu(listView);
}
@Override
public void configureSearchWidget(
Activity activity, MenuItem menuItem, TrackController trackController) {
// Do nothing
}
@Override
public boolean handleSearchMenuSelection(Activity activity) {
activity.onSearchRequested();
return true;
}
@Override
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items) {
for (T item : items) {
arrayAdapter.add(item);
}
}
@Override
public void invalidMenu(Activity activity) {
// Do nothing
}
@Override
public void setTabBackground(TabWidget tabWidget) {
// Do nothing
}
@Override
public boolean hasDialogTitleDivider() {
return false;
}
@Override
public void setTitleAndSubtitle(Activity activity, String title, String subtitle) {
activity.setTitle(title + " " + subtitle);
}
@Override
public boolean handleSearchKey(MenuItem menuItem) {
// Return false and allow the framework to handle the search key.
return false;
}
@Override
public boolean isGoogleFeedbackAvailable() {
return false;
}
@Override
public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) {
return TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE;
}
@Override
public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) {
// Do nothing
}
@SuppressWarnings("deprecation")
@Override
public void removeGlobalLayoutListener(
ViewTreeObserver observer, OnGlobalLayoutListener listener) {
observer.removeGlobalOnLayoutListener(listener);
}
@Override
public boolean hasLocationMode() {
return false;
}
}
@@ -1,77 +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 com.google.android.apps.mytracks.util;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import android.annotation.TargetApi;
import android.content.SharedPreferences.Editor;
import android.location.Geocoder;
import android.os.StrictMode;
import android.util.Log;
import java.util.Arrays;
/**
* API level 9 specific implementation of the {@link ApiAdapter}.
*
* @author Rodrigo Damazio
*/
@TargetApi(9)
public class Api9Adapter extends Api8Adapter {
private static final String TAG = Api9Adapter.class.getSimpleName();
@Override
public void applyPreferenceChanges(Editor editor) {
// Apply asynchronously
editor.apply();
}
@Override
public void enableStrictMode() {
Log.d(TAG, "Enabling strict mode");
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
}
@Override
public byte[] copyByteArray(byte[] input, int start, int end) {
return Arrays.copyOfRange(input, start, end);
}
@Override
public HttpTransport getHttpTransport() {
return new NetHttpTransport();
}
@Override
public boolean isGeoCoderPresent() {
return Geocoder.isPresent();
}
@Override
public boolean revertMenuIconColor() {
return false;
}
}
@@ -1,256 +0,0 @@
/*
* 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.
*/
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.ContextualActionModeCallback;
import com.google.android.apps.mytracks.TrackController;
import com.google.api.client.http.HttpTransport;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences;
import android.view.MenuItem;
import android.view.ViewTreeObserver;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TabWidget;
import java.io.IOException;
import java.util.List;
/**
* A set of methods that may be implemented differently depending on the Android
* API level.
*
* @author Bartlomiej Niechwiej
*/
public interface ApiAdapter {
/**
* Applies all the changes done to a given preferences editor. Changes may or
* may not be applied immediately.
* <p>
* Due to changes in API level 9.
*
* @param editor the editor
*/
public void applyPreferenceChanges(SharedPreferences.Editor editor);
/**
* Enables strict mode where supported, only if this is a development build.
* <p>
* Due to changes in API level 9.
*/
public void enableStrictMode();
/**
* Copies elements from an input byte array into a new byte array, from
* indexes start (inclusive) to end (exclusive). The end index must be less
* than or equal to the input length.
* <p>
* Due to changes in API level 9.
*
* @param input the input byte array
* @param start the start index
* @param end the end index
* @return a new array containing elements from the input byte array.
*/
public byte[] copyByteArray(byte[] input, int start, int end);
/**
* Gets a {@link HttpTransport}.
* <p>
* Due to changes in API level 9.
*/
public HttpTransport getHttpTransport();
/**
* Returns true if GeoCoder is present.
* <p>
* Due to changes in API level 9.
*/
public boolean isGeoCoderPresent();
/**
* Returns true to revert menu icon color.
* <p>
* Due to changes in API level 9.
*/
public boolean revertMenuIconColor();
/**
* Gets a {@link BluetoothSocket}.
* <p>
* Due to changes in API level 10.
*
* @param bluetoothDevice
*/
public BluetoothSocket getBluetoothSocket(BluetoothDevice bluetoothDevice) throws IOException;
/**
* Hides the title. If the platform supports the action bar, do nothing.
* Ideally, with the action bar, we would like to collapse the navigation tabs
* into the action bar. However, collapsing is not supported by the
* compatibility library.
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
*/
public void hideTitle(Activity activity);
/**
* Configures the action bar with the Home button as an Up button. If the
* platform doesn't support the action bar, do nothing.
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
*/
public void configureActionBarHomeAsUp(Activity activity);
/**
* Configures the list view context menu.
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
* @param listView the list view
* @param contextualActionModeCallback the callback when an item is selected
* in the contextual action mode
*/
public void configureListViewContextualMenu(Activity activity, ListView listView,
ContextualActionModeCallback contextualActionModeCallback);
/**
* Configures the search widget.
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
* @param menuItem the search menu item
* @param trackController the track controller to hide/show when search widget
* is expanded/collapsed. Can be null
*/
public void configureSearchWidget(
Activity activity, MenuItem menuItem, TrackController trackController);
/**
* Handles the search menu selection. Returns true if handled.
* <p>
* Due to changes in API level 11.
*
* @param activity the activity
*/
public boolean handleSearchMenuSelection(Activity activity);
/**
* Adds all items to an array adapter.
* <p>
* Due to changes in API level 11.
*
* @param arrayAdapter the array adapter
* @param items list of items
*/
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items);
/**
* Invalidates the menu.
* <p>
* Due to changes in API level 11.
*/
public void invalidMenu(Activity activity);
/**
* Sets the tab background.
* <p>
* Due to changes in API level 11.
*
* @param tabWidget the tab widget
*/
public void setTabBackground(TabWidget tabWidget);
/**
* Returns true if has dialog title divider.
* <p>
* Due to changes in API level 11.
*/
public boolean hasDialogTitleDivider();
/**
* Sets title and subtitle.
* <p>
* Due to changes in API level 11;
*/
public void setTitleAndSubtitle(Activity activity, String title, String subtitle);
/**
* Handles the search key press. Returns true if handled.
* <p>
* Due to changes in API level 14.
*
* @param menu the search menu
*/
public boolean handleSearchKey(MenuItem menu);
/**
* Returns true if Google Feedback is available.
* <p>
* Due to changes in ApI level 14.
*/
public boolean isGoogleFeedbackAvailable();
/**
* Gets the app widget size.
* <p>
* Due to changes in API level 16.
*
* @param appWidgetManager the app widget manager
* @param appWidgetId the app widget id
*/
public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId);
/**
* Sets the app widget size.
* <p>
* Due to changes in API level 16.
*
* @param appWidgetManager the app widget manager.
* @param appWidgetId the app widgit id
* @param size the size
*/
public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size);
/**
* Removes the global layout listener.
* <p>
* Due to changes in API level 16.
*
* @param observer the observer
* @param listener the listener
*/
public void removeGlobalLayoutListener(
ViewTreeObserver observer, ViewTreeObserver.OnGlobalLayoutListener listener);
/**
* Returns true if has location mode.
* <p>
* Due to changes in API level 19.
*/
public boolean hasLocationMode();
}
@@ -1,54 +0,0 @@
/*
* 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.
*/
package com.google.android.apps.mytracks.util;
import android.os.Build;
/**
* A factory to get the {@link ApiAdapter} for the current device.
*
* @author Rodrigo Damazio
*/
public class ApiAdapterFactory {
private static ApiAdapter apiAdapter;
/**
* Gets the {@link ApiAdapter} for the current device.
*/
public static ApiAdapter getApiAdapter() {
if (apiAdapter == null) {
if (Build.VERSION.SDK_INT >= 19) {
apiAdapter = new Api19Adapter();
} else if (Build.VERSION.SDK_INT >= 17) {
apiAdapter = new Api17Adapter();
} else if (Build.VERSION.SDK_INT >= 16) {
apiAdapter = new Api16Adapter();
} else if (Build.VERSION.SDK_INT >= 14) {
apiAdapter = new Api14Adapter();
} else if (Build.VERSION.SDK_INT >= 11) {
apiAdapter = new Api11Adapter();
} else if (Build.VERSION.SDK_INT >= 10) {
apiAdapter = new Api10Adapter();
} else if (Build.VERSION.SDK_INT >= 9) {
apiAdapter = new Api9Adapter();
} else {
apiAdapter = new Api8Adapter();
}
}
return apiAdapter;
}
}
@@ -127,36 +127,34 @@ public class DialogUtils {
* @param dialog the dialog * @param dialog the dialog
*/ */
public static void setDialogTitleDivider(Context context, Dialog dialog) { public static void setDialogTitleDivider(Context context, Dialog dialog) {
if (ApiAdapterFactory.getApiAdapter().hasDialogTitleDivider()) { try {
try { ViewGroup decorView = (ViewGroup) dialog.getWindow().getDecorView();
ViewGroup decorView = (ViewGroup) dialog.getWindow().getDecorView(); if (decorView == null) {
if (decorView == null) { return;
return;
}
FrameLayout windowContentView = (FrameLayout) decorView.getChildAt(0);
if (windowContentView == null) {
return;
}
FrameLayout contentView = (FrameLayout) windowContentView.getChildAt(0);
if (contentView == null) {
return;
}
LinearLayout parentPanel = (LinearLayout) contentView.getChildAt(0);
if (parentPanel == null) {
return;
}
LinearLayout topPanel = (LinearLayout) parentPanel.getChildAt(0);
if (topPanel == null) {
return;
}
View titleDivider = topPanel.getChildAt(2);
if (titleDivider == null) {
return;
}
titleDivider.setBackgroundColor(context.getResources().getColor(R.color.holo_orange_dark));
} catch (Exception e) {
// Can safely ignore
} }
FrameLayout windowContentView = (FrameLayout) decorView.getChildAt(0);
if (windowContentView == null) {
return;
}
FrameLayout contentView = (FrameLayout) windowContentView.getChildAt(0);
if (contentView == null) {
return;
}
LinearLayout parentPanel = (LinearLayout) contentView.getChildAt(0);
if (parentPanel == null) {
return;
}
LinearLayout topPanel = (LinearLayout) parentPanel.getChildAt(0);
if (topPanel == null) {
return;
}
View titleDivider = topPanel.getChildAt(2);
if (titleDivider == null) {
return;
}
titleDivider.setBackgroundColor(context.getResources().getColor(R.color.holo_orange_dark));
} catch (Exception e) {
// Can safely ignore
} }
} }
} }
@@ -75,9 +75,7 @@ public class GoogleLocationUtils {
* @param context the context * @param context the context
*/ */
public static String getGpsDisabledMessage(Context context) { public static String getGpsDisabledMessage(Context context) {
int id = ApiAdapterFactory.getApiAdapter().hasLocationMode() ? R.string.gps_disabled_location_mode return context.getString(R.string.gps_disabled_location_mode, getLocationSettingsName(context));
: R.string.gps_disabled;
return context.getString(id, getLocationSettingsName(context));
} }
/** /**
@@ -86,9 +84,7 @@ public class GoogleLocationUtils {
* @param context the context * @param context the context
*/ */
public static String getGpsDisabledMyLocationMessage(Context context) { public static String getGpsDisabledMyLocationMessage(Context context) {
int id = ApiAdapterFactory.getApiAdapter().hasLocationMode() ? R.string.gps_disabled_my_location_location_mode return context.getString(R.string.gps_disabled_my_location_location_mode, getLocationSettingsName(context));
: R.string.gps_disabled_my_location;
return context.getString(id, getLocationSettingsName(context));
} }
/** /**
@@ -113,13 +109,7 @@ public class GoogleLocationUtils {
if (!isEnforceable(context)) { if (!isEnforceable(context)) {
return true; return true;
} }
if (!ApiAdapterFactory.getApiAdapter().hasLocationMode()) { return getUseLocationForServices(context) != USE_LOCATION_FOR_SERVICES_OFF;
// Before KitKat
return getUseLocationForServices(context) == USE_LOCATION_FOR_SERVICES_ON;
} else {
// KitKat+
return getUseLocationForServices(context) != USE_LOCATION_FOR_SERVICES_OFF;
}
} }
/** /**
@@ -142,13 +132,8 @@ public class GoogleLocationUtils {
if (!isEnforceable(context)) { if (!isEnforceable(context)) {
return false; return false;
} }
if (!ApiAdapterFactory.getApiAdapter().hasLocationMode()) {
// Before KitKat return getUseLocationForServices(context) == USE_LOCATION_FOR_SERVICES_OFF;
return true;
} else {
// KitKat+
return getUseLocationForServices(context) == USE_LOCATION_FOR_SERVICES_OFF;
}
} }
/** /**
@@ -149,7 +149,7 @@ public class PreferencesUtils {
Constants.SETTINGS_NAME, Context.MODE_PRIVATE); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit(); Editor editor = sharedPreferences.edit();
editor.putBoolean(getKey(context, keyId), value); editor.putBoolean(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -178,7 +178,7 @@ public class PreferencesUtils {
Constants.SETTINGS_NAME, Context.MODE_PRIVATE); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit(); Editor editor = sharedPreferences.edit();
editor.putInt(getKey(context, keyId), value); editor.putInt(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -207,7 +207,7 @@ public class PreferencesUtils {
Constants.SETTINGS_NAME, Context.MODE_PRIVATE); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit(); Editor editor = sharedPreferences.edit();
editor.putFloat(getKey(context, keyId), value); editor.putFloat(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -235,7 +235,7 @@ public class PreferencesUtils {
Constants.SETTINGS_NAME, Context.MODE_PRIVATE); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit(); Editor editor = sharedPreferences.edit();
editor.putLong(getKey(context, keyId), value); editor.putLong(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -264,7 +264,7 @@ public class PreferencesUtils {
Constants.SETTINGS_NAME, Context.MODE_PRIVATE); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit(); Editor editor = sharedPreferences.edit();
editor.putString(getKey(context, keyId), value); editor.putString(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); editor.apply();
} }
/** /**
@@ -226,12 +226,10 @@ public class TrackIconUtils {
* @param menu the menu * @param menu the menu
*/ */
public static void setMenuIconColor(Menu menu) { public static void setMenuIconColor(Menu menu) {
if (ApiAdapterFactory.getApiAdapter().revertMenuIconColor()) { int size = menu.size();
int size = menu.size(); for (int i = 0; i < size; i++) {
for (int i = 0; i < size; i++) { MenuItem menuitem = menu.getItem(i);
MenuItem menuitem = menu.getItem(i); revertMenuIconColor(menuitem);
revertMenuIconColor(menuitem);
}
} }
} }
@@ -241,9 +239,7 @@ public class TrackIconUtils {
* @param menuitem the menu item * @param menuitem the menu item
*/ */
public static void setMenuIconColor(MenuItem menuitem) { public static void setMenuIconColor(MenuItem menuitem) {
if (ApiAdapterFactory.getApiAdapter().revertMenuIconColor()) { revertMenuIconColor(menuitem);
revertMenuIconColor(menuitem);
}
} }
/** /**
@@ -91,7 +91,7 @@ public class TrackNameUtils {
* @param location the location * @param location the location
*/ */
private static String getReverseGeoCoding(Context context, Location location) { private static String getReverseGeoCoding(Context context, Location location) {
if (location == null || !ApiAdapterFactory.getApiAdapter().isGeoCoderPresent()) { if (location == null || !Geocoder.isPresent()) {
return null; return null;
} }
Geocoder geocoder = new Geocoder(context); Geocoder geocoder = new Geocoder(context);
@@ -22,7 +22,6 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.services.ControlRecordingService; import com.google.android.apps.mytracks.services.ControlRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
@@ -55,6 +54,8 @@ public class TrackWidgetProvider extends AppWidgetProvider {
public static final int KEYGUARD_DEFAULT_SIZE = 1; public static final int KEYGUARD_DEFAULT_SIZE = 1;
public static final int HOME_SCREEN_DEFAULT_SIZE = 2; public static final int HOME_SCREEN_DEFAULT_SIZE = 2;
private static final String APP_WIDGET_SIZE_KEY = "app_widget_size_key";
private static final int TWO_CELLS = 110; private static final int TWO_CELLS = 110;
private static final int THREE_CELLS = 180; private static final int THREE_CELLS = 180;
private static final int FOUR_CELLS = 250; private static final int FOUR_CELLS = 250;
@@ -124,9 +125,13 @@ public class TrackWidgetProvider extends AppWidgetProvider {
newSize = 1; newSize = 1;
} }
} }
int size = ApiAdapterFactory.getApiAdapter().getAppWidgetSize(appWidgetManager, appWidgetId); int size = getAppWidgetSize(appWidgetManager, appWidgetId);
if (size != newSize) { if (size != newSize) {
ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, newSize); Bundle bundle = new Bundle();
bundle.putInt(APP_WIDGET_SIZE_KEY, size);
appWidgetManager.updateAppWidgetOptions(appWidgetId, bundle);
updateAppWidget(context, appWidgetManager, appWidgetId, -1L); updateAppWidget(context, appWidgetManager, appWidgetId, -1L);
} }
} }
@@ -142,7 +147,7 @@ public class TrackWidgetProvider extends AppWidgetProvider {
*/ */
public static void updateAppWidget( public static void updateAppWidget(
Context context, AppWidgetManager appWidgetManager, int appWidgetId, long trackId) { Context context, AppWidgetManager appWidgetManager, int appWidgetId, long trackId) {
int size = ApiAdapterFactory.getApiAdapter().getAppWidgetSize(appWidgetManager, appWidgetId); int size = getAppWidgetSize(appWidgetManager, appWidgetId);
RemoteViews remoteViews = getRemoteViews(context, trackId, size); RemoteViews remoteViews = getRemoteViews(context, trackId, size);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
} }
@@ -233,6 +238,17 @@ public class TrackWidgetProvider extends AppWidgetProvider {
return remoteViews; return remoteViews;
} }
/**
* Gets the app widget size.
*
* @param appWidgetManager the app widget manager
* @param appWidgetId the app widget id
*/
private static int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) {
Bundle bundle = appWidgetManager.getAppWidgetOptions(appWidgetId);
return bundle.getInt(APP_WIDGET_SIZE_KEY, HOME_SCREEN_DEFAULT_SIZE);
}
/** /**
* Sets a widget item. * Sets a widget item.
* *