accelerometer - Android可以穿戴连续传感加速度计和陀螺数据

  显示原文与译文双语对照的内容
0 0

我正在开发一个将运行在可以穿戴( 智能手表 3 ) 和手持( 三星 S5 ) 上的应用。

我想对加速度计和陀螺数据进行连续的监测,并将数据保存并保存到手持设备上。

我想知道哪种方法是最好的实现方法。 目前我正在使用 DataApi

由于加速度计和陀螺数据采样速率很高,而且可以穿戴的应用将数据连续发送到电话。

这是手表上的Activity:


public class MyActivity extends Activity implements SensorEventListener{

 private TextView mTextView;
 private TextView textViewGyro;
 private SensorManager mSensorManager;
 private GoogleApiClient mGoogleApiClient;
 private String mNode;
 private float x,y,z;
 private float gx,gy,gz;
 private final String TAG = MyActivity.class.getName();
 private final float GAIN = 0.9f;
 public static final float EPSILON = 0.000000001f;
 String WEARABLE_DATA_PATH ="/wearable_data";
//String WEARABLE_GYROSCOPE_PATH ="/wearable_gyroscope";


 @Override
 protected void onCreate(Bundle savedInstanceState) {

 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_my);
 final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
 stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
 @Override
 public void onLayoutInflated(WatchViewStub stub) {
 mTextView = (TextView) stub.findViewById(R.id.text);
 textViewGyro= (TextView) stub.findViewById(R.id.textgyro);
 }
 });

 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

 mGoogleApiClient = new GoogleApiClient.Builder(this)
. addApi(Wearable.API)
. addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
 @Override
 public void onConnected(Bundle bundle) {
 Log.d(TAG,"onConnected");
 Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
 @Override
 public void onResult(NodeApi.GetConnectedNodesResult nodes) { 
 if (nodes.getNodes().size()> 0) {
 mNode = nodes.getNodes().get(0).getId();
 Log.e("Wearable","Device found");
 Log.e("Wearable",mNode);
 }
 }
 });
 }

 @Override
 public void onConnectionSuspended(int i) {
 Log.d(TAG,"onConnectionSuspended");

 }
 })
. addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
 @Override
 public void onConnectionFailed(ConnectionResult connectionResult) {
 Log.d(TAG,"onConnectionFailed :" + connectionResult.toString());
 }
 })
. build();
 }

 @Override
 protected void onResume() {
 super.onResume();

 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

 mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);

 Sensor sensor1 = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
 mSensorManager.registerListener(this, sensor1, SensorManager.SENSOR_DELAY_NORMAL);

 mGoogleApiClient.connect();
 }

 @Override
 protected void onPause() {
 super.onPause();
 mSensorManager.unregisterListener(this);
 mGoogleApiClient.disconnect();
 }

 @Override
 public void onSensorChanged(SensorEvent event) {
 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
 x = (x * GAIN + event.values[0] * (1 - GAIN));
 y = (y * GAIN + event.values[1] * (1 - GAIN));
 z = (z * GAIN + event.values[2] * (1 - GAIN));

 if (mTextView!= null) mTextView.setText(String.format("n" +"Accelerometer Data: nX : %fnY : %fnZ : %fn",x, y, z));

 DataMap dataMap = new DataMap();
 dataMap.putLong("timestamp", new Date().getTime());
 dataMap.putFloat("ax",x);
 dataMap.putFloat("ay",y);
 dataMap.putFloat("az",z);

 new SendToDataLayerThread(WEARABLE_DATA_PATH, dataMap).start();

 }

 if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
 gx = event.values[0];
 gy = event.values[1];
 gz = event.values[2];

 float omegaMagnitude = (float)java.lang.Math.sqrt(gx*gx + gy*gy + gz*gz);

