Java 在Android Wear smartwatch上获取和存储加速计数据
我正在尝试使用智能手表(三星Gear Live)上的Android Wear应用程序获取加速度计数据。为了获取这些数据,我使用了一个监听三个组件的服务:Java 在Android Wear smartwatch上获取和存储加速计数据,java,android-activity,android-service,wear-os,android-sensors,Java,Android Activity,Android Service,Wear Os,Android Sensors,我正在尝试使用智能手表(三星Gear Live)上的Android Wear应用程序获取加速度计数据。为了获取这些数据,我使用了一个监听三个组件的服务: SensorEventListener,其中onSensorChanged方法触发SensorEventLoggerTask,该任务将带有时间戳的加速计数据存储在smartwatch上的文件中 监听电池的系统意图 侦听活动上的按钮单击的意图。活动用于注释数据,因此我知道(人)活动(跑步、吃饭、睡觉等)开始的时间戳: 这工作正常,我可以每隔5-6
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;
}
}
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;
}
}
}
WearableService.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;
}
}
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;
}
}
}
公共类WearableService扩展服务实现SensorEventListener{
私人印刷品;
私人打印流ps_bat;
私有打印流ps_按钮;
私有字符串androidpath;
私有浮动[]重力=新浮动[3];
私有浮点[]线性_加速度=新浮点[3];
私人电力经理;
私有PowerManager.WakeLock wl;
私人传感器管理器;
专用传感器;
//创建服务并注册侦听器
@凌驾
public void onCreate(){
super.onCreate();
this.registerListeners();
}
//将传感器管理器、监听器注册到电池和目标
私有无效注册表侦听器(){
mSensorManager=(SensorManager)this.getSystemService(SENSOR\u服务);
macceleronsor=mSensorManager.getDefaultSensor(Sensor.TYPE_加速计);
msSensorManager.registerListener(这是mAcceleroSensor,SensorManager.SENSOR\u DELAY\u最快);
IntentFilter ifilter=新的IntentFilter(Intent.ACTION\u电池\u已更改);
Intent batteryStatus=此寄存器接收器(电池接收器,ifilter);
这个.registerReceiver(广播接收器,新意图过滤器(“按钮活动”);
}
//在第一时间开始服务
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
Toast.makeText(这是“服务启动”,Toast.LENGTH_SHORT).show();
这个.getFile();
pm=(PowerManager)getSystemService(Context.POWER\u服务);
PowerManager.WakeLock wl=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|
PowerManager.ACQUIRE|u导致|u唤醒|
PowerManager.ON_发布后,“KeepCPUWorking”);
wl.acquire();
return Service.START\u STICKY;
}
//当传感器值发生变化时
传感器更改时的公共无效(传感器事件){
if(event.sensor.getType()==sensor.TYPE\u加速计){
//执行后台任务以存储数据
新建SensorEventLoggerTask().execute(事件);
}
}
//获取必须存储数据的文件的句柄
public void getFile(){
androidpath=Environment.getExternalStorageDirectory().toString();
试一试{
ps=新的打印流(新文件输出流(androidpath+“/data_acc.dat”);
ps_bat=newprintstream(newfileoutputstream(androidpath+“/data_bat.dat”);
ps_button=newprintstream(newfileoutputstream(androidpath+“/data_button.dat”);
}捕获(例外e){
e、 printStackTrace();
}
}
//创建侦听来自电池的意图的接收器
专用广播接收器电池\接收器=新广播接收器(){
@凌驾
公共void onReceive(上下文arg0,意图arg1){
int bLevel=arg1.getIntExtra(“级别”,-1);//获取电池电量
int bScale=arg1.getIntExtra(“比例”,-1);
ps_bat.println(“+System.currentTimeMillis()+”;“+bLevel+”;“+bScale”);
}
};
@凌驾
公共空间{
如果(wl.ishell())wl.release();
}
//用于接收按钮的广播事件。
专用广播接收器BroadcastReceiver=新建
广播接收机(){
@凌驾
public void onReceive(上下文、意图){
字符串msg=intent.getStringExtra(“按钮”)+;“+intent.getStringExtra(“时间”);
ps_按钮。打印项次(msg);
}
};
//创建将事件记录到文件的任务
私有类SensorEventLoggerTask扩展了AsyncTask{
@凌驾
受保护的无效doInBackground(传感器事件…事件){
//获取事件和值
SensorEvent=事件[0];
字符串msg=”“+事件值[0]+”;“+事件值[1]+”;“+事件值[2];
//构建生产线
msg=”“+System.currentTimeMillis()+“;”+msg;
//写入文件
ps.println(msg);
返回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>`
`
`
这确实是一个有趣的问题,我可能还需要解决它。如果我提出了一个好的解决方案,我会把它作为一个答案发布。