Moving signal strength sampling into a separate app.

This commit is contained in:
Rodrigo Damazio
2010-11-26 23:51:32 -08:00
parent 7abce12499
commit 5971d67a66
49 changed files with 1341 additions and 315 deletions
-3
View File
@@ -184,9 +184,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Beim teilen mit Freunden wird nur die Karten URL gesendet.</string>
<string name="settings_share_url_only_summary_off">Beim teilen mit Freunden wird der GPS Track selbst gesendet.</string>
<string name="settings_signal_sampling_frequency">Empfangsstärke Aufzeichnungsfrequenz</string>
<string name="settings_signal_sampling_frequency_summary">Dauer zwischen zwei Aufzeichnungen der Telefonempfangsstärke.</string>
<string name="settings_split_frequency">Zerteilungs Frequenz</string>
<string name="settings_split_frequency_summary">Längste Dauer oder Entfernung nach der automatisch ein Marker eingefügt wird.</string>
<string name="pace_label">Tempo</string>
-3
View File
@@ -187,9 +187,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Sólo el URL del mapa será enviado al compartir</string>
<string name="settings_share_url_only_summary_off">Los contenidos de la pista también serán incluídos al compartir</string>
<string name="settings_signal_sampling_frequency">Frecuencia de medición de señal</string>
<string name="settings_signal_sampling_frequency_summary">Tiempo entre grabaciones de la intensidad de la señal del teléfono</string>
<string name="settings_split_frequency">Dividir frecuencia</string>
<string name="settings_split_frequency_summary">Tiempo o distancia máxima para insertar una nueva marca de división</string>
<string name="pace_label">Paso</string>
-3
View File
@@ -187,9 +187,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Seule l\'adresse URL de la carte sera envoyée lors du partage</string>
<string name="settings_share_url_only_summary_off">Le contenu du parcours sera également inclus lors du partage</string>
<string name="settings_signal_sampling_frequency">Échantillonnage du signal</string>
<string name="settings_signal_sampling_frequency_summary">Intervalle de temps entre deux enregistrements de la force du signal</string>
<string name="settings_split_frequency">Fréquence de séparation</string>
<string name="settings_split_frequency_summary">Temps ou distance minimum avant l\'insertion d\'un marqueur de séparation</string>
<string name="pace_label">Rythme</string>
-3
View File
@@ -193,9 +193,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Solo l\'URL della mappa sarà inviata quando condividi un percorso</string>
<string name="settings_share_url_only_summary_off">Anche il contenuto del percorso sarà inviato quando condividi un persorso</string>
<string name="settings_signal_sampling_frequency">Frequenza di campionamento</string>
<string name="settings_signal_sampling_frequency_summary">Tempo fra due registrazioni della qualità del segnale cellulare</string>
<string name="settings_split_frequency">Frequenza di divisione</string>
<string name="settings_split_frequency_summary">Tempo o distanza massima dopo di cui il percorso verrà diviso</string>
<string name="pace_label">Andatura</string>
-11
View File
@@ -194,9 +194,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">共有時にマップのURLのみ送信します</string>
<string name="settings_share_url_only_summary_off">共有時にトラックのコンテントが含まれます</string>
<string name="settings_signal_sampling_frequency">信号サンプリング周波数</string>
<string name="settings_signal_sampling_frequency_summary">端末の信号強度記録の時間間隔</string>
<string name="settings_split_frequency">分割頻度</string>
<string name="settings_split_frequency_summary">分割マーカを挿入する時間または距離の間隔</string>
<string name="pace_label">ペース</string>
@@ -384,12 +381,4 @@ limitations under the License.
<!-- Check Units -->
<string name="check_units_title">計測単位についてのご注意</string>
<string name="check_units_message">デフォルトの単位はメートルです.設定を変更しますか?</string>
<!-- Signal Strength -->
<string name="error_rate"> 誤り率: %1$d</string>
<string name="signal_to_noise_ratio"> S/N比: %1$d</string>
<string name="ecio"> Ec/Io比: %1$.1f dB</string>
<string name="gsm_strength">GSM 強度: %1$d</string>
<string name="cdma_strength">CDMA 強度: %1$d dBm</string>
<string name="evdo_strength">EVDO 強度: %1$d dBm</string>
</resources>
-11
View File
@@ -195,9 +195,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Tylko odnośnik do mapy będzie wysyłany podczas dzielenia się</string>
<string name="settings_share_url_only_summary_off">Zawartość trasy będzie również przesyłana</string>
<string name="settings_signal_sampling_frequency">Częstotliowść próbkowania sygnału</string>
<string name="settings_signal_sampling_frequency_summary">Czas między dwoma zapisami siły sygnału telefonu</string>
<string name="settings_split_frequency">Częstotliwość rozdzielania</string>
<string name="settings_split_frequency_summary">Maksymalny czas lub odległość po którym wstawiony zostanie znacznik rozdzielenia</string>
@@ -416,12 +413,4 @@ limitations under the License.
<!-- Check Units -->
<string name="check_units_title">Jednostki miary</string>
<string name="check_units_message">Domyślnie używane są jednostki metryczne. Chcesz to zmienić?</string>
<!-- Signal Strength -->
<string name="error_rate"> Poziom błędów: %1$d</string>
<string name="signal_to_noise_ratio"> Stosunek sygnału do szumu: %1$d</string>
<string name="ecio"> Ec/lo: %1$.1f dB</string>
<string name="gsm_strength">Siła GSM: %1$d</string>
<string name="cdma_strength">Siła CDMA: %1$d dBm</string>
<string name="evdo_strength">Siła EVDO: %1$d dBm</string>
</resources>
-11
View File
@@ -195,9 +195,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Bara länken till kartan kommer att skickas vid delning</string>
<string name="settings_share_url_only_summary_off">Innehållet i spåret kommer också att inkluderas vid delning</string>
<string name="settings_signal_sampling_frequency">Signalprovsfrekvens</string>
<string name="settings_signal_sampling_frequency_summary">Tid mellan två inspelningar av telefonens signalstyrka</string>
<string name="settings_split_frequency">Delningsfrekvens</string>
<string name="settings_split_frequency_summary">Maximala tiden eller distansen varefter en ny delningsmarkör kommer infogas</string>
<string name="pace_label">Tempo</string>
@@ -383,12 +380,4 @@ limitations under the License.
<!-- Check Units -->
<string name="check_units_title">Mätenheter</string>
<string name="check_units_message">Som standard är enheterna metriska. Vill du ändra den inställningen?</string>
<!-- Signal Strength -->
<string name="error_rate"> Felfrekvens: %1$d</string>
<string name="signal_to_noise_ratio"> Signal / brus-förhållande: %1$d</string>
<string name="ecio"> Ec/lo: %1$.1f dB</string>
<string name="gsm_strength">GSM-styrka: %1$d</string>
<string name="cdma_strength">CDMA-styrka: %1$d dBm</string>
<string name="evdo_strength">EVDO-styrka: %1$d dBm</string>
</resources>
-17
View File
@@ -201,9 +201,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">在分享时只发送地图的 URL</string>
<string name="settings_share_url_only_summary_off">在分享时也包括轨迹的内容</string>
<string name="settings_signal_sampling_frequency">信号采样频率</string>
<string name="settings_signal_sampling_frequency_summary">记录电话信号强度的时间间隔</string>
<string name="settings_split_frequency">切割频度</string>
<string name="settings_split_frequency_summary">插入新切割标记所需要达到的最大时间或距离</string>
@@ -451,14 +448,6 @@ limitations under the License.
<string name="check_units_title">测量单位提示</string>
<string name="check_units_message">默认单位均为公制. 你想要修改此设置吗?</string>
<!-- Signal Strength -->
<string name="error_rate"> 错误率: %1$d</string>
<string name="signal_to_noise_ratio"> 信噪比: %1$d</string>
<string name="ecio"> Ec/lo: %1$.1f dB</string>
<string name="gsm_strength">GSM 强度 %1$d</string>
<string name="cdma_strength">CDMA 强度 %1$d dBm</string>
<string name="evdo_strength">EVDO 强度 %1$d dBm</string>
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
<string name="method_bluetooth">蓝牙</string>
<string name="bluetooth_options">蓝牙设置</string>
@@ -467,12 +456,6 @@ limitations under the License.
<string name="sensor_options">感应器选项</string>
<!-- Bluetooth Sensor -->
<string name="bluetooth_connected">连接到 %s</string>
<string name="bluetooth_connecting">蓝牙感应器连接中 ...</string>
-1
View File
@@ -36,7 +36,6 @@ limitations under the License.
<string name="sensor_id_key">sensorId</string>
<string name="sensor_type_key">sensorType</string>
<string name="share_url_only_key">shareUrlOnly</string>
<string name="signal_sampling_frequency_key">signalSamplingFrequency</string>
<string name="split_frequency_key">splitFrequency</string>
<string name="timestamp_track_name_key">timestampTrackName</string>
-11
View File
@@ -201,9 +201,6 @@ limitations under the License.
<string name="settings_share_url_only_summary_on">Only the URL of the map will be sent when sharing</string>
<string name="settings_share_url_only_summary_off">The contents of the track will also be included when sharing</string>
<string name="settings_signal_sampling_frequency">Signal sampling frequency</string>
<string name="settings_signal_sampling_frequency_summary">Time between two recordings of the phone\'s signal strength</string>
<string name="settings_split_frequency">Split frequency</string>
<string name="settings_split_frequency_summary">Maximum time or distance after which a new split marker will be inserted</string>
@@ -447,14 +444,6 @@ limitations under the License.
<string name="check_units_title">Units of Measure Notice</string>
<string name="check_units_message">By default units are metric. Would you like to change that setting?</string>
<!-- Signal Strength -->
<string name="error_rate"> Error Rate: %1$d</string>
<string name="signal_to_noise_ratio"> Signal to Noise Ratio: %1$d</string>
<string name="ecio"> Ec/lo: %1$.1f dB</string>
<string name="gsm_strength">GSM Strength: %1$d</string>
<string name="cdma_strength">CDMA Strength: %1$d dBm</string>
<string name="evdo_strength">EVDO Strength: %1$d dBm</string>
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
<string name="method_bluetooth">Bluetooth</string>
<string name="bluetooth_options">Bluetooth options</string>
-8
View File
@@ -84,14 +84,6 @@ limitations under the License.
android:entryValues="@array/min_required_accuracy_values"
android:defaultValue="200" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="@string/signal_sampling_frequency_key"
android:title="@string/settings_signal_sampling_frequency"
android:summary="@string/settings_signal_sampling_frequency_summary"
android:entries="@array/task_frequency_options"
android:entryValues="@array/task_frequency_values"
android:defaultValue="-1" />
<com.google.android.apps.mytracks.IntegerListPreference
android:key="@string/auto_resume_track_timeout_key"
android:title="@string/settings_auto_resume_track_timeout"
@@ -49,7 +49,10 @@ public final class Waypoint implements Parcelable {
waypoint.type = source.readInt();
waypoint.startId = source.readLong();
waypoint.stopId = source.readLong();
waypoint.stats = source.readParcelable(classLoader);
byte hasStats = source.readByte();
if (hasStats > 0) {
waypoint.stats = source.readParcelable(classLoader);
}
byte hasLocation = source.readByte();
if (hasLocation > 0) {
waypoint.location = source.readParcelable(classLoader);
@@ -100,7 +103,10 @@ public final class Waypoint implements Parcelable {
dest.writeInt(type);
dest.writeLong(startId);
dest.writeLong(stopId);
dest.writeParcelable(stats, 0);
dest.writeByte(stats == null ? (byte) 0 : (byte) 1);
if (stats != null) {
dest.writeParcelable(stats, 0);
}
dest.writeByte(location == null ? (byte) 0 : (byte) 1);
if (location != null) {
dest.writeParcelable(location, 0);
@@ -40,7 +40,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
private final String minRecordingIntervalKey;
private final String minRequiredAccuracyKey;
private final String recordingTrackKey;
private final String signalSamplingFrequencyKey;
private final String splitFrequencyKey;
public PreferenceManager(TrackRecordingService service) {
@@ -72,8 +71,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
service.getString(R.string.min_required_accuracy_key);
recordingTrackKey =
service.getString(R.string.recording_track_key);
signalSamplingFrequencyKey =
service.getString(R.string.signal_sampling_frequency_key);
splitFrequencyKey =
service.getString(R.string.split_frequency_key);
@@ -163,10 +160,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
service.getSplitManager().setSplitFrequency(
sharedPreferences.getInt(splitFrequencyKey, 0));
}
if (key == null || key.equals(signalSamplingFrequencyKey)) {
service.getSignalManager().setFrequency(
sharedPreferences.getInt(signalSamplingFrequencyKey, -1), service);
}
if (key == null || key.equals(metricUnitsKey)) {
service.getSplitManager().setMetricUnits(
sharedPreferences.getBoolean(metricUnitsKey, true));
@@ -1,48 +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.services;
import com.google.android.apps.mytracks.MyTracksConstants;
import com.google.android.apps.mytracks.util.ApiFeatures;
import android.content.Context;
import android.util.Log;
/**
* Factory for producing a proper {@link SignalStrengthTask} according to the
* current API level.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthTaskFactory {
private final boolean hasModernSignalStrength;
SignalStrengthTaskFactory(ApiFeatures apiFeatures) {
this.hasModernSignalStrength = apiFeatures.hasModernSignalStrength();
}
public PeriodicTask create(Context context) {
if (hasModernSignalStrength) {
Log.d(MyTracksConstants.TAG,
"TrackRecordingService using modern signal strength api.");
return new SignalStrengthTaskModern(context);
} else {
Log.w(MyTracksConstants.TAG,
"TrackRecordingService using legacy signal strength api.");
return new SignalStrengthTask(context);
}
}
}
@@ -123,7 +123,6 @@ public class TrackRecordingService extends Service implements LocationListener {
* Status announcer executer.
*/
private PeriodicTaskExecuter announcementExecuter;
private TaskExecuterManager signalManager;
private SplitManager splitManager;
private PreferenceManager prefManager;
@@ -425,7 +424,6 @@ public class TrackRecordingService extends Service implements LocationListener {
statsBuilder = new TripStatisticsBuilder(stats.getStartTime());
setUpAnnouncer();
signalManager.restore();
splitManager.restore();
length = 0;
lastValidLocation = null;
@@ -643,11 +641,6 @@ public class TrackRecordingService extends Service implements LocationListener {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
splitManager = new SplitManager(this);
SignalStrengthTaskFactory strengthTaskFactory =
new SignalStrengthTaskFactory(ApiFeatures.getInstance());
signalManager =
new TaskExecuterManager(-1, strengthTaskFactory.create(this), this);
prefManager = new PreferenceManager(this);
registerLocationListener();
/**
@@ -730,8 +723,6 @@ public class TrackRecordingService extends Service implements LocationListener {
timer.purge();
unregisterLocationListener();
shutdownAnnouncer();
signalManager.shutdown();
signalManager = null;
splitManager.shutdown();
splitManager = null;
@@ -863,15 +854,25 @@ public class TrackRecordingService extends Service implements LocationListener {
throw new IllegalStateException(
"Unable to insert waypoint marker while not recording!");
}
if (waypoint.getLocation() != null) {
waypoint.setLength(length);
waypoint.setDuration(waypoint.getLocation().getTime()
- statsBuilder.getStatistics().getStartTime());
Uri uri = providerUtils.insertWaypoint(waypoint);
return Long.parseLong(uri.getLastPathSegment());
if (waypoint.getLocation() == null) {
if (lastValidLocation == null) {
Log.w(MyTracksConstants.TAG, "Cannot insert waypoint with no location");
return -1;
}
waypoint.setLocation(lastValidLocation);
}
return -1;
if (waypoint.getTrackId() < 0) {
waypoint.setTrackId(recordingTrackId);
}
waypoint.setLength(length);
waypoint.setDuration(waypoint.getLocation().getTime()
- statsBuilder.getStatistics().getStartTime());
Uri uri = providerUtils.insertWaypoint(waypoint);
return Long.parseLong(uri.getLastPathSegment());
}
/**
@@ -1041,7 +1042,6 @@ public class TrackRecordingService extends Service implements LocationListener {
showNotification();
registerLocationListener();
splitManager.restore();
signalManager.restore();
// Reset the number of auto-resume retries.
setAutoResumeTrackRetries(
@@ -1168,8 +1168,4 @@ public class TrackRecordingService extends Service implements LocationListener {
public SplitManager getSplitManager() {
return splitManager;
}
public TaskExecuterManager getSignalManager() {
return signalManager;
}
}
@@ -107,10 +107,6 @@ public class ApiFeatures {
return true;
}
public boolean hasModernSignalStrength() {
return getApiLevel() >= 7;
}
// Visible for testing.
protected int getApiLevel() {
@@ -1,72 +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.services;
import com.google.android.apps.mytracks.util.ApiFeatures;
import android.test.AndroidTestCase;
/**
* Tests for {@link SignalStrengthTaskFactoryTest}.
* These tests require Eclair+ (API level 7) to run.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthTaskFactoryTest extends AndroidTestCase {
/**
* Mock version of the {@link ApiFeatures} class.
*/
private static class MockApiFeatures extends ApiFeatures {
private boolean hasModernStrength;
public void setHasModernSignalStrength(boolean hasModernStrength) {
this.hasModernStrength = hasModernStrength;
}
@Override
public boolean hasModernSignalStrength() {
return hasModernStrength;
}
}
private MockApiFeatures apiFeatures;
@Override
protected void setUp() throws Exception {
super.setUp();
apiFeatures = new MockApiFeatures();
}
public void testCreate() {
apiFeatures.setHasModernSignalStrength(true);
SignalStrengthTaskFactory factory =
new SignalStrengthTaskFactory(apiFeatures);
PeriodicTask task = factory.create(getContext());
assertTrue(task.getClass().getName(),
task instanceof SignalStrengthTaskModern);
}
public void testCreate_legacy() {
apiFeatures.setHasModernSignalStrength(false);
SignalStrengthTaskFactory factory =
new SignalStrengthTaskFactory(apiFeatures);
PeriodicTask task = factory.create(getContext());
assertTrue(task.getClass().getName(), task instanceof SignalStrengthTask);
}
}
@@ -561,16 +561,6 @@ public class TrackRecordingServiceTest
functionalTest(R.string.min_recording_distance_key, 2);
}
@MediumTest
public void testWithProperties_noSignalSamplingFreq() throws Exception {
functionalTest(R.string.signal_sampling_frequency_key, (Object) null);
}
@MediumTest
public void testWithProperties_defaultSignalSamplingFreq() throws Exception {
functionalTest(R.string.signal_sampling_frequency_key, 1);
}
@MediumTest
public void testWithProperties_noSplitFreq() throws Exception {
functionalTest(R.string.split_frequency_key, (Object) null);
@@ -65,17 +65,6 @@ public class ApiFeaturesTest extends TestCase {
}
}
public void testHasModernSignalStrength() {
for (int i = 3; i <= 6; i++) {
features.setApiLevel(i);
assertFalse(features.hasModernSignalStrength());
}
features.setApiLevel(7);
assertTrue(features.hasModernSignalStrength());
features.setApiLevel(8);
assertTrue(features.hasModernSignalStrength());
}
public void testGetApiPlatformAdapter() {
assertNotNull(features.getApiPlatformAdapter());
}
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SignalStrengthSampler</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,12 @@
#Tue Nov 23 23:09:24 PST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
+61
View File
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.apps.mytracks.signalstrength"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<!-- Activity for configuring preferences -->
<activity android:name=".SignalStrengthPreferences"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Receiver to know when recording starts/stops and act on the service accordingly -->
<receiver android:name=".RecordingStateReceiver">
<intent-filter>
<action android:name="com.google.android.apps.mytracks.TRACK_STARTED" />
<action android:name="com.google.android.apps.mytracks.TRACK_PAUSED" />
<action android:name="com.google.android.apps.mytracks.TRACK_RESUMED" />
<action android:name="com.google.android.apps.mytracks.TRACK_STOPPED" />
</intent-filter>
</receiver>
<!-- Service which listens for signal strength and writes waypoints -->
<service android:name=".SignalStrengthService"
android:label="Signal Strength Sampling Service"
android:icon="@drawable/icon"
android:enabled="true" />
</application>
<!-- Requirements -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.apps.mytracks.TRACK_NOTIFICATIONS" />
<uses-permission android:name="com.google.android.apps.mytracks.WRITE_TRACK_DATA" />
<uses-feature android:name="android.hardware.telephony" android:required="true"/>
<uses-feature android:name="android.hardware.telephony.gsm" android:required="false"/>
<uses-sdk android:minSdkVersion="3" />
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true" />
</manifest>
+11
View File
@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=Google Inc.:Google APIs:8
+34
View File
@@ -0,0 +1,34 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Task frequency -->
<string-array name="task_period_options">
<item>As often as possible</item>
<item>1 min</item>
<item>2 min</item>
<item>5 min</item>
<item>10 min</item>
<item>15 min</item>
<item>30 min</item>
<item>60 min</item>
</string-array>
<!-- DO NOT TRANSLATE -->
<string-array name="task_period_values">
<item>-1</item>
<item>1</item>
<item>2</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>30</item>
<item>60</item>
</string-array>
</resources>
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">Signal strength sampler for My Tracks</string>
<string name="settings_sampling">Sampling settings</string>
<string name="settings_auto_start">Automatic start</string>
<string name="settings_auto_start_summary_on">Automatically start inserting signal strength waypoints whenever My Tracks starts recording a track.</string>
<string name="settings_auto_start_summary_off">You will need to manually start signal sampling using the controls below.</string>
<string name="settings_min_signal_sampling_period">Min. sampling period</string>
<string name="settings_min_signal_sampling_period_summary">Minimum time between two recordings of the phone\'s signal strength</string>
<string name="settings_control">Sampling control</string>
<string name="settings_control_start">Start sampling</string>
<string name="settings_control_start_summary">Starts sampling signal strength immediately, if My Tracks is recording. Sampling will stop once My Tracks stops recording.</string>
<string name="settings_control_stop">Stop sampling</string>
<string name="settings_control_stop_summary">Stops sampling signal strength if sampling is currently active.</string>
<string name="started_sampling">Started sampling cell signal strength.</string>
<string name="stopped_sampling">Stopped sampling cell signal strength.</string>
<string name="unknown">-</string>
<!-- Signal Strength -->
<string name="error_rate"> Error Rate: %1$d</string>
<string name="signal_to_noise_ratio"> Signal to Noise Ratio: %1$d</string>
<string name="ecio"> Ec/lo: %1$.1f dB</string>
<string name="gsm_strength">GSM Strength: %1$d</string>
<string name="cdma_strength">CDMA Strength: %1$d dBm</string>
<string name="evdo_strength">EVDO Strength: %1$d dBm</string>
<!-- Non-translatable strings -->
<string name="settings_auto_start_key">autoStartSampling</string>
<string name="settings_min_signal_sampling_period_key">signalSamplingFrequency</string>
<string name="settings_control_start_key">startSamplingControl</string>
<string name="settings_control_stop_key">stopSamplingControl</string>
</resources>
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/settings_sampling">
<CheckBoxPreference android:key="@string/settings_auto_start_key"
android:title="@string/settings_auto_start"
android:summaryOn="@string/settings_auto_start_summary_on"
android:summaryOff="@string/settings_auto_start_summary_off"
android:defaultValue="false" />
<ListPreference
android:key="@string/settings_min_signal_sampling_period_key"
android:title="@string/settings_min_signal_sampling_period"
android:summary="@string/settings_min_signal_sampling_period_summary"
android:entries="@array/task_period_options"
android:entryValues="@array/task_period_values"
android:defaultValue="-1" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_control">
<Preference android:key="@string/settings_control_start_key"
android:title="@string/settings_control_start"
android:summary="@string/settings_control_start_summary"
android:persistent="false" />
<Preference android:key="@string/settings_control_stop_key"
android:title="@string/settings_control_stop"
android:summary="@string/settings_control_stop_summary"
android:persistent="false" />
</PreferenceCategory>
</PreferenceScreen>
@@ -0,0 +1,2 @@
package com.google.android.apps.mytracks.content;
parcelable Waypoint;
@@ -0,0 +1,189 @@
/*
* Copyright 2009 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.content;
import android.location.Location;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A way point. It has a location, meta data such as name, description,
* category, and icon, plus it can store track statistics for a "sub-track".
*
* TODO: hashCode and equals
*
* @author Leif Hendrik Wilden
* @author Rodrigo Damazio
*/
public final class Waypoint implements Parcelable {
/**
* Creator for a Waypoint object
*/
public static class Creator implements Parcelable.Creator<Waypoint> {
public Waypoint createFromParcel(Parcel source) {
ClassLoader classLoader = getClass().getClassLoader();
Waypoint waypoint = new Waypoint();
waypoint.id = source.readLong();
waypoint.name = source.readString();
waypoint.description = source.readString();
waypoint.category = source.readString();
waypoint.icon = source.readString();
waypoint.trackId = source.readLong();
waypoint.type = source.readInt();
waypoint.startId = source.readLong();
waypoint.stopId = source.readLong();
if (source.readByte() > 0) {
throw new UnsupportedOperationException(
"No support for reading waypoints with stats");
}
byte hasLocation = source.readByte();
if (hasLocation > 0) {
waypoint.location = source.readParcelable(classLoader);
}
return waypoint;
}
public Waypoint[] newArray(int size) {
return new Waypoint[size];
}
}
public static final Creator CREATOR = new Creator();
public static final int TYPE_WAYPOINT = 0;
public static final int TYPE_STATISTICS = 1;
private long id = -1;
private String name = "";
private String description = "";
private String category = "";
private String icon = "";
private long trackId = -1;
private int type = 0;
private Location location;
/** Start track point id */
private long startId = -1;
/** Stop track point id */
private long stopId = -1;
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeString(name);
dest.writeString(description);
dest.writeString(category);
dest.writeString(icon);
dest.writeLong(trackId);
dest.writeInt(type);
dest.writeLong(startId);
dest.writeLong(stopId);
dest.writeByte((byte) 0); // No stats
dest.writeByte(location == null ? (byte) 0 : (byte) 1);
if (location != null) {
dest.writeParcelable(location, 0);
}
}
// Getters and setters:
//---------------------
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Location getLocation() {
return location;
}
public void setTrackId(long trackId) {
this.trackId = trackId;
}
public int describeContents() {
return 0;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getTrackId() {
return trackId;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public long getStartId() {
return startId;
}
public void setStartId(long startId) {
this.startId = startId;
}
public long getStopId() {
return stopId;
}
public void setStopId(long stopId) {
this.stopId = stopId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public void setLocation(Location location) {
this.location = location;
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.content.Waypoint;
/**
* MyTracks service.
* This service is the process that actually records and manages tracks.
*/
interface ITrackRecordingService {
/**
* Starts recording a new track.
*
* @return the track ID of the new track
*/
long startNewTrack();
/**
* Checks and returns whether we're currently recording a track.
*/
boolean isRecording();
/**
* Returns the track ID of the track currently being recorded, or -1 if none
* is being recorded. This ID can then be used to read track data from the
* content source.
*/
long getRecordingTrackId();
/**
* Inserts a waypoint marker in the track being recorded.
*
* @param waypoint the waypoint to insert
* @return the unique ID of the inserted marker
*/
long insertWaypointMarker(in Waypoint waypoint);
/**
* Inserts a statistics marker in the track being recorded.
*
* @param location the location at which to insert the marker
* @return the unique ID of the inserted marker
*/
long insertStatisticsMarker(in Location location);
/**
* Inserts a location in the track being recorded.
*
* When recording, locations detected by the GPS are already automatically
* added to the track, so this should be used only for adding special points
* or for testing.
*
* @param loc the location to insert
*/
void recordLocation(in Location loc);
/**
* Stops recording the current track.
*/
void endCurrentTrack();
/**
* Returns whether at least one track has been or is being recorded (and was
* not deleted).
*/
boolean hasRecorded();
/**
* Deletes all the stored tracks.
*/
void deleteAllTracks();
}
@@ -0,0 +1,61 @@
/*
* 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.signalstrength;
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
/**
* Broadcast listener which gets notified when we start or stop recording a track.
*
* @author Rodrigo Damazio
*/
public class RecordingStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent intent) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
boolean autoStart = preferences.getBoolean(
ctx.getString(R.string.settings_auto_start_key), false);
if (!autoStart) {
Log.d(TAG, "Not auto-starting signal sampling");
return;
}
String action = intent.getAction();
if (START_TRACK_ACTION.equals(action) || RESUME_TRACK_ACTION.equals(action)) {
startService(ctx);
} else if (STOP_TRACK_ACTION.equals(action) || PAUSE_TRACK_ACTION.equals(action)) {
stopService(ctx);
} else {
Log.e(TAG, "Unknown action received: " + action);
}
}
// @VisibleForTesting
protected void stopService(Context ctx) {
SignalStrengthService.stopService(ctx);
}
// @VisibleForTesting
protected void startService(Context ctx) {
SignalStrengthService.startService(ctx);
}
}
@@ -0,0 +1,56 @@
/*
* 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.signalstrength;
import android.content.ComponentName;
import android.os.Build;
/**
* Constants for the signal sampler.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthConstants {
// TODO: Many of these could be moved into a common library for third-party apps
public static final String START_TRACK_ACTION =
"com.google.android.apps.mytracks.TRACK_STARTED";
public static final String PAUSE_TRACK_ACTION =
"com.google.android.apps.mytracks.TRACK_PAUSED";
public static final String RESUME_TRACK_ACTION =
"com.google.android.apps.mytracks.TRACK_RESUMED";
public static final String STOP_TRACK_ACTION =
"com.google.android.apps.mytracks.TRACK_STOPPED";
public static final String TRACK_ID_EXTRA =
"com.google.android.apps.mytracks.TRACK_ID";
public static final String MYTRACKS_SERVICE =
"com.google.android.apps.mytracks.services.TrackRecordingService";
public static final String MYTRACKS_SERVICE_PACKAGE =
"com.google.android.maps.mytracks";
public static final ComponentName MYTRACKS_SERVICE_COMPONENT =
new ComponentName(MYTRACKS_SERVICE_PACKAGE, MYTRACKS_SERVICE);
public static final String START_SAMPLING =
"com.google.android.apps.mytracks.signalstrength.START";
public static final String STOP_SAMPLING =
"com.google.android.apps.mytracks.signalstrength.STOP";
public static final int ANDROID_API_LEVEL = Integer.parseInt(
Build.VERSION.SDK);
public static final String TAG = "SignalStrengthSampler";
private SignalStrengthConstants() {}
}
@@ -0,0 +1,42 @@
/*
* 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.signalstrength;
/**
* Interface for the service that reads signal strength.
*
* @author Rodrigo Damazio
*/
public interface SignalStrengthListener {
/**
* Interface for getting notified about a new sampled signal strength.
*/
public interface SignalStrengthCallback {
void onSignalStrengthSampled(
String description,
String icon);
}
/**
* Starts listening to signal strength.
*/
void register();
/**
* Stops listening to signal strength.
*/
void unregister();
}
@@ -13,14 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.signalstrength;
package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.MyTracksConstants;
import com.google.android.apps.mytracks.content.Waypoint;
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
import android.content.Context;
import android.location.Location;
import android.telephony.CellLocation;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneStateListener;
@@ -31,67 +28,49 @@ import java.util.List;
/**
* A class to monitor the network signal strength.
*
* TODO: i18n
*
* @author Sandor Dornbush
*/
public class SignalStrengthTask extends PhoneStateListener
implements PeriodicTask {
public class SignalStrengthListenerCupcake extends PhoneStateListener
implements SignalStrengthListener {
private final Context context;
private final SignalStrengthCallback callback;
private TelephonyManager manager;
private int signalStrength = -1;
public SignalStrengthTask(Context c) {
context = c;
public SignalStrengthListenerCupcake(Context context, SignalStrengthCallback callback) {
this.context = context;
this.callback = callback;
}
@Override
public void start() {
manager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
public void register() {
manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager == null) {
Log.e(MyTracksConstants.TAG, "Cannot get telephony manager.");
Log.e(TAG, "Cannot get telephony manager.");
} else {
manager.listen(this, getListenEvents());
}
}
protected int getListenEvents() {
return PhoneStateListener.LISTEN_SIGNAL_STRENGTHS;
return PhoneStateListener.LISTEN_SIGNAL_STRENGTH;
}
@Override
public void onSignalStrengthChanged(int asu) {
this.signalStrength = asu;
Log.d(MyTracksConstants.TAG, "Signal Strength: " + signalStrength);
public void onSignalStrengthChanged(int signalStrength) {
Log.d(TAG, "Signal Strength: " + signalStrength);
this.signalStrength = signalStrength;
notifySignalSampled();
}
@Override
public void run(TrackRecordingService service) {
Log.d(MyTracksConstants.TAG, "Adding signal marker");
Location location = service.getLastLocation();
if (manager == null) {
Log.d(MyTracksConstants.TAG, "Adding signal marker: marker null");
return;
}
if (location == null) {
Log.d(MyTracksConstants.TAG, "Adding signal marker: location null");
return;
}
Waypoint wpt = new Waypoint();
wpt.setName("Signal Strength");
wpt.setType(Waypoint.TYPE_WAYPOINT);
wpt.setTrackId(service.getRecordingTrackId());
protected void notifySignalSampled() {
int networkType = manager.getNetworkType();
wpt.setIcon(getIcon(networkType));
wpt.setLocation(location);
wpt.setDescription(getDescription());
long waypointId = service.insertWaypointMarker(wpt);
if (waypointId >= 0) {
Log.d(MyTracksConstants.TAG, "Added signal marker");
} else {
Log.e(MyTracksConstants.TAG, "Cannot insert waypoint marker?");
}
callback.onSignalStrengthSampled(getDescription(), getIcon(networkType));
}
/**
@@ -138,7 +117,7 @@ public class SignalStrengthTask extends PhoneStateListener
sb.append('\n');
List<NeighboringCellInfo> infos = manager.getNeighboringCellInfo();
Log.i(MyTracksConstants.TAG, "Found " + infos.size() + " cells.");
Log.i(TAG, "Found " + infos.size() + " cells.");
if (infos.size() > 0) {
sb.append("Neighbors: ");
for (NeighboringCellInfo info : infos) {
@@ -178,7 +157,7 @@ public class SignalStrengthTask extends PhoneStateListener
}
@Override
public void shutdown() {
public void unregister() {
if (manager != null) {
manager.listen(this, PhoneStateListener.LISTEN_NONE);
manager = null;
@@ -192,4 +171,8 @@ public class SignalStrengthTask extends PhoneStateListener
protected Context getContext() {
return context;
}
public SignalStrengthCallback getSignalStrengthCallback() {
return callback;
}
}
@@ -14,10 +14,9 @@
* the License.
*/
package com.google.android.apps.mytracks.services;
package com.google.android.apps.mytracks.signalstrength;
import com.google.android.apps.mytracks.MyTracksConstants;
import com.google.android.maps.mytracks.R;
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
import android.content.Context;
import android.telephony.PhoneStateListener;
@@ -27,15 +26,17 @@ import android.util.Log;
/**
* A class to monitor the network signal strength.
*
* TODO: i18n
*
* @author Sandor Dornbush
*/
public class SignalStrengthTaskModern extends SignalStrengthTask {
public class SignalStrengthListenerEclair extends SignalStrengthListenerCupcake {
private SignalStrength signalStrength = null;
public SignalStrengthTaskModern(Context c) {
super(c);
public SignalStrengthListenerEclair(Context ctx, SignalStrengthCallback callback) {
super(ctx, callback);
}
@Override
@@ -43,6 +44,13 @@ public class SignalStrengthTaskModern extends SignalStrengthTask {
return PhoneStateListener.LISTEN_SIGNAL_STRENGTHS;
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
Log.d(TAG, "Signal Strength Modern: " + signalStrength);
this.signalStrength = signalStrength;
notifySignalSampled();
}
/**
* Gets a human readable description for the network type.
*
@@ -146,10 +154,4 @@ public class SignalStrengthTaskModern extends SignalStrengthTask {
sb.append(getContext().getString(signalFormat, signal));
sb.append("\n");
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
Log.d(MyTracksConstants.TAG, "Signal Strength Modern: " + signalStrength);
this.signalStrength = signalStrength;
}
}
@@ -0,0 +1,47 @@
/*
* 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.signalstrength;
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback;
import android.content.Context;
import android.util.Log;
/**
* Factory for producing a proper {@link SignalStrengthListenerCupcake} according to the
* current API level.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthListenerFactory {
public SignalStrengthListener create(Context context, SignalStrengthCallback callback) {
if (hasModernSignalStrength()) {
Log.d(TAG, "TrackRecordingService using modern signal strength api.");
return new SignalStrengthListenerEclair(context, callback);
} else {
Log.w(TAG, "TrackRecordingService using legacy signal strength api.");
return new SignalStrengthListenerCupcake(context, callback);
}
}
// @VisibleForTesting
protected boolean hasModernSignalStrength() {
return ANDROID_API_LEVEL >= 7;
}
}
@@ -0,0 +1,53 @@
/*
* 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.signalstrength;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
/**
* Main signal strength sampler activity, which displays preferences.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthPreferences extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
// Attach service control funciontality
findPreference(getString(R.string.settings_control_start_key))
.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
SignalStrengthService.startService(SignalStrengthPreferences.this);
return true;
}
});
findPreference(getString(R.string.settings_control_stop_key))
.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
SignalStrengthService.stopService(SignalStrengthPreferences.this);
return true;
}
});
}
}
@@ -0,0 +1,248 @@
/*
* 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.signalstrength;
import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.IBinder;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import java.util.List;
/**
* Serivce which actually reads signal strength and sends it to My Tracks.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthService extends Service
implements ServiceConnection, SignalStrengthCallback, OnSharedPreferenceChangeListener {
private SignalStrengthListener signalListener;
private ITrackRecordingService mytracksService;
private long lastSamplingTime;
private long samplingPeriod;
@Override
public void onStart(Intent intent, int startId) {
handleCommand(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(intent, startId);
return START_STICKY;
}
private void handleCommand(Intent intent, int startId) {
String action = intent.getAction();
if (START_SAMPLING.equals(action)) {
startSampling();
} else {
stopSampling();
}
}
private void startSampling() {
// TODO: Start foreground
if (!isMytracksRunning()) {
Log.w(TAG, "My Tracks not running!");
return;
}
Log.d(TAG, "Starting sampling");
Intent intent = new Intent();
intent.setComponent(MYTRACKS_SERVICE_COMPONENT);
if (!bindService(intent, SignalStrengthService.this, 0)) {
Log.e(TAG, "Couldn't bind to service.");
return;
}
}
private boolean isMytracksRunning() {
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
for (RunningServiceInfo serviceInfo : services) {
if (serviceInfo.pid != 0 &&
serviceInfo.service.equals(MYTRACKS_SERVICE_COMPONENT)) {
return true;
}
}
return false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (this) {
mytracksService = ITrackRecordingService.Stub.asInterface(service);
Log.d(TAG, "Bound to My Tracks");
boolean recording = false;
try {
recording = mytracksService.isRecording();
} catch (RemoteException e) {
Log.e(TAG, "Failed to talk to my tracks", e);
}
if (!recording) {
Log.w(TAG, "My Tracks is not recording, bailing");
stopSampling();
return;
}
// We're ready to send waypoints, so register for signal sampling
SignalStrengthListenerFactory factory = new SignalStrengthListenerFactory();
signalListener = factory.create(this, this);
signalListener.register();
// Register for preference changes
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(this);
samplingPeriod = Long.parseLong(preferences.getString(
getString(R.string.settings_min_signal_sampling_period_key), "-1"));
preferences.registerOnSharedPreferenceChangeListener(this);
// Tell the user we've started.
Toast.makeText(this, R.string.started_sampling, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onSignalStrengthSampled(String description, String icon) {
long now = System.currentTimeMillis();
if (now - lastSamplingTime < samplingPeriod * 60 * 1000) {
return;
}
// We don't set location or track id - My Tracks can fill those
Waypoint wpt = new Waypoint();
wpt.setName("Signal Strength");
wpt.setType(Waypoint.TYPE_WAYPOINT);
wpt.setIcon(icon);
wpt.setDescription(description);
try {
long waypointId;
synchronized (this) {
if (mytracksService == null) {
Log.d(TAG, "No my tracks service to send to");
return;
}
waypointId = mytracksService.insertWaypointMarker(wpt);
}
if (waypointId >= 0) {
Log.d(TAG, "Added signal marker");
lastSamplingTime = now;
} else {
Log.e(TAG, "Cannot insert waypoint marker?");
}
} catch (RemoteException e) {
Log.e(TAG, "Cannot talk to my tracks service", e);
}
}
private void stopSampling() {
Log.d(TAG, "Stopping sampling");
synchronized (this) {
// Unregister from preference change updates
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(this);
preferences.unregisterOnSharedPreferenceChangeListener(this);
// Unregister from receiving signal updates
if (signalListener != null) {
signalListener.unregister();
signalListener = null;
}
// Unbind from My Tracks
if (mytracksService != null) {
unbindService(this);
mytracksService = null;
}
// Reset the last sampling time
lastSamplingTime = 0;
// Tell the user we've stopped
Toast.makeText(this, R.string.stopped_sampling, Toast.LENGTH_SHORT).show();
// Stop
stopSelf();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "Disconnected from My Tracks");
synchronized (this) {
mytracksService = null;
}
}
@Override
public void onDestroy() {
stopSampling();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void startService(Context context) {
Intent intent = new Intent();
intent.setClass(context, SignalStrengthService.class);
intent.setAction(START_SAMPLING);
context.startService(intent);
}
public static void stopService(Context context) {
Intent intent = new Intent();
intent.setClass(context, SignalStrengthService.class);
intent.setAction(STOP_SAMPLING);
context.startService(intent);
}
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (getString(R.string.settings_min_signal_sampling_period_key).equals(key)) {
samplingPeriod = Long.parseLong(sharedPreferences.getString(key, "-1"));
}
}
}
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry combineaccessrules="false" kind="src" path="/SignalStrengthSampler"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="libs/AndroidMockRuntime.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SignalStrengthSamplerTest</name>
<comment></comment>
<projects>
<project>SignalStrengthSampler</project>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,5 @@
#Fri Nov 26 22:23:21 PST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.source=1.5
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.apps.mytracks.signalstrength.test"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
<uses-library android:name="android.test.runner" />
</application>
<uses-sdk android:minSdkVersion="3" />
<instrumentation android:targetPackage="com.google.android.apps.mytracks.signalstrength"
android:name="android.test.InstrumentationTestRunner" />
</manifest>
@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=Google Inc.:Google APIs:8
+34
View File
@@ -0,0 +1,34 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="hello">Hello World!</string>
</resources>
@@ -0,0 +1,68 @@
/*
* 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.signalstrength.test;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerCupcake;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerEclair;
import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerFactory;
import com.google.android.testing.mocking.AndroidMock;
import android.test.AndroidTestCase;
/**
* Tests for {@link SignalStrengthListenerFactory}.
* These tests require Eclair+ (API level 7) to run.
*
* @author Rodrigo Damazio
*/
public class SignalStrengthListenerFactoryTest extends AndroidTestCase {
private boolean hasModernSignalStrength;
private TestableSignalStrengthListenerFactory factory;
private SignalStrengthCallback callback;
private class TestableSignalStrengthListenerFactory extends SignalStrengthListenerFactory {
@Override
protected boolean hasModernSignalStrength() {
return hasModernSignalStrength;
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
factory = new TestableSignalStrengthListenerFactory();
callback = AndroidMock.createMock(SignalStrengthCallback.class);
}
public void testCreate_eclair() {
hasModernSignalStrength = true;
SignalStrengthListener listener = factory.create(getContext(), callback);
assertTrue(listener.getClass().getName(),
listener instanceof SignalStrengthListenerEclair);
}
public void testCreate_legacy() {
hasModernSignalStrength = false;
SignalStrengthListener listener = factory.create(getContext(), callback);
assertTrue(listener.getClass().getName(),
listener instanceof SignalStrengthListenerCupcake);
}
}