Android Wearable和Handheld之间的实时数据交换

时间:2014-10-06 20:25:16

标签: wear-os android-wear-data-api

我正在开发一款简单的应用程序,可以在可穿戴设备(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;
    }
}

2 个答案:

答案 0 :(得分:2)

您是否尝试过Mario Viviani的Teleport(数据同步和信息库)

答案 1 :(得分:2)

尝试使用Message API而不是Data API。只需创建一条包含您数据的邮件,然后将其发送到您的其他设备:http://developer.android.com/reference/com/google/android/gms/wearable/MessageApi.html