Android Wear DataItem 同步/并行使用 Google 现在
Android Wear DataItem Syncing / parallel use of Google now
我正在为 android wear 开发一个应用程序,它正在收集传感器数据(例如加速度,..)并将其与移动设备上的相应应用程序同步 phone。每次触发传感器(onSensorChanged),执行以下代码:
Runnable runnable = new Runnable() {
@Override
public void run() {
PutDataMapRequest dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + sensorType);
dataMap.getDataMap().putInt(WearConstants.ACCURACY, accuracy);
dataMap.getDataMap().putLong(WearConstants.TIMESTAMP_WEAR, timestamp);
dataMap.getDataMap().putFloatArray(WearConstants.VALUES, values);
Wearable.DataApi.putDataItem(mApiClient, dataMap.asPutDataRequest()).setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d(TAG, "Sending sensor data: " + dataItemResult.getStatus().isSuccess());
}
});
}
}; Thread thread = new Thread(runnable); thread.start();
效果很好,传感器数据传输到手机 phone 并显示在应用程序中。该应用程序的第二个功能是可以做笔记。做笔记有两种可能性:a) 在应用程序打开时按下按钮 b) 在应用程序关闭时由 "Ok Google, take a note" 触发。 (参见 Google documentation)
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
startActivityForResult(intent, WearConstants.W_SPEECH);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case WearConstants.W_SPEECH: {
if (resultCode == RESULT_OK && data != null) {
List<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String spokenText = results.get(0);
sendSpeech(spokenText);
}
}
}
}
这也很好用,但前提是应用程序没有监听传感器变化。这就是问题所在:每次我在应用程序(或后台服务)侦听传感器变化时触发语音操作时,都无法识别语音并且我收到错误 "Google not reachable"。在我看来,BluetoothLE 连接的容量不足。因此,我尝试批处理传感器数据(在 ArrayList 中)并在收听语音命令时暂停发送到手机 phone,但没有区别。经过五天的努力寻找解决方案后,我现在有点绝望了:-)我希望你有新的想法或提示接下来要尝试什么。
经过一些额外的研究,我似乎终于找到了解决方案:当我尝试在第一个 运行 中批量处理传感器数据时,我只是暂停了发送。但是当达到我的限制时,我仍然分别发送每个值。那是个大错误。将我的数据项更改为包含数据映射数组后,电池使用情况和性能看起来相当不错。这是我现在使用的代码:
DataMap dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + sensorType).getDataMap();
dataMap.putInt(WearConstants.SENSOR, sensorType);
dataMap.putInt(WearConstants.ACCURACY, accuracy);
dataMap.putLong(WearConstants.TIMESTAMP_WEAR, timestamp);
dataMap.putFloatArray(WearConstants.VALUES, values);
dataMaps.add(dataMap);
if(dataMaps.size() > maxMaps) {
final ArrayList dataMapsCopy = (ArrayList) dataMaps.clone();
dataMaps.clear();
Runnable runnable = new Runnable() {
@Override
public void run() {
PutDataMapRequest dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + WearConstants.BATCH);
dataMap.getDataMap().putDataMapArrayList(WearConstants.DATA_ARRAY, dataMapsCopy);
Wearable.DataApi.putDataItem(mApiClient, dataMap.asPutDataRequest()).setResultCallback(new ResultCallback() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d(TAG, "Sending sensor data: " + dataItemResult.getStatus().isSuccess());
}
});
}
};
Thread thread = new Thread(runnable);
thread.start();
}
我正在为 android wear 开发一个应用程序,它正在收集传感器数据(例如加速度,..)并将其与移动设备上的相应应用程序同步 phone。每次触发传感器(onSensorChanged),执行以下代码:
Runnable runnable = new Runnable() {
@Override
public void run() {
PutDataMapRequest dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + sensorType);
dataMap.getDataMap().putInt(WearConstants.ACCURACY, accuracy);
dataMap.getDataMap().putLong(WearConstants.TIMESTAMP_WEAR, timestamp);
dataMap.getDataMap().putFloatArray(WearConstants.VALUES, values);
Wearable.DataApi.putDataItem(mApiClient, dataMap.asPutDataRequest()).setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d(TAG, "Sending sensor data: " + dataItemResult.getStatus().isSuccess());
}
});
}
}; Thread thread = new Thread(runnable); thread.start();
效果很好,传感器数据传输到手机 phone 并显示在应用程序中。该应用程序的第二个功能是可以做笔记。做笔记有两种可能性:a) 在应用程序打开时按下按钮 b) 在应用程序关闭时由 "Ok Google, take a note" 触发。 (参见 Google documentation)
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
startActivityForResult(intent, WearConstants.W_SPEECH);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case WearConstants.W_SPEECH: {
if (resultCode == RESULT_OK && data != null) {
List<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String spokenText = results.get(0);
sendSpeech(spokenText);
}
}
}
}
这也很好用,但前提是应用程序没有监听传感器变化。这就是问题所在:每次我在应用程序(或后台服务)侦听传感器变化时触发语音操作时,都无法识别语音并且我收到错误 "Google not reachable"。在我看来,BluetoothLE 连接的容量不足。因此,我尝试批处理传感器数据(在 ArrayList 中)并在收听语音命令时暂停发送到手机 phone,但没有区别。经过五天的努力寻找解决方案后,我现在有点绝望了:-)我希望你有新的想法或提示接下来要尝试什么。
经过一些额外的研究,我似乎终于找到了解决方案:当我尝试在第一个 运行 中批量处理传感器数据时,我只是暂停了发送。但是当达到我的限制时,我仍然分别发送每个值。那是个大错误。将我的数据项更改为包含数据映射数组后,电池使用情况和性能看起来相当不错。这是我现在使用的代码:
DataMap dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + sensorType).getDataMap();
dataMap.putInt(WearConstants.SENSOR, sensorType);
dataMap.putInt(WearConstants.ACCURACY, accuracy);
dataMap.putLong(WearConstants.TIMESTAMP_WEAR, timestamp);
dataMap.putFloatArray(WearConstants.VALUES, values);
dataMaps.add(dataMap);
if(dataMaps.size() > maxMaps) {
final ArrayList dataMapsCopy = (ArrayList) dataMaps.clone();
dataMaps.clear();
Runnable runnable = new Runnable() {
@Override
public void run() {
PutDataMapRequest dataMap = PutDataMapRequest.create(WearConstants.WTP_SENSOR_DATA_CHANGED + WearConstants.BATCH);
dataMap.getDataMap().putDataMapArrayList(WearConstants.DATA_ARRAY, dataMapsCopy);
Wearable.DataApi.putDataItem(mApiClient, dataMap.asPutDataRequest()).setResultCallback(new ResultCallback() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d(TAG, "Sending sensor data: " + dataItemResult.getStatus().isSuccess());
}
});
}
};
Thread thread = new Thread(runnable);
thread.start();
}