1

thank you for reading my problem, and hopefully I will get help from you guys. I have LG watch urbane , and the OS is updated to 6.0.1 unfortunately after the update, I have many problems in the applications on my wear. is there any solution that I can rollback or downgrade the Android os to the previous one? or could anyone help me with this code please? I have an application that collects the motion data from Accelerometer and gyroscope wear sensors for five min. I set the timestamp to 20hz per second (so I should get 20 samples per second from each sensor, thus 6000 samples(records) every 5 min). However, after 5 mins, I have got 30,000 samples( records) from Accelerometer sensor, and 6000 from gyroscope sensor, which is exactly what I want , but the problem with Accelerometer sensor. this problem didn't exist with the old OS of the wear. it appeared after the update. before the update of the Wear OS, I was getting the same number of samples from both sensors every five min (6000 records). bellow is the code for the App

package edu.fordham.cis.wisdm.actipebble;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.Vibrator;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.view.WindowManager;
import android.widget.TextView;
import java.util.*;
import java.lang.*;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.common.collect.Lists;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Handles the collection of data and the transmission of the data back to the phone in batches.
 * @author Andrew H. Johnston <a href="mailto:ajohnston9@fordham.edu">ajohnston9@fordham.edu</a>
 * @version 1.0STABLE
 */
public class WearTrainingActivity extends Activity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mGyroscope;
    private TextView mPrompt;
    private TextView      mProgress;

    private GoogleApiClient googleApiClient;

    private ArrayList<AccelerationRecord> mAccelerationRecords = new ArrayList<AccelerationRecord>();
    private ArrayList<GyroscopeRecord> mGyroscopeRecords = new ArrayList<GyroscopeRecord>();

    /**
     * Tells the Sensor if it should save the records it
     */
    private boolean shouldCollect = false;

    /**
     * Debugging tag
     */
    private static final String TAG = "WearTrainingActivity";

    /**
     * One of the strategies to keep the watch screen on
     */
    private PowerManager.WakeLock wakeLock;

    /**
     * Constant used to add clarity to formulae below
     */
    private static final short MILLIS_IN_A_SECOND = 1000;
    /**
     * Change the second (i.e. 2nd) multiplicand to change the number of seconds of data collected
     */
    private int delay  = MILLIS_IN_A_SECOND * 300;
    /**
     * Expressed in a formula so that value makes more sense
     */
    private int maxNumRecords = (delay / MILLIS_IN_A_SECOND) * 20;


    /**
     * Keeps track of the number of records obtained. This is more accurate than a time-based
     * approach.
     */
    private int recordCount   = 0;
    /**
     * Sample rate, expressed as number of microseconds between samplings
     */
    private static final int SAMPLE_RATE = 50000;
    /**
     * Maximum number of records we can send to the phone in one transmission.
     */
    private static final int MAX_RECORDS_SENT_AT_ONCE = 3500;
    /**
     * Flag that signals the end of data transmission to the phone
     */
    private static final String DATA_COLLECTION_DONE = "/thats-all-folks";
 
 private static boolean first = true;
 private static long first_time;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_training);
        //Easy way to keep watch from sleeping on me
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        mProgress = (TextView) findViewById(R.id.txtProgress);
        mPrompt = (TextView) findViewById(R.id.txtPrompt);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mProgress = (TextView) findViewById(R.id.txtProgress);
                mPrompt = (TextView) findViewById(R.id.txtPrompt);
            }
        });
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mGyroscope     = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        //Collect at 20Hz (Once every 50,000 microseconds)
        mSensorManager.registerListener(this, mAccelerometer, SAMPLE_RATE);
        mSensorManager.registerListener(this, mGyroscope, SAMPLE_RATE);
        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle bundle) {
                        Log.d(TAG, "Connected to phone.");
                    }

                    @Override
                    public void onConnectionSuspended(int i) {
                        Log.d(TAG, "Connection to phone suspended. Code: " + i);
                    }
                })
                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult connectionResult) {
                        Log.d(TAG, "Fuck! Connection failed: " + connectionResult);
                    }
                })
                .addApi(Wearable.API)
                .build();
        googleApiClient.connect();
        shouldCollect = true;
        Log.d(TAG, "Started collecting");
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK,
                "WearTrainingWakelock");
        wakeLock.acquire();
    }

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


    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer, SAMPLE_RATE);
        mSensorManager.registerListener(this, mGyroscope, SAMPLE_RATE);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (first) {
   first_time = System.currentTimeMillis();
   first = false;
  }
  if (shouldCollect) {
            long temp1 = System.currentTimeMillis();
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            switch(event.sensor.getType()) {
                case Sensor.TYPE_ACCELEROMETER:
                    mAccelerationRecords.add(new AccelerationRecord(x,y,z,timestamp));
                    recordCount++;
                    break;
                case Sensor.TYPE_GYROSCOPE:
                    GyroscopeRecord gyro = new GyroscopeRecord(x,y,z,timestamp);
                    //Clean up debugging output a little
                    if (recordCount % 10 == 0) {
                        Log.d(TAG, "Record is: " + gyro.toString());
                    }
                    mGyroscopeRecords.add(gyro);
            }
            //recordCount > maxNumRecords
            if (shouldCollect && (System.currentTimeMillis() - first_time >= 5*60*1000)) {
                shouldCollect = false;
                new Thread(new SendDataToPhoneTask()).start();
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //Not used but must be overridden
    }



    class SendDataToPhoneTask implements Runnable {

        @Override
        public void run() {
            Log.d(TAG, "Ending stream");
            try {
                List<List<AccelerationRecord>> accelLists =
                        Lists.partition(mAccelerationRecords, MAX_RECORDS_SENT_AT_ONCE);
                List<List<GyroscopeRecord>> gyroLists =
                        Lists.partition(mGyroscopeRecords, MAX_RECORDS_SENT_AT_ONCE);
                 /* I know the following two for loops look like they could be
                  * abstracted into a single generic method, but due to type erasure
                  * of generics I can't do this with a single polymoprhic method.
                  */
                for (List<AccelerationRecord> list : accelLists) {
                    Log.d(TAG, "Sending list of acceleration records...");
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(baos);
                    ArrayList<AccelerationRecord> tmp = new ArrayList<AccelerationRecord>(list);
                    Log.d(TAG, "List is of size: " + tmp.size());
                    oos.writeObject(tmp);
                    oos.flush();
                    oos.close();
                    byte[] data = baos.toByteArray();
                    PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/accel-data");
                    dataMapRequest.getDataMap().putByteArray("/accel", data);
                    PutDataRequest request = dataMapRequest.asPutDataRequest();
                    PendingResult<DataApi.DataItemResult> pendingResult =
                            Wearable.DataApi.putDataItem(googleApiClient, request);
                }
                //Having a bug where a "that's all" message actually beats the
                //data to the phone, so we'll just attach the message to the last
                //list of data going out
                for (int i = 0; i < gyroLists.size(); ++i) {
                    List<GyroscopeRecord> list = gyroLists.get(i);
                    Log.d(TAG, "Sending list of gyroscope records...");
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ObjectOutputStream oosG = new ObjectOutputStream(baos);
                    ArrayList<GyroscopeRecord> tmp = new ArrayList<GyroscopeRecord>(list);
                    Log.d(TAG, "List is of size: " + tmp.size());
                    oosG.writeObject(tmp);
                    oosG.flush();
                    oosG.close();
                    byte[] data = baos.toByteArray();
                    PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/gyro-data");
                    dataMapRequest.getDataMap().putByteArray("/gyro", data);
                    if ((i+1) == gyroLists.size()) {
                        dataMapRequest.getDataMap().putString("/done", DATA_COLLECTION_DONE);
                    } else {
                        dataMapRequest.getDataMap().putString("/done", "/not-done");
                    }
                    PutDataRequest request = dataMapRequest.asPutDataRequest();
                    PendingResult<DataApi.DataItemResult> pendingResult =
                            Wearable.DataApi.putDataItem(googleApiClient, request);
                }
                //Vibrate and tell the user to check their phone
                Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
                vibrator.vibrate(500L); //Vibrate for half a second
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mPrompt.setText("Please finish the training by opening your phone.");
                        mProgress.setText("");
                    }
                });
            } catch (IOException e) {
                Log.d(TAG, "Something fucky happened: " + e.getMessage());
            } finally {
                //Screen can turn off now.
                wakeLock.release();
            }

        }
    }
}
neamah
  • 31
  • 1
  • 1
  • 2

0 Answers0