我正在开发一个可以在可穿戴设备(Samsung Gear Live)和手持设备(Moto G)上运行的简单应用程序。我想在手持设备上显示来自可穿戴设备的心率传感器、加速度计和陀螺仪的数据。这是实现这一目标的最佳方法。现在我正在使用DataApi
,但由于我每秒都在更新数据,它分配了太多内存,然后被操作系统杀死。这是我在可穿戴设备上运行的服务
public class SensorDataListener extends Service implements SensorEventListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final String TAG = SensorDataListener.class.getSimpleName();
private static final int TIMEOUT_HEART_RATE = 1000000;
private static final int TIMEOUT_ACCELEROMETER = 1000000;
private static final int TIMEOUT_GYROSCOPE = 1000000;
private static final String PATH_SENSOR_DATA = "/sensor_data";
private static final String KEY_HEART_RATE = "heart_rate";
private static final String KEY_ACC_X = "acc_x";
private static final String KEY_ACC_Y = "acc_y";
private static final String KEY_ACC_Z = "acc_z";
private static final String KEY_GYRO_X = "gyro_x";
private static final String KEY_GYRO_Y = "gyro_y";
private static final String KEY_GYRO_Z = "gyro_z";
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Sensor mGyroscope;
private Sensor mHeartRate;
private int mCurHeartRateVal;
private float[] mCurAccelerometerVal = new float[3];
private float[] mCurGyroscopeVal = new float[3];
private GoogleApiClient mGoogleApiClient;
ScheduledExecutorService mUpdateScheduler;
ScheduledExecutorService scheduler;
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(com.google.android.gms.wearable.Wearable.API)
.build();
mGoogleApiClient.connect();
mSensorManager = ((SensorManager)getSystemService(SENSOR_SERVICE));
mHeartRate = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
startDataUpdated();
}
private void startDataUpdated() {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
updateData();
}
}, 5, 3, TimeUnit.SECONDS);
}
private void updateData() {
PutDataMapRequest dataMap = PutDataMapRequest.create(PATH_SENSOR_DATA);
dataMap.getDataMap().putInt(KEY_HEART_RATE, mCurHeartRateVal);
dataMap.getDataMap().putFloat(KEY_ACC_X, mCurAccelerometerVal[0]);
dataMap.getDataMap().putFloat(KEY_ACC_Y, mCurAccelerometerVal[1]);
dataMap.getDataMap().putFloat(KEY_ACC_Z, mCurAccelerometerVal[2]);
dataMap.getDataMap().putFloat(KEY_GYRO_X, mCurGyroscopeVal[0]);
dataMap.getDataMap().putFloat(KEY_GYRO_Y, mCurGyroscopeVal[1]);
dataMap.getDataMap().putFloat(KEY_GYRO_Z, mCurGyroscopeVal[2]);
PutDataRequest request = dataMap.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mSensorManager.registerListener(this, mHeartRate, TIMEOUT_HEART_RATE);
mSensorManager.registerListener(this, mAccelerometer, TIMEOUT_ACCELEROMETER);
mSensorManager.registerListener(this, mGyroscope, TIMEOUT_GYROSCOPE);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
mGoogleApiClient.disconnect();
scheduler.shutdown();
mSensorManager.unregisterListener(this);
//mUpdateScheduler.shutdownNow();
super.onDestroy();
}
@Override
public void onSensorChanged(SensorEvent event) {
switch(event.sensor.getType()) {
case Sensor.TYPE_HEART_RATE:
if(event.values[0] <= 0) // HR sensor is being initialized
return;
mCurHeartRateVal = Float.valueOf(event.values[0]).intValue();
break;
case Sensor.TYPE_ACCELEROMETER:
mCurAccelerometerVal[0] = event.values[0];
mCurAccelerometerVal[1] = event.values[1];
mCurAccelerometerVal[2] = event.values[2];
break;
case Sensor.TYPE_GYROSCOPE: {
mCurGyroscopeVal[0] = event.values[0];
mCurGyroscopeVal[1] = event.values[1];
mCurGyroscopeVal[2] = event.values[2];
break;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public void onConnected(Bundle bundle) { Log.d(TAG, "onConnected"); }
@Override
public void onConnectionSuspended(int i) { Log.d(TAG, "onConnectionSuspended"); }
@Override
public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "onConnectionFailed"); }
@Override
public IBinder onBind(Intent intent) {
return null;
}
}