//Normalize the rotation vector if it's big enough to get the axis
//(that is, EPSILON should represent your maximum allowable margin of error)
 if (omegaMagnitude> EPSILON) {
 gx/= omegaMagnitude;
 gy/= omegaMagnitude;
 gz/= omegaMagnitude;
 }

 if (textViewGyro!= null)
 textViewGyro.setText(String.format("nGyroscope Data: nX : %fnY : %fnZ : %fn", gx, gy, gz));

 DataMap dataMap = new DataMap();
 dataMap.putLong("timestamp", new Date().getTime());
 dataMap.putFloat("gx",gx);
 dataMap.putFloat("gy",gy);
 dataMap.putFloat("gz",gz);

 new SendToDataLayerThread(WEARABLE_DATA_PATH, dataMap).start();
 }
 }

 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {

 }

 class SendToDataLayerThread extends Thread {
 String path;
 DataMap dataMap;

//Constructor for sending data objects to the data layer
 SendToDataLayerThread(String p, DataMap data) {
 path = p;
 dataMap = data;
 }

 public void run() {
 NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
 for (Node node : nodes.getNodes()) {

//Construct a DataRequest and send over the data layer
 PutDataMapRequest putDMR = PutDataMapRequest.create(path);
 putDMR.getDataMap().putAll(dataMap);
 PutDataRequest request = putDMR.asPutDataRequest();
 DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleApiClient,request).await();
 if (result.getStatus().isSuccess()) {
 Log.e("myTag","DataMap:" + dataMap +" sent to:" + node.getDisplayName());
 } else {
//Log an error
 Log.e("myTag","ERROR: failed to send DataMap");
 }
 }
 }
 }
}

我是 Having 以下例外和错误:


02-13 02:06:37.777 17349-17360/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (su@357af50)

02-13 02:24:09.300 594-685/? D/WearableService? putData: exception during processing: PutDataRequest[dataSz=67, numAssets=0, uri=wear:/wearable_gyroscope]
 android.os.DeadObjectException

02-13 02:24:09.108 594-685/? D/WearableService? getConnectedNodes: exception during processing
 android.os.DeadObjectException

android.system.ErrnoException: read failed: EAGAIN (Try again)
 at libcore.io.Posix.readBytes(Native Method)
 at libcore.io.Posix.read(Posix.java:147)
 at libcore.io.BlockGuardOs.read(BlockGuardOs.java:230)
 at android.system.Os.read(Os.java:364)
 at com.android.server.am.NativeCrashListener.consumeNativeCrashData(NativeCrashListener.java:240)
 at com.android.server.am.NativeCrashListener.run(NativeCrashListener.java:138)
02-13 15:46:29.977 150-150/? E/DEBUG? AM write failure (32/Broken pipe)
02-13 15:46:34.704 21570-21581/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (su@35563df0)

02-13 11:14:44.482 12012-12012/? E/AndroidRuntime? FATAL EXCEPTION: main
 Process: com.example.fazlay.accelerometerwearable, PID: 12012
 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
 at java.lang.Thread.nativeCreate(Native Method)
 at java.lang.Thread.start(Thread.java:1063)
 at com.example.fazlay.accelerometerwearable.MyActivity.onSensorChanged(MyActivity.java:168)
 at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:405)
 at android.os.MessageQueue.nativePollOnce(Native Method)
 at android.os.MessageQueue.next(MessageQueue.java:143)
 at android.os.Looper.loop(Looper.java:122)
 at android.app.ActivityThread.main(ActivityThread.java:5221)
 at java.lang.reflect.Method.invoke(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:372)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

02-13 15:52:47.934 424-464/? E/ActivityManager? ANR in com.example.fazlay.accelerometerwearable (com.example.fazlay.accelerometerwearable/.MyActivity)
 PID: 0
 Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 6. Wait queue head age: 13150.8ms.)


02-13 16:19:23.999 24797-24797/? E/AndroidRuntime? FATAL EXCEPTION: main
 Process: com.example.fazlay.accelerometerwearable, PID: 24797
 java.lang.IllegalStateException: await must not be called on the UI thread
 at com.google.android.gms.internal.jx.a(Unknown Source)
 at com.google.android.gms.common.api.BaseImplementation$AbstractPendingResult.await(Unknown Source)
 at com.example.fazlay.accelerometerwearable.MyActivity.onSensorChanged(MyActivity.java:171)
 at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:405)
 at android.os.MessageQueue.nativePollOnce(Native Method)
 at android.os.MessageQueue.next(MessageQueue.java:143)
 at android.os.Looper.loop(Looper.java:122)
 at android.app.ActivityThread.main(ActivityThread.java:5221)
 at java.lang.reflect.Method.invoke(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:372)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

时间: 原作者:

0 0

看一下Github项目 SensorDashboard,他们接收所有传感器数据并通过 MessageAPI 将它传递到移动设备。 我觉得它工作得很好。 我记得他们使用某种上限来限制正在发送的数据量。

原作者:
...