gpt4 book ai didi

android - Android 可穿戴设备上加速度计和陀螺仪数据的连续感知

转载 作者:太空狗 更新时间:2023-10-29 14:10:54 26 4
gpt4 key购买 nike

我正在开发一款可在可穿戴设备(Sony Smart Watch 3)和手持设备(Samsung S5)上运行的应用程序。

我想持续从 watch 中感应加速度计和陀螺仪数据,并将数据发送并保存到手持设备。

我想知道实现此目标的最佳方法是什么。目前我正在使用 DataApi

由于加速度计和陀螺仪数据采样率足够高,并且可穿戴设备上的应用程序不断向手机发送数据,因此分配了太多内存,然后被操作系统杀死。

这是 watch 上的 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 : %f\nY : %f\nZ : %f\n",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 : %f\nY : %f\nZ : %f\n", 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");
}
}
}
}
}

我有以下异常和错误:

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)

最佳答案

看看Github项目SensorDashboard ,他们接收所有传感器数据并通过 MessageAPI 将其传递到手机。我认为它工作得很好。据我所知,他们使用某种上限来限制发送的数据量。

关于android - Android 可穿戴设备上加速度计和陀螺仪数据的连续感知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28512138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com