- ApiFeatures.isAudioFocusSupported
- ApiFeatures.hasBackup
- ApiFeatures.useNetHttpTransport
into the appropriate ApiLevelAdapter.

Do not plan to move
- ApiFeatures.hasBluetoothDeviceCreateInsecureRfcommSocketToServiceRecord
- ApiFeatures.canReuseSQLiteQueryBuilder
- ApiFeatures.hasTextToSpeech
This commit is contained in:
Jimmy Shih
2011-10-14 16:09:09 -07:00
parent c5deb1d3b7
commit d19f647d99
11 changed files with 137 additions and 101 deletions
@@ -93,7 +93,7 @@ public class SettingsActivity extends PreferenceActivity {
preferenceManager.setSharedPreferencesMode(0);
// Set up automatic preferences backup
backupListener = BackupPreferencesListener.create(this, apiFeatures);
backupListener = apiFeatures.getApiAdapter().getBackupPreferencesListener(this);
preferences = preferenceManager.getSharedPreferences();
preferences.registerOnSharedPreferenceChangeListener(backupListener);
@@ -41,8 +41,6 @@ import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.util.Strings;
import android.app.Activity;
@@ -140,8 +138,7 @@ public class SendToFusionTables implements Runnable {
this.stringUtils = new StringUtils(context);
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
HttpTransport transport = ApiFeatures.getInstance().useNetHttpTransport()
? new NetHttpTransport() : new ApacheHttpTransport();
HttpTransport transport = ApiFeatures.getInstance().getApiAdapter().getHttpTransport();
httpRequestFactory = transport.createRequestFactory(new MethodOverride());
}
@@ -15,63 +15,13 @@
*/
package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.util.ApiFeatures;
import android.app.backup.BackupManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
/**
* Shared preferences listener which notifies the backup system about new data
* being available for backup.
* This class is API-version-safe and will provide a dummy implementation if
* the device doesn't support backup services.
*
* @author Rodrigo Damazio
*/
public abstract class BackupPreferencesListener
implements OnSharedPreferenceChangeListener {
/**
* Real implementation of the listener, which calls the {@link BackupManager}.
*/
private static class BackupPreferencesListenerImpl
extends BackupPreferencesListener {
private final BackupManager backupManager;
public BackupPreferencesListenerImpl(Context context) {
this.backupManager = new BackupManager(context);
}
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
backupManager.dataChanged();
}
}
/**
* Dummy implementation of the listener which does nothing.
*/
private static class DummyBackupPreferencesListener
extends BackupPreferencesListener {
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
// Do nothing
}
}
/**
* Creates and returns a proper instance of the listener for this device.
*/
public static BackupPreferencesListener create(
Context context, ApiFeatures apiFeatures) {
if (apiFeatures.hasBackup()) {
return new BackupPreferencesListenerImpl(context);
} else {
return new DummyBackupPreferencesListener();
}
}
public abstract class BackupPreferencesListener implements OnSharedPreferenceChangeListener {
}
@@ -0,0 +1,40 @@
/*
* Copyright 2011 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.io.backup;
import android.app.backup.BackupManager;
import android.content.Context;
import android.content.SharedPreferences;
/**
* Implementation of {@link BackupPreferencesListener} that calls the
* {@link BackupManager}.
*
* @author Jimmy Shih
*/
public class BackupPreferencesListenerImpl extends BackupPreferencesListener {
private final BackupManager backupManager;
public BackupPreferencesListenerImpl(Context context) {
this.backupManager = new BackupManager(context);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
backupManager.dataChanged();
}
}
@@ -37,11 +37,7 @@ public class StatusAnnouncerFactory implements PeriodicTaskFactory {
@Override
public PeriodicTask create(Context context) {
if (hasTts) {
if (ApiFeatures.getInstance().isAudioFocusSupported()) {
return new FroyoStatusAnnouncerTask(context);
} else {
return new StatusAnnouncerTask(context);
}
return ApiFeatures.getInstance().getApiAdapter().getPeriodicTask(context);
} else {
return null;
}
@@ -16,11 +16,7 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.Constants;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import android.bluetooth.BluetoothDevice;
import android.os.Build;
import android.util.Log;
@@ -71,6 +67,8 @@ public class ApiFeatures {
// load the class when supported.
if (getApiLevel() >= 9) {
apiLevelAdapter = new ApiLevel9Adapter();
} else if (getApiLevel() >= 8) {
apiLevelAdapter = new ApiLevel8Adapter();
} else if (getApiLevel() >= 5) {
apiLevelAdapter = new ApiLevel5Adapter();
} else {
@@ -107,35 +105,11 @@ public class ApiFeatures {
return getApiLevel() >= 5;
}
// API Level 8 Changes
public boolean isAudioFocusSupported() {
return getApiLevel() >= 8;
}
/**
* Returns whether cloud backup (a.k.a. Froyo backup) is available.
*/
public boolean hasBackup() {
return getApiLevel() >= 8;
}
// API Level 9 Changes
/**
* Returns true if {@link NetHttpTransport} should be used rather than
* {@link ApacheHttpTransport}. See {@link HttpTransport} for more info.
*/
public boolean useNetHttpTransport() {
return getApiLevel() >= 9;
}
// API Level 10 changes
/**
* Returns true if
* {@link BluetoothDevice#createInsecureRfcommSocketToServiceRecord} is
* available.
* Returns true if BluetoothDevice.createInsecureRfcommSocketToServiceRecord
* is available.
*/
public boolean hasBluetoothDeviceCreateInsecureRfcommSocketToServiceRecord() {
return getApiLevel() >= 10;
@@ -17,9 +17,17 @@ package com.google.android.apps.mytracks.util;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
import com.google.android.apps.mytracks.services.tasks.PeriodicTask;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerTask;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.ApacheHttpTransport;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
@@ -52,6 +60,22 @@ public class ApiLevel3Adapter implements ApiLevelAdapter {
notificationManager.cancel(id);
}
}
@Override
public PeriodicTask getPeriodicTask(Context context) {
return new StatusAnnouncerTask(context);
}
@Override
public BackupPreferencesListener getBackupPreferencesListener(Context context) {
return new BackupPreferencesListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// Do nothing
}
};
}
private void setServiceForeground(Service service, boolean foreground) {
// setForeground has been completely removed in API level 11, so we use reflection.
@@ -93,4 +117,9 @@ public class ApiLevel3Adapter implements ApiLevelAdapter {
public DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) {
return new DecimalFormatSymbols(locale);
}
@Override
public HttpTransport getHttpTransport() {
return new ApacheHttpTransport();
}
}
@@ -0,0 +1,26 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListenerImpl;
import com.google.android.apps.mytracks.services.tasks.FroyoStatusAnnouncerTask;
import com.google.android.apps.mytracks.services.tasks.PeriodicTask;
import android.content.Context;
/**
* API level 8 specific implementation of the {@link ApiLevelAdapter}.
*
* @author Jimmy Shih
*/
public class ApiLevel8Adapter extends ApiLevel5Adapter {
@Override
public PeriodicTask getPeriodicTask(Context context) {
return new FroyoStatusAnnouncerTask(context);
}
@Override
public BackupPreferencesListener getBackupPreferencesListener(Context context) {
return new BackupPreferencesListenerImpl(context);
}
}
@@ -1,6 +1,8 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.Constants;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import android.content.SharedPreferences.Editor;
import android.os.StrictMode;
@@ -15,7 +17,7 @@ import java.util.Locale;
*
* @author Rodrigo Damazio
*/
public class ApiLevel9Adapter extends ApiLevel5Adapter {
public class ApiLevel9Adapter extends ApiLevel8Adapter {
@Override
public void applyPreferenceChanges(Editor editor) {
@@ -46,4 +48,9 @@ public class ApiLevel9Adapter extends ApiLevel5Adapter {
public DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) {
return DecimalFormatSymbols.getInstance(locale);
}
@Override
public HttpTransport getHttpTransport() {
return new NetHttpTransport();
}
}
@@ -15,9 +15,14 @@
*/
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
import com.google.android.apps.mytracks.services.tasks.PeriodicTask;
import com.google.api.client.http.HttpTransport;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import java.text.DecimalFormatSymbols;
@@ -58,6 +63,20 @@ public interface ApiLevelAdapter {
void stopForeground(Service service, NotificationManager notificationManager,
int id);
/**
* Gets a {@link PeriodicTask}.
*
* Due to changes in API level 8.
*/
PeriodicTask getPeriodicTask(Context context);
/**
* Gets a {@link BackupPreferencesListener}.
*
* Due to changes in API level 8.
*/
BackupPreferencesListener getBackupPreferencesListener(Context context);
/**
* Applies all changes done to the given preferences editor.
* Changes may or may not be applied immediately.
@@ -97,4 +116,11 @@ public interface ApiLevelAdapter {
* @return a new instance of {@link DecimalFormatSymbols}
*/
DecimalFormatSymbols getDecimalFormatSymbols(Locale locale);
/**
* Gets a {@link HttpTransport}.
*
* Due to changes in API level 9.
*/
HttpTransport getHttpTransport();
}
@@ -47,15 +47,6 @@ public class ApiFeaturesTest extends TestCase {
features = new TestableApiFeatures();
}
public void testHasBackup() {
for (int i = 3; i <= 7; i++) {
features.setApiLevel(i);
assertFalse(features.hasBackup());
}
features.setApiLevel(8);
assertTrue(features.hasBackup());
}
public void testHasTextToSpeech() {
features.setApiLevel(3);
assertFalse(features.hasTextToSpeech());