我试图在智能手表(Samsung Gear Live)上使用Android Wear应用获取加速度计数据。为了获取该数据,我使用了一个侦听三个组件的服务:
这很好用,我可以每隔5-6毫秒(或多或少)对数据进行采样。但是,这仅适用于通过adb连接智能手表或活动处于活动状态时(按下按钮)。从它不再连接的那一刻起,数据就会出现空白。对于间隙,我的意思是加速度计值的两个时间戳之间的时间远大于5-6 ms。走到几秒......间隙似乎不规则。但是当活动变为活动状态(按下按钮)或我将智能手表连接到adb时,会收集值。当智能手表未激活时,服务似乎暂停/休眠/关闭。
下面我发布了代码。该项目由两个类WearableActivity和WearableService组成。此外,我还展示了清单。尽管这只是原型代码,但是在解决数据差距或代码建议方面的任何帮助都将不胜感激。
WearableActivity.java
public class WearableActivity extends Activity {
//Set strings and widgets
private static final String TAG = "WearableActivity";
private TextView mTextView;
private Button[] buttons;
private String[] strings;
@Override
protected void onCreate(Bundle savedInstanceState) {
//setscreen
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wearable);
//check if service is already running
if(this.check() == false)
this.startService(new Intent(this, WearableService.class));
Resources res = this.getResources();
strings = res.getStringArray(R.array.button_names);
buttons = new Button[strings.length];
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);
mTextView.setText("ActiMon_Store Started");
buttons[0] = (Button)stub.findViewById(R.id.button1);
buttons[1] = (Button)stub.findViewById(R.id.button2);
buttons[2] = (Button)stub.findViewById(R.id.button3);
buttons[3] = (Button)stub.findViewById(R.id.button4);
buttons[0].setText(strings[0]);
buttons[1].setText(strings[1]);
buttons[2].setText(strings[2]);
buttons[3].setText(strings[3]);
for(Button b : buttons)
b.setOnClickListener(btnListener);
}
});
}
//---create an anonymous class to act as a button click listener---
private OnClickListener btnListener = new OnClickListener()
{
public void onClick(View v)
{
Intent buttonIntent = new Intent("button_activity");
Button b = (Button)v;
buttonIntent.putExtra("time", Long.toString(System.currentTimeMillis()));
buttonIntent.putExtra("button", b.getText().toString());
sendBroadcast(buttonIntent);
Toast.makeText(getApplicationContext(),
"Event sent", Toast.LENGTH_LONG).show();
}
};
//Checks is the service WearableService already started
public boolean check(){
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
{
if ("com.example.WearableService"
.equals(service.service.getClassName()))
{
Log.i(TAG,"Service already running!");
return true;
}
}
Log.i(TAG,"Service already running!");
return false;
}
}
WearableService.java
public class WearableService extends Service implements SensorEventListener {
private PrintStream ps;
private PrintStream ps_bat;
private PrintStream ps_button;
private String androidpath;
private float[] gravity = new float[3];
private float[] linear_acceleration = new float[3];
private PowerManager pm;
private PowerManager.WakeLock wl;
private SensorManager mSensorManager;
private Sensor mAcceleroSensor;
//Create the service and register the listeners
@Override
public void onCreate(){
super.onCreate();
this.registerListeners();
}
//Registers the SensorManager, the listener to the battery and the intent
private void registerListeners(){
mSensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
mAcceleroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this,mAcceleroSensor,SensorManager.SENSOR_DELAY_FASTEST);
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(battery_receiver, ifilter);
this.registerReceiver(broadcastReceiver, new IntentFilter("button_activity"));
}
//Start service as at STICKY
@Override
public int onStartCommand(Intent intent, int flags, int startId){
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
this.getFile();
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE,"KeepCPUWorking");
wl.acquire();
return Service.START_STICKY;
}
//When sensor value has changed
public void onSensorChanged(SensorEvent event){
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
//Perform a background task to store the data
new SensorEventLoggerTask().execute(event);
}
}
//Get handles to files where data has to be stored
public void getFile(){
androidpath = Environment.getExternalStorageDirectory().toString();
try{
ps = new PrintStream(new FileOutputStream(androidpath + "/data_acc.dat"));
ps_bat = new PrintStream(new FileOutputStream(androidpath + "/data_bat.dat"));
ps_button = new PrintStream(new FileOutputStream(androidpath + "/data_button.dat"));
} catch (Exception e){
e.printStackTrace();
}
}
//Create receiver that listens to Intents from the Battery
private BroadcastReceiver battery_receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
int bLevel = arg1.getIntExtra("level", -1); // gets the battery level
int bScale = arg1.getIntExtra("scale", -1);
ps_bat.println("" + System.currentTimeMillis() + ";" + bLevel + ";" + bScale);
}
};
@Override
public void onDestroy(){
if(wl.isHeld()) wl.release();
}
// For receiving the broadcast event of the buttons.
private BroadcastReceiver broadcastReceiver = new
BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("button") + ";" + intent.getStringExtra("time");
ps_button.println(msg);
}
};
//Create a Task that logs events to a file
private class SensorEventLoggerTask extends AsyncTask<SensorEvent, Void, Void>{
@Override
protected Void doInBackground(SensorEvent... events) {
//Getting the event and values
SensorEvent event = events[0];
String msg = "" + event.values[0] + ";" + event.values[1] + ";" + event.values[2];
//constructing the the line
msg = "" + System.currentTimeMillis() + ";" + msg;
//writing to file
ps.println(msg);
return null;
}
}
}
的Manifest.xml
`<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wearabledemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:name="android.hardware.type.watch" />
<uses-sdk
android:minSdkVersion="20"
android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".WearableActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:name=".WearableService"
android:label="@string/app_name"
android:exported="true"
android:permission="android.permission.WAKE_LOCK" >
</service>
</application>
</manifest>`