I'm trying to get the accelerometer data, but I'm not able to get it when I want. I want 20 lectures per second more or less, it is not that important. The thing is that I'm receiving way more, like the maximum possible. I've been looking at the documentation, but still I get like 100 actualization per second. Here is the code:
public class MainActivity extends WearableActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAcceSensor;
private final static String TAG = "Wear MainActivity";
private TextView mTextView;
private Button myButton;
private ToggleButton activateSensors;
private int num = 1;
public boolean isOn;
private String datapath = "/message_path";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mTextView = findViewById(R.id.text);
//send a message from the wear. This one will not have response.
myButton = findViewById(R.id.wrbutton);
activateSensors = findViewById(R.id.toggleButton);
activateSensors.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if(isChecked) isOn = true;
else isOn = false;
}
});
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String message = "Hello device " + num;
//Requires a new thread to avoid blocking the UI
new SendThread(datapath, message).start();
num++;
}
});
// Register the local broadcast receiver to receive messages from the listener.
IntentFilter messageFilter = new IntentFilter(Intent.ACTION_SEND);
MessageReceiver messageReceiver = new MessageReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, messageFilter);
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mAcceSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Enables Always-on
setAmbientEnabled();
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAcceSensor,
50000, 50000);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this, mAcceSensor);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
String msg = Float.toString(sensorEvent.values[0]) +","+ Float.toString(sensorEvent.values[1]) +","+ Float.toString(sensorEvent.values[2])+","+getCurrentTimeStamp();
if (isOn){
new SendThread(datapath, msg).start();
}
}
}
public static String getCurrentTimeStamp(){
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentDateTime = dateFormat.format(new Date()); // Find todays date
return currentDateTime;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
(Now a block about sending from one device to the other)
}
As you can see, I have the listener defined as: mSensorManager.registerListener(this, mAcceSensor, 50000, 50000);
That should give me an actualization every 50 milisecond, but I got a lot more.
I've been looking around and I've found reports since 2016 that in WearOS, it doesn't matter the code you try here:
mSensorManager.registerListener(this, mAcceSensor, 50000, 50000);
It doesn't matter if you use
mSensorManager.registerListener(this, mAcceSensor, SensorManager.SENSOR_DELAY_UI);
or mSensorManager.registerListener(this, mAcceSensor, SensorManager.SENSOR_DELAY_FASTEST);
or my code, it always uses the fastest sample rate possible, around 100 Hz.
Galaxy Nexus: Sensor Sampling Rate becomes faster when sampling more Sensors
Android sensor sampling rate won't drow below 60 hz
In the end I opted into a sleazy way:
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
nowDate = new Date();
if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
String msg = Float.toString(sensorEvent.values[0]) +","+ Float.toString(sensorEvent.values[1]) +","+ Float.toString(sensorEvent.values[2]);
if (isOn && (nowDate.getTime() -startDate.getTime()) >= 40){
startDate = nowDate;
String timeStamp = dateFormat.format(nowDate);
msg = msg +","+timeStamp;
new SendThread(datapath, msg).start();
}
}
}
It works, it's not perfect, but it works good enough. It seems like it doesn't matter the value I choose into the if condition, I've tried 40, 50 and 60 and all get almost perfectly 16-17Hz. I've tried also changing from SENSOR_DELAY_UI to SENSOR_DELAY_FASTEST and I get the same results, 16-17Hz consistently, so it's not a matter of choosing.
I hope this helps someone with the same problem, and if there is a more stylish way of doing, I'll be reading.