在Android Wear智能手表上获取和存储加速计数据

时间:2015-02-19 16:01:09

标签: java android-activity android-service wear-os android-sensors

我试图在智能手表(Samsung Gear Live)上使用Android Wear应用获取加速度计数据。为了获取该数据,我使用了一个侦听三个组件的服务:

  1. 一个SensorEventListener,其中onSensorChanged方法触发一个SensorEventLoggerTask,它将带有时间戳的加速度计数据存储在smartwatch上的文件中
  2. 监听电池的系统意图
  3. 侦听按钮点击活动的Intent。该活动用于注释数据,因此我知道什么时间戳(人)活动(跑步,吃饭,睡觉......)开始:
  4. 这很好用,我可以每隔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>`
    

0 个答案:

没有答案