diff --git a/myTracks/build.gradle b/myTracks/build.gradle index 3600df7eb..2aca26ae5 100644 --- a/myTracks/build.gradle +++ b/myTracks/build.gradle @@ -22,7 +22,6 @@ android { dependencies { implementation project(':myTracksLib') - compile files('libs/antlib.jar') androidTestCompile files('libs/AndroidMockGenerator.jar') androidTestCompile files('libs/robotium-solo-5.0.1.jar') diff --git a/myTracks/libs/antlib.jar b/myTracks/libs/antlib.jar deleted file mode 100644 index 21d141ba9..000000000 Binary files a/myTracks/libs/antlib.jar and /dev/null differ diff --git a/myTracks/proguard.cfg b/myTracks/proguard.cfg index fc8bb4eb1..3bdeb3eef 100644 --- a/myTracks/proguard.cfg +++ b/myTracks/proguard.cfg @@ -106,8 +106,3 @@ # class name is enough to get the file name. -renamesourcefileattribute MT -keepattributes SourceFile,LineNumberTable - -# Keep services needed by ANT+ protocol --keep public class com.dsi.ant.IAnt_6 --keep public class com.dsi.ant.IAnt --keep public class com.dsi.ant.IServiceSettings diff --git a/myTracks/src/main/AndroidManifest.xml b/myTracks/src/main/AndroidManifest.xml index 7baa899e5..b7c5cb75e 100644 --- a/myTracks/src/main/AndroidManifest.xml +++ b/myTracks/src/main/AndroidManifest.xml @@ -30,8 +30,6 @@ limitations under the License. - - diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java index d8c17e946..c070d2a56 100644 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java +++ b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java @@ -16,7 +16,6 @@ package com.google.android.apps.mytracks.services.sensors; -import com.google.android.apps.mytracks.services.sensors.ant.AntSensorManager; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; @@ -96,7 +95,6 @@ public class SensorManagerFactory { context, R.string.sensor_type_key, PreferencesUtils.SENSOR_TYPE_DEFAULT); switch (sensorType) { - case "ANT": return new AntSensorManager(context); case "ZEPHYR": return new ZephyrSensorManager(context); case "POLAR": return new PolarSensorManager(context); } diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java deleted file mode 100644 index 7da1fe8f6..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java +++ /dev/null @@ -1,588 +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.services.sensors.ant; - -import com.dsi.ant.AntDefine; -import com.dsi.ant.AntInterface; -import com.dsi.ant.AntInterfaceIntent; -import com.dsi.ant.AntMesg; -import com.dsi.ant.exception.AntInterfaceException; -import com.dsi.ant.exception.AntServiceNotConnectedException; -import com.google.android.apps.mytracks.content.Sensor; -import com.google.android.apps.mytracks.content.Sensor.SensorDataSet; -import com.google.android.apps.mytracks.content.Sensor.SensorState; -import com.google.android.apps.mytracks.services.sensors.SensorManager; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.R; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.provider.Settings; -import android.util.Log; -import android.widget.Toast; - -import java.lang.reflect.Field; -import java.util.Locale; - -/** - * Ant Sensor Manager. - * - * @author Jimmy Shih - */ -public class AntSensorManager extends SensorManager { - - /** - * Channel States - */ - public enum ChannelStates { - CLOSED, // Channel is closed - PENDING_OPEN, // User has requested opening the channel, waiting for a reset - SEARCHING, // Channel is opened, but has not received data - TRACKING_STATUS, // Channel is opened and has received status data recently - TRACKING_DATA, // Channel is opened and has received measurement data - // recently - OFFLINE // Channel is closed as the result of a search timeout - } - public static final short WILDCARD = 0; - - private static final String TAG = AntSensorManager.class.getSimpleName(); - private static final int CHANNELS = 4; - private static final String RADIO_ANT = "ant"; - private static final byte ANT_NETWORK = (byte) 0x01; - - private final Context context; - private final ChannelConfiguration channelConfig[]; - private final IntentFilter statusIntentFilter; - private final AntInterface antInterface; - - private boolean serviceConnected = false; - private boolean hasClaimedInterface = false; - - private SensorDataSet sensorDataSet = null; - private long lastSensorDataSetTime = 0; - private AntSensorValue antSensorValue = new AntSensorValue(); - - private boolean requestedReset = false; - - private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() { - @Override - public void onServiceConnected() { - setSensorState(Sensor.SensorState.CONNECTING); - serviceConnected = true; - try { - hasClaimedInterface = antInterface.hasClaimedInterface(); - if (!hasClaimedInterface) { - hasClaimedInterface = antInterface.claimInterface(); - } - if (!hasClaimedInterface) { - tryClaimAnt(); - return; - } - if (!antInterface.isEnabled()) { - antInterface.enable(); - } - requestReset(); - enableDataMessage(true); - } catch (AntInterfaceException e) { - handleAntError(); - } - } - - @Override - public void onServiceDisconnected() { - serviceConnected = false; - if (hasClaimedInterface) { - enableDataMessage(false); - } - setSensorState(SensorState.DISCONNECTED); - } - }; - - /** - * Constructor. - * - * @param context the context - */ - public AntSensorManager(Context context) { - this.context = context; - - channelConfig = new ChannelConfiguration[CHANNELS]; - channelConfig[0] = new HeartRateChannelConfiguration(); - channelConfig[1] = new SpeedDistanceChannelConfiguration(); - channelConfig[2] = new BikeCadenceChannelConfiguration(); - channelConfig[3] = new CombinedBikeChannelConfiguration(); - - statusIntentFilter = new IntentFilter(); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLED_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLING_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_DISABLED_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_DISABLING_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_RESET_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION); - statusIntentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); - - antInterface = new AntInterface(); - } - - @Override - protected synchronized void setUpChannel() { - tearDownChannel(); - if (AntInterface.hasAntSupport(context)) { - context.registerReceiver(statusReceiver, statusIntentFilter); - if (!antInterface.initService(context, serviceListener)) { - AntInterface.goToMarket(context); - } - } - } - - @Override - protected void tearDownChannel() { - try { - context.unregisterReceiver(statusReceiver); - } catch (IllegalArgumentException e) { - // Can safely ignore - } - enableDataMessage(false); - if (serviceConnected) { - try { - if (hasClaimedInterface) { - antInterface.releaseInterface(); - } - hasClaimedInterface = false; - antInterface.stopRequestForceClaimInterface(); - } catch (AntServiceNotConnectedException e) { - // Can safely ignore - } catch (AntInterfaceException e) { - Log.w(TAG, "Exception in tearDonwChannel.", e); - } - antInterface.releaseService(); - serviceConnected = false; - } - setSensorState(SensorState.DISCONNECTED); - } - - @Override - public SensorDataSet getSensorDataSet() { - return sensorDataSet; - } - - /** - * Tries to claim the ant interface. - */ - private void tryClaimAnt() { - try { - antInterface.requestForceClaimInterface(context.getString(R.string.my_tracks_app_name)); - } catch (AntInterfaceException e) { - handleAntError(); - } - } - - /** - * Configures ant radio. - */ - private void configureAntRadio() { - try { - if (serviceConnected && hasClaimedInterface && antInterface.isEnabled()) { - try { - antInterface.ANTDisableEventBuffering(); - } catch (AntInterfaceException e) { - Log.e(TAG, "Cannot disable event buffering.", e); - } - } else { - Log.i(TAG, "Cannot disable event buffering now."); - } - } catch (AntInterfaceException e) { - Log.e(TAG, "Unable to check enabled state.", e); - } - } - - /** - * Handles ant error. - */ - private void handleAntError() { - clearAllChannels(); - } - - /** - * Opens a channel. - * - * @param channel the channel - */ - private void openChannel(byte channel) { - short deviceNumber = (short) PreferencesUtils.getInt( - context, channelConfig[channel].getDeviceIdKey(), WILDCARD); - channelConfig[channel].setDeviceNumber(deviceNumber); - channelConfig[channel].setChannelState(ChannelStates.PENDING_OPEN); - setupAntChannel(ANT_NETWORK, channel); - } - - /** - * Closes a channel. - * - * @param channel the channel - */ - private void closeChannel(byte channel) { - channelConfig[channel].setInitializing(false); - channelConfig[channel].setDeinitializing(true); - channelConfig[channel].setChannelState(ChannelStates.CLOSED); - try { - antInterface.ANTCloseChannel(channel); - // Note, unassign channel after getting channel closed event - } catch (AntInterfaceException e) { - Log.w(TAG, "Unable to close channel: " + channel, e); - handleAntError(); - } - } - - /** - * Clears all channels. - */ - private void clearAllChannels() { - for (int i = 0; i < CHANNELS; i++) { - channelConfig[i].setChannelState(ChannelStates.CLOSED); - } - setSensorState(SensorState.DISCONNECTED); - } - - /** - * Requests reset. - */ - private void requestReset() { - try { - requestedReset = true; - antInterface.ANTResetSystem(); - configureAntRadio(); - } catch (AntInterfaceException e) { - Log.e(TAG, "Unable to reset ant.", e); - requestedReset = false; - } - } - - @Override - public boolean isEnabled() { - if (antInterface == null || !antInterface.isServiceConnected()) { - return false; - } - try { - return antInterface.isEnabled(); - } catch (AntInterfaceException e) { - Log.w(TAG, "Unable to check enabled.", e); - return false; - } - } - - private final BroadcastReceiver statusReceiver = new BroadcastReceiver() { - public void onReceive(Context c, Intent intent) { - String ANTAction = intent.getAction(); - if (ANTAction.equals(AntInterfaceIntent.ANT_DISABLED_ACTION)) { - clearAllChannels(); - } else if (ANTAction.equals(AntInterfaceIntent.ANT_RESET_ACTION)) { - if (!requestedReset) { - // Someone else triggered an ant reset - clearAllChannels(); - } else { - requestedReset = false; - configureAntRadio(); - } - } else if (ANTAction.equals(AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION)) { - boolean wasClaimed = hasClaimedInterface; - - // Could also read ANT_INTERFACE_CLAIMED_PID from intent and see if it - // matches the current process PID. - try { - hasClaimedInterface = antInterface.hasClaimedInterface(); - if (hasClaimedInterface) { - enableDataMessage(true); - } else { - if (wasClaimed) { - // Claimed by another application - enableDataMessage(false); - setSensorState(SensorState.DISCONNECTED); - } - } - } catch (AntInterfaceException e) { - handleAntError(); - } - } else if (ANTAction.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { - if (isAirPlaneMode()) { - clearAllChannels(); - } - } - } - }; - - private final BroadcastReceiver dataReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context c, Intent intent) { - if (intent.getAction().equals(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)) { - byte[] antRxMessage = intent.getByteArrayExtra(AntInterfaceIntent.ANT_MESSAGE); - byte channel; - switch (antRxMessage[AntMesg.MESG_ID_OFFSET]) { - case AntMesg.MESG_BROADCAST_DATA_ID: - case AntMesg.MESG_ACKNOWLEDGED_DATA_ID: - channel = antRxMessage[AntMesg.MESG_DATA_OFFSET]; - if (channelConfig[channel].getChannelState() != ChannelStates.CLOSED) { - channelConfig[channel].setChannelState(ChannelStates.TRACKING_DATA); - } - - if (channelConfig[channel].getDeviceNumber() == WILDCARD) { - try { - antInterface.ANTRequestMessage(channel, AntMesg.MESG_CHANNEL_ID_ID); - } catch (AntInterfaceException e) { - handleAntError(); - } - } - channelConfig[channel].decodeMessage(antRxMessage, antSensorValue); - setSensorDataSet(); - break; - case AntMesg.MESG_RESPONSE_EVENT_ID: - handleResponseEventMessage(antRxMessage); - break; - case AntMesg.MESG_CHANNEL_ID_ID: - channel = antRxMessage[AntMesg.MESG_DATA_OFFSET]; - short deviceNumber = (short) ((antRxMessage[AntMesg.MESG_DATA_OFFSET + 1] & 0xFF - | ((antRxMessage[AntMesg.MESG_DATA_OFFSET + 2] & 0xFF) << 8)) & 0xFFFF); - channelConfig[channel].setDeviceNumber(deviceNumber); - PreferencesUtils.setInt(context, channelConfig[channel].getDeviceIdKey(), deviceNumber); - Toast.makeText(context, - context.getString(R.string.settings_sensor_connected, deviceNumber), - Toast.LENGTH_SHORT).show(); - setSensorState(SensorState.CONNECTED); - break; - default: - break; - } - } - } - - /** - * Handles response event message. - * - * @param message the message - */ - private void handleResponseEventMessage(byte[] message) { - // For a list of possible message codes see ANT Message Protocol and Usage - // section 9.5.6.1 available from thisisant.com - byte channel = message[AntMesg.MESG_DATA_OFFSET]; - if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_EVENT_ID) - && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.EVENT_RX_SEARCH_TIMEOUT)) { - // A channel timed out searching, unassign it - channelConfig[channel].setInitializing(false); - channelConfig[channel].setDeinitializing(false); - channelConfig[channel].setChannelState(ChannelStates.OFFLINE); - try { - antInterface.ANTUnassignChannel(channel); - } catch (AntInterfaceException e) { - handleAntError(); - } - setSensorState(SensorState.DISCONNECTED); - } - - if (channelConfig[channel].isInitializing()) { - if (message[AntMesg.MESG_DATA_OFFSET + 2] != 0) { - // Error response - Log.e(TAG, String.format(Locale.US, - "Error code(%#02x) on message ID(%#02x) on channel %d", - message[AntMesg.MESG_DATA_OFFSET + 2], message[AntMesg.MESG_DATA_OFFSET + 1], - channel)); - } else { - // Switch on message id - switch (message[AntMesg.MESG_DATA_OFFSET + 1]) { - case AntMesg.MESG_ASSIGN_CHANNEL_ID: - try { - antInterface.ANTSetChannelId(channel, channelConfig[channel].getDeviceNumber(), - channelConfig[channel].getDeviceType(), ChannelConfiguration.TRANSMISSION_TYPE); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_CHANNEL_ID_ID: - try { - antInterface.ANTSetChannelPeriod(channel, channelConfig[channel].getMessagPeriod()); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_CHANNEL_MESG_PERIOD_ID: - try { - antInterface.ANTSetChannelRFFreq(channel, ChannelConfiguration.FREQUENCY); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_CHANNEL_RADIO_FREQ_ID: - try { - // Disable high priority search - antInterface.ANTSetChannelSearchTimeout(channel, (byte) 0); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_CHANNEL_SEARCH_TIMEOUT_ID: - try { - // Set search timeout to 30 seconds (low priority search) - antInterface.ANTSetLowPriorityChannelSearchTimeout(channel, (byte) 12); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_SET_LP_SEARCH_TIMEOUT_ID: - if (channelConfig[channel].getDeviceNumber() == WILDCARD) { - try { - // Configure proximity search, if using wild card search - antInterface.ANTSetProximitySearch( - channel, ChannelConfiguration.PROXIMITY_SEARCH); - } catch (AntInterfaceException e) { - handleAntError(); - } - } else { - try { - antInterface.ANTOpenChannel(channel); - } catch (AntInterfaceException e) { - handleAntError(); - } - } - break; - case AntMesg.MESG_PROX_SEARCH_CONFIG_ID: - try { - antInterface.ANTOpenChannel(channel); - } catch (AntInterfaceException e) { - handleAntError(); - } - break; - case AntMesg.MESG_OPEN_CHANNEL_ID: - channelConfig[channel].setInitializing(false); - channelConfig[channel].setChannelState(ChannelStates.SEARCHING); - break; - default: - break; - } - } - } else if (channelConfig[channel].isDeinitializing()) { - if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_EVENT_ID) - && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.EVENT_CHANNEL_CLOSED)) { - try { - antInterface.ANTUnassignChannel(channel); - } catch (AntInterfaceException e) { - handleAntError(); - } - } else if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_UNASSIGN_CHANNEL_ID) - && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.RESPONSE_NO_ERROR)) { - channelConfig[channel].setDeinitializing(false); - } - } - } - }; - - /** - * Sets sensor data set. - */ - private void setSensorDataSet() { - long now = System.currentTimeMillis(); - // Data comes in at ~4Hz rate from the sensors, so after >300 msec fresh - // data is here from all the connected sensors - if (now < lastSensorDataSetTime + 300) { - return; - } - lastSensorDataSetTime = now; - - SensorDataSet.Builder builder = Sensor.SensorDataSet.newBuilder(); - int heartRate = antSensorValue.getHeartRate(); - if (heartRate != -1) { - builder.setHeartRate(Sensor.SensorData.newBuilder() - .setValue(heartRate).setState(Sensor.SensorState.SENDING)); - } - int cadence = antSensorValue.getCadence(); - if (cadence != -1) { - builder.setCadence(Sensor.SensorData.newBuilder() - .setValue(cadence).setState(Sensor.SensorState.SENDING)); - } - sensorDataSet = builder.setCreationTime(now).build(); - setSensorState(SensorState.SENDING); - } - - /** - * Sets up ant channel. - * - * @param networkNumber the network number - * @param channel the channel - */ - private void setupAntChannel(byte networkNumber, byte channel) { - try { - channelConfig[channel].setInitializing(true); - channelConfig[channel].setDeinitializing(false); - - // Assign as slave channel on selected network - antInterface.ANTAssignChannel(channel, AntDefine.PARAMETER_RX_NOT_TX, networkNumber); - - // The rest of the channel configuration will occur after the response is - // received in handleResponseEventMessage - } catch (AntInterfaceException aie) { - handleAntError(); - } - } - - /** - * Enables data message. - * - * @param enabled true to enable - */ - private void enableDataMessage(boolean enabled) { - if (enabled) { - context.registerReceiver( - dataReceiver, new IntentFilter(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)); - for (int i = 0; i < CHANNELS; i++) { - openChannel((byte) i); - } - } else { - try { - context.unregisterReceiver(dataReceiver); - for (int i = 0; i < CHANNELS; i++) { - closeChannel((byte) i); - } - } catch (IllegalArgumentException e) { - // Can safely ignore - } - } - } - - /** - * Returns true if in airplane mode. - */ - private boolean isAirPlaneMode() { - if (!Settings.System.getString( - context.getContentResolver(), Settings.System.AIRPLANE_MODE_RADIOS) - .contains(RADIO_ANT)) { - return false; - } - if (Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) - == 0) { - return false; - } - - try { - Field field = Settings.System.class.getField("AIRPLANE_MODE_TOGGLEABLE_RADIOS"); - return !Settings.System.getString(context.getContentResolver(), (String) field.get(null)) - .contains(RADIO_ANT); - } catch (Exception e) { - // This is expected if the list does not yet exist, so just return true - return true; - } - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorValue.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorValue.java deleted file mode 100644 index ca74d3946..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/AntSensorValue.java +++ /dev/null @@ -1,60 +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.services.sensors.ant; - -/** - * Contains the latest ant sensor value. - * - * @author Jimmy Shih - */ -public class AntSensorValue { - - private int heartRate = -1; - private int cadence = -1; - - /** - * Gets the heart rate. - */ - public int getHeartRate() { - return heartRate; - } - - /** - * Sets the heart rate. - * - * @param heartRate the heart rate to set - */ - public void setHeartRate(int heartRate) { - this.heartRate = heartRate; - } - - /** - * Gets the cadence. - */ - public int getCadence() { - return cadence; - } - - /** - * Sets the cadence. - * - * @param cadence the cadence to set - */ - public void setCadence(int cadence) { - this.cadence = cadence; - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/BikeCadenceChannelConfiguration.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/BikeCadenceChannelConfiguration.java deleted file mode 100644 index 061fd71fc..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/BikeCadenceChannelConfiguration.java +++ /dev/null @@ -1,55 +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.services.sensors.ant; - -import com.google.android.maps.mytracks.R; - -/** - * Bike cadence sensor channel configuration. - * - * @author Jimmy Shih - */ -public class BikeCadenceChannelConfiguration extends ChannelConfiguration { - - private static final int DEVICE_ID_KEY = R.string.ant_bike_cadence_sensor_id_key; - private static final byte DEVICE_TYPE = 0x7A; - private static final short MESSAGE_PERIOD = 8102; - - private CadenceCounter cadenceCounter = new CadenceCounter(); - - @Override - public int getDeviceIdKey() { - return DEVICE_ID_KEY; - } - - @Override - public byte getDeviceType() { - return DEVICE_TYPE; - } - - @Override - public short getMessagPeriod() { - return MESSAGE_PERIOD; - } - - @Override - public void decodeMessage(byte[] message, AntSensorValue antSensorValue) { - int revolutionCount = ((int) message[9] & 0xFF) + ((int) message[10] & 0xFF) * 256; - int eventTime = ((int) message[7] & 0xFF) + ((int) message[8] & 0xFF) * 256; - antSensorValue.setCadence(cadenceCounter.getEventsPerMinute(revolutionCount, eventTime)); - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CadenceCounter.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CadenceCounter.java deleted file mode 100644 index d49e66ab9..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CadenceCounter.java +++ /dev/null @@ -1,178 +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.services.sensors.ant; - -import java.util.LinkedList; - -/** - * A counter that processes an Ant+ sensor data (count + event time) and returns - * the instantaneous cadence value. - * - * @author Laszlo Molnar - */ -public class CadenceCounter { - - private static final int MILLIS_PER_MINUTE = 60000; - private static final int MAX_HISTORY_TIME_IN_MILLIS = 5000; // 5 seconds - private static final int MAX_HISTORY_SIZE = 100; - private static final int EVENT_TIME_PER_MINUTE = 60 * 1024; - - /** - * Cadence data. - * - * @author Laszlo Molnar - */ - private static class CadenceData { - final long systemTime; - final int count; - final int eventTime; - - private CadenceData(long systemTime, int count, int eventTime) { - this.systemTime = systemTime; - this.count = count; - this.eventTime = eventTime; - } - } - - // The last count - private int lastCount; - - // The last calculated cadence - private int eventsPerMinute; - - // The history of the previous sensor data, oldest first - private LinkedList history; - - public CadenceCounter() { - lastCount = -1; - eventsPerMinute = 0; - history = new LinkedList(); - } - - /** - * Gets the cadence value. - * - * @param count count - * @param eventTime event time - */ - public int getEventsPerMinute(int count, int eventTime) { - long now = System.currentTimeMillis(); - int countChange = (count - lastCount) & 0xFFFF; - - if (lastCount < 0) { - /* - * eventTime for the initial count value is probably out of date, so not - * updating the history. - */ - lastCount = count; - eventsPerMinute = 0; - return 0; - } - - lastCount = count; - - if (countChange != 0) { - if (removeOldHistory(now)) { - CadenceData lastCadenceData = history.getLast(); - int eventTimeChange = (eventTime - lastCadenceData.eventTime) & 0xFFFF; - if (eventTimeChange != 0) { - countChange = (count - lastCadenceData.count) & 0xFFFF; - eventsPerMinute = countChange * EVENT_TIME_PER_MINUTE / eventTimeChange; - } - } - history.addLast(new CadenceData(now, count, eventTime)); - return eventsPerMinute; - } else { - // The sensor has resent old data - if (history.isEmpty()) { - eventsPerMinute = 0; - return 0; - } - - CadenceData lastCadenceData = history.getLast(); - if ((now - lastCadenceData.systemTime) * eventsPerMinute < MILLIS_PER_MINUTE) { - // The last eventsPerMinute is still valid - return eventsPerMinute; - } - - // Update the history - if (!removeOldHistory(now)) { - eventsPerMinute = 0; - return 0; - } - - /* - * Too much time has passed since the last count change. A smaller value - * than eventsPerMinute must be returned. The value is calculated from the - * history. - */ - return getValueFromHistory(now); - } - } - - /** - * Gets the cadence value from the history when the sensor only resends the - * old data. - * - * @param now the current system time - */ - private int getValueFromHistory(long now) { - CadenceData firstCadenceData = history.getFirst(); - CadenceData lastCadenceData = history.getLast(); - int eventTimeChange = (lastCadenceData.eventTime - firstCadenceData.eventTime) & 0xFFFF; - int countChange = (lastCount - firstCadenceData.count) & 0xFFFF; - - // (now - lastCadenceData) + (lastCadenceData - firstCadenceData) - int systemTimeChange = (int) (now - lastCadenceData.systemTime - + (eventTimeChange * MILLIS_PER_MINUTE) / EVENT_TIME_PER_MINUTE); - - /* - * eventsPerMinute is not updated because it is still needed when a new - * sensor event arrives. - */ - if (systemTimeChange == 0) { - return eventsPerMinute; - } - int value = (countChange * MILLIS_PER_MINUTE) / systemTimeChange; - - /* - * Do not return a larger number than eventsPerMinute because this function - * is only called when more time has passed after the last count change than - * the interval from eventsPerMinute. - */ - return value < eventsPerMinute ? value : eventsPerMinute; - } - - /** - * Removes old data from the history. - * - * @param now the current system time - * @return true if the remaining history is not empty. - */ - private boolean removeOldHistory(long now) { - CadenceData historyElement = history.peek(); - while (historyElement != null) { - if (now - historyElement.systemTime <= MAX_HISTORY_TIME_IN_MILLIS - && history.size() < MAX_HISTORY_SIZE) { - return true; - } - history.removeFirst(); - historyElement = history.peek(); - } - return false; - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java deleted file mode 100644 index f13cd15f8..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java +++ /dev/null @@ -1,123 +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.services.sensors.ant; - -import com.google.android.apps.mytracks.services.sensors.ant.AntSensorManager.ChannelStates; - -/** - * Ant channel configuration. - * - * @author Jimmy Shih - */ -public abstract class ChannelConfiguration { - - public static final byte FREQUENCY = 57; // 2457Mhz (Ant+ frequency) - public static final byte TRANSMISSION_TYPE = 0; // 0 for wild card search - public static final byte PROXIMITY_SEARCH = 7; - - private short deviceNumber = AntSensorManager.WILDCARD; - private ChannelStates channelState = ChannelStates.CLOSED; - private boolean isInitializing = false; - private boolean isDeinitializing = false; - - /** - * Gets the My Tracks settings device id key. - */ - public abstract int getDeviceIdKey(); - - /** - * Gets the device type. - */ - public abstract byte getDeviceType(); - - /** - * Gets the message period. - */ - public abstract short getMessagPeriod(); - - /** - * Decodes the message and places the value in antSensorValue. - * - * @param message the message - * @param antSensorValue the ant sensor value - */ - public abstract void decodeMessage(byte[] message, AntSensorValue antSensorValue); - - /** - * Gets the device number. - */ - public short getDeviceNumber() { - return deviceNumber; - } - - /** - * Sets the device number. - * - * @param deviceNumber the device number to set - */ - public void setDeviceNumber(short deviceNumber) { - this.deviceNumber = deviceNumber; - } - - /** - * Gets the channel state. - */ - public ChannelStates getChannelState() { - return channelState; - } - - /** - * Sets the channel state. - * - * @param channelState the channelState to set - */ - public void setChannelState(ChannelStates channelState) { - this.channelState = channelState; - } - - /** - * Returns true if initializing. - */ - public boolean isInitializing() { - return isInitializing; - } - - /** - * Sets isInitializing. - * - * @param isInitializing true if isInitializing - */ - public void setInitializing(boolean isInitializing) { - this.isInitializing = isInitializing; - } - - /** - * Returns true if deinitializing. - */ - public boolean isDeinitializing() { - return isDeinitializing; - } - - /** - * Sets isDeinitializing. - * - * @param isDeinitializing true if isDeinitializing - */ - public void setDeinitializing(boolean isDeinitializing) { - this.isDeinitializing = isDeinitializing; - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CombinedBikeChannelConfiguration.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CombinedBikeChannelConfiguration.java deleted file mode 100644 index 784aaa4da..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/CombinedBikeChannelConfiguration.java +++ /dev/null @@ -1,56 +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.services.sensors.ant; - -import com.google.android.maps.mytracks.R; - -/** - * Combined bike sensor channel configuration. - * - * @author Jimmy Shih - */ -public class CombinedBikeChannelConfiguration extends ChannelConfiguration { - - private static final int DEVICE_ID_KEY = R.string.ant_combined_bike_sensor_id_key; - private static final byte DEVICE_TYPE = 0x79; - private static final short MESSAGE_PERIOD = 8086; - - private CadenceCounter cadenceCounter = new CadenceCounter(); - - @Override - public int getDeviceIdKey() { - return DEVICE_ID_KEY; - } - - @Override - public byte getDeviceType() { - return DEVICE_TYPE; - } - - @Override - public short getMessagPeriod() { - return MESSAGE_PERIOD; - } - - @Override - public void decodeMessage(byte[] message, AntSensorValue antSensorValue) { - int revolutionCount = ((int) message[5] & 0xFF) + ((int) message[6] & 0xFF) * 256; - int eventTime = ((int) message[3] & 0xFF) + ((int) message[4] & 0xFF) * 256; - - antSensorValue.setCadence(cadenceCounter.getEventsPerMinute(revolutionCount, eventTime)); - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/HeartRateChannelConfiguration.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/HeartRateChannelConfiguration.java deleted file mode 100644 index 6ae2d2ae7..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/HeartRateChannelConfiguration.java +++ /dev/null @@ -1,51 +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.services.sensors.ant; - -import com.google.android.maps.mytracks.R; - -/** - * Heart rate monitor channel configuration. - * - * @author Jimmy Shih - */ -public class HeartRateChannelConfiguration extends ChannelConfiguration { - - private static final int DEVICE_ID_KEY = R.string.ant_heart_rate_monitor_id_key; - private static final byte DEVICE_TYPE = 0x78; - private static final short MESSAGE_PERIOD = 8070; - - @Override - public int getDeviceIdKey() { - return DEVICE_ID_KEY; - } - - @Override - public byte getDeviceType() { - return DEVICE_TYPE; - } - - @Override - public short getMessagPeriod() { - return MESSAGE_PERIOD; - } - - @Override - public void decodeMessage(byte[] message, AntSensorValue antSensorValue) { - antSensorValue.setHeartRate(message[10] & 0xFF); - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/SpeedDistanceChannelConfiguration.java b/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/SpeedDistanceChannelConfiguration.java deleted file mode 100644 index a107bcec9..000000000 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/services/sensors/ant/SpeedDistanceChannelConfiguration.java +++ /dev/null @@ -1,55 +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.services.sensors.ant; - -import com.google.android.maps.mytracks.R; - -/** - * Speed distance monitor channel configuration. - * - * @author Jimmy Shih - */ -public class SpeedDistanceChannelConfiguration extends ChannelConfiguration { - - private static final int DEVICE_ID_KEY = R.string.ant_speed_distance_monitor_id_key; - private static final byte DEVICE_TYPE = 0x7C; - private static final short MESSAGE_PERIOD = 8134; - - @Override - public int getDeviceIdKey() { - return DEVICE_ID_KEY; - } - - @Override - public byte getDeviceType() { - return DEVICE_TYPE; - } - - @Override - public short getMessagPeriod() { - return MESSAGE_PERIOD; - } - - @Override - public void decodeMessage(byte[] message, AntSensorValue antSensorValue) { - // Check page 2 data - if (message[3] == 0x02) { - antSensorValue.setCadence( - (int) ((message[6] & 0xFF) + (((message[7] >>> 4) & 0x0F) / 16.0f))); - } - } -} diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java b/myTracks/src/main/java/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java index bed1455b5..31a6cc603 100644 --- a/myTracks/src/main/java/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java +++ b/myTracks/src/main/java/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java @@ -16,8 +16,6 @@ package com.google.android.apps.mytracks.settings; -import com.dsi.ant.AntInterface; -import com.google.android.apps.mytracks.services.sensors.ant.AntSensorManager; import com.google.android.apps.mytracks.util.BluetoothDeviceUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; @@ -48,9 +46,7 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { super.onCreate(bundle); addPreferencesFromResource(R.xml.sensor_settings); - boolean hasAntSupport = AntInterface.hasAntSupport(this); - - configSensorType(hasAntSupport); + configSensorType(); findPreference(getString(R.string.settings_sensor_bluetooth_pairing_key)) .setOnPreferenceClickListener(new OnPreferenceClickListener() { @@ -60,30 +56,15 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { return true; } }); - - if (!hasAntSupport) { - PreferenceScreen rootPreferenceScreen = (PreferenceScreen) findPreference( - getString(R.string.settings_sensor_root_key)); - rootPreferenceScreen.removePreference( - findPreference(getString(R.string.settings_sensor_ant_key))); - } } @SuppressWarnings("deprecation") - private void configSensorType(boolean hasAntSupport) { - ListPreference preference = (ListPreference) findPreference( - getString(R.string.sensor_type_key)); + private void configSensorType() { + ListPreference preference = (ListPreference) findPreference(getString(R.string.sensor_type_key)); String value = PreferencesUtils.getString( this, R.string.sensor_type_key, PreferencesUtils.SENSOR_TYPE_DEFAULT); - String[] options = getResources().getStringArray( - hasAntSupport ? R.array.sensor_type_all_options : R.array.sensor_type_bluetooth_options); - String[] values = getResources().getStringArray( - hasAntSupport ? R.array.sensor_type_all_values : R.array.sensor_type_bluetooth_values); - - if (!hasAntSupport && value.equals(R.string.sensor_type_value_ant)) { - value = PreferencesUtils.SENSOR_TYPE_DEFAULT; - PreferencesUtils.setString(this, R.string.sensor_type_key, value); - } + String[] options = getResources().getStringArray(R.array.sensor_type_bluetooth_options); + String[] values = getResources().getStringArray( R.array.sensor_type_bluetooth_values); OnPreferenceChangeListener listener = new OnPreferenceChangeListener() { @Override @@ -102,49 +83,10 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { */ @SuppressWarnings("deprecation") private void updateUiBySensorType(String sensorType) { - boolean isBluetooth = getString(R.string.sensor_type_value_polar).equals(sensorType) - || getString(R.string.sensor_type_value_zephyr).equals(sensorType); + boolean isBluetooth = getString(R.string.sensor_type_value_polar).equals(sensorType) || getString(R.string.sensor_type_value_zephyr).equals(sensorType); findPreference(getString(R.string.settings_sensor_bluetooth_key)).setEnabled(isBluetooth); - - boolean isAnt = getString(R.string.sensor_type_value_ant).equals(sensorType); - updateAntSensor(R.string.settings_sensor_ant_reset_heart_rate_monitor_key, - R.string.ant_heart_rate_monitor_id_key, isAnt); - updateAntSensor(R.string.settings_sensor_ant_reset_speed_distance_monitor_key, - R.string.ant_speed_distance_monitor_id_key, isAnt); - updateAntSensor(R.string.settings_sensor_ant_reset_bike_cadence_sensor_key, - R.string.ant_bike_cadence_sensor_id_key, isAnt); - updateAntSensor(R.string.settings_sensor_ant_reset_combined_bike_sensor_key, - R.string.ant_combined_bike_sensor_id_key, isAnt); } - /** - * Updates an ant sensor. - * - * @param preferenceKey the preference key - * @param valueKey the value key - * @param enabled true if enabled - */ - @SuppressWarnings("deprecation") - private void updateAntSensor(int preferenceKey, final int valueKey, boolean enabled) { - Preference preference = findPreference(getString(preferenceKey)); - if (preference != null) { - preference.setEnabled(enabled); - int deviceId = PreferencesUtils.getInt(this, valueKey, AntSensorManager.WILDCARD); - if (deviceId == AntSensorManager.WILDCARD) { - preference.setSummary(R.string.settings_sensor_ant_not_connected); - } else { - preference.setSummary(getString(R.string.settings_sensor_ant_paired, deviceId)); - } - preference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference pref) { - PreferencesUtils.setInt(SensorSettingsActivity.this, valueKey, AntSensorManager.WILDCARD); - pref.setSummary(R.string.settings_sensor_ant_not_connected); - return true; - } - }); - } - } @Override protected void onResume() { diff --git a/myTracks/src/main/res/values/arrays_do_not_translate.xml b/myTracks/src/main/res/values/arrays_do_not_translate.xml index 499dbca46..7f331672a 100644 --- a/myTracks/src/main/res/values/arrays_do_not_translate.xml +++ b/myTracks/src/main/res/values/arrays_do_not_translate.xml @@ -167,18 +167,6 @@ limitations under the License. 1000 2000 - - @string/settings_sensor_type_polar - @string/settings_sensor_type_zephyr - @string/settings_sensor_type_ant - @string/value_none - - - @string/sensor_type_value_polar - @string/sensor_type_value_zephyr - @string/sensor_type_value_ant - @string/sensor_type_value_none - @string/settings_sensor_type_polar @string/settings_sensor_type_zephyr diff --git a/myTracks/src/main/res/values/do_not_translate.xml b/myTracks/src/main/res/values/do_not_translate.xml index 8b8d3ca33..f0811b8ab 100644 --- a/myTracks/src/main/res/values/do_not_translate.xml +++ b/myTracks/src/main/res/values/do_not_translate.xml @@ -78,7 +78,6 @@ Google은 이용자에 대한 위치정보의 이용∙제공사실을 위치정 My Tracks Recording Service www.google.com/mobile/mytracks com.google.android.apps.mytracks.MYTRACKS_NOTIFICATIONS - ANT NONE POLAR ZEPHYR diff --git a/myTracks/src/main/res/values/keys.xml b/myTracks/src/main/res/values/keys.xml index 286ff70b2..b953f078c 100644 --- a/myTracks/src/main/res/values/keys.xml +++ b/myTracks/src/main/res/values/keys.xml @@ -80,11 +80,6 @@ limitations under the License. settingsRecording settingsReset settingsSensor - settingsSensorAnt - settingsSensorAntResetBikeCadenceSensor - settingsSensorAntResetCombinedBikeSensor - settingsSensorAntResetHeartRateMonitor - settingsSensorAntResetSpeedDistanceMonitor settingsSensorBluetooth settingsSensorBluetoothPairing settingsSensorRoot diff --git a/myTracks/src/main/res/values/strings.xml b/myTracks/src/main/res/values/strings.xml index d4197ce5a..26ff05cc3 100644 --- a/myTracks/src/main/res/values/strings.xml +++ b/myTracks/src/main/res/values/strings.xml @@ -1814,13 +1814,6 @@ limitations under the License. Character limit: ~23 (1 line)"> Sensor type - - ANT+ - - - - - - - \ No newline at end of file