I am having problems accessing heart rate sensor on Moto 360.
I tried following things :
Sensor mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
mSensorManager.registerListener(this, mHeartRateSensor, SensorManager.SENSOR_DELAY_NORMAL);
and then implement SensorEventListener interface :
#Override
public void onSensorChanged(SensorEvent event) {
String TAG = "tag";
Log.i(TAG, "--------------------------");
Log.i(TAG, msg);
Log.i(TAG, ""+ event.sensor.getType());
Log.i("live","--------------");
And what is strange to me I do not get any messages at all (not only heart rate).
Also I tried listing all sensors and it does not show Heart rate sensor on the list.
Of course I've added persmissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.watchtest" >
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
Any ideas ?
thanks.
w.
Started to work for me after I did the following:
Uninstalled my app from the watch with
adb -s localhost:4444 uninstall com.example.android.wearable.jumpingjack
Added permissions to get the heart rate sensor
<uses-permission android:name="android.permission.BODY_SENSORS"/>
Set the min and target SDK version to match the watch
android:minSdkVersion="20" android:targetSdkVersion="20"
Started the app again. I received the heart rate sensor with Sensor.TYPE_HEART_RATE and I started to receive its readings. Although they were far from good. There were a lot of readings, but they were just the same, limited to these 5 values:
heartRate onSensorChanged values = [0.0], accuracy = 0, sensor = {Sensor name="Heart Rate Sensor", vendor="Motorola", version=1, type=21, maxRange=65535.0, resolution=1.0, power=0.45, minDelay=0}
heartRate onSensorChanged values = [53.0], accuracy = 2, sensor = {Sensor name="Heart Rate Sensor", vendor="Motorola", version=1, type=21, maxRange=65535.0, resolution=1.0, power=0.45, minDelay=0}
heartRate onSensorChanged values = [54.0], accuracy = 2, sensor = {Sensor name="Heart Rate Sensor", vendor="Motorola", version=1, type=21, maxRange=65535.0, resolution=1.0, power=0.45, minDelay=0}
heartRate onSensorChanged values = [55.0], accuracy = 2, sensor = {Sensor name="Heart Rate Sensor", vendor="Motorola", version=1, type=21, maxRange=65535.0, resolution=1.0, power=0.45, minDelay=0}
heartRate onSensorChanged values = [77.0], accuracy = 1, sensor = {Sensor name="Heart Rate Sensor", vendor="Motorola", version=1, type=21, maxRange=65535.0, resolution=1.0, power=0.45, minDelay=0}
Most of the time I was getting the same 53.0 value which doesn't seem to be my real heart rate. 77 could have been the one.
I had quite a similar problem on the Moto 360. The sensor always returned 0.0f as a value.
Then I waited for two minutes, and suddenly values!=0 came in. It seems that this sensor needs a "warmup" before showing anything. Not really astonishing if you take into account that it measures something happening roughly once a second with the unit "beats per minute". It cannot be reliable before one or two minutes have passed. And each app has its own measurement: It doesn't matter if another heartbeat app is also running (like the Moto Body thing).
This also means that you must create a service to listen to the sensor (and a binder to pass the sensor's value to your activity or your phone).
Have a look at the demo project I shared on github:
https://github.com/upost/MyHeartbeat
As #Kent and #Murphy suggested, updated SDK was the solution. In my case I needed to drop the project and create new from scratch as even with updated SDK old one did not work.
So, I came here, with the same problem and the simple solution is to remove the application from the watch using the adb:
adb -s localhost:4444 uninstall com.*packagename*
Then simply reinstall it using android studio, eclipse or whatever you used originally.
Thanks to Alexander K for this solution
Related
I have an Xperia Z phone which runs Android 5.1 on.
When checking the sensors that are present I get the below results:
mSensorAccelerometer: {Sensor name="MPL Accelerometer", vendor="Invensense", version=1, type=1, maxRange=19.6133, resolution=0.038344003, power=0.139, minDelay=5000}
mSensorLinearAcceleration: {Sensor name="MPL Linear Acceleration", vendor="Invensense", version=1, type=10, maxRange=19.6133, resolution=0.038344003, power=16.239, minDelay=5000}
mSensorSignificantMotion: null
mSensorStepDetector: null
mSensorStepCounter: null
So, there are a physical Accelerometer and a Linear Acceleration composite sensors.
Signification Sensor, Step Detector and Step Counter composite sensors seem as not present. However the documentation writes that Underlying physical sensor: Accelerometer for these three sensors.
Is there any chance to use these three sensors?
Why do they seem as null although they are software-based (virtual) sensors?
I am able to access Heart Rate of User using Optical Heart rate Sensor using SensorEventListener:
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE),
SensorManager.SENSOR_DELAY_NORMAL);
What I need is to get raw PPG data like:
https://ars.els-cdn.com/content/image/1-s2.0-S0960077915001344-gr1.jpg
Through Google Fit or any other means can I get this data?
I looked into Google Fit API usage:
https://developers.google.com/fit/android/sensors
It gives TYPE_HEART_RATE_BPM and HEART_RATE_SUMMARY , but not PPG raw data.
I spent some time figuring out if it's feasible to get the raw PPG signal from android API, and contrary to what some may say, it is definitely possible to do that. And here is how to do it:
1- Get the sensor type (represented by a number) of your PPG sensor (it is a constant that describes the sensor). This can be done by listing all the available sensors on your device:
List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor currentSensor : sensorList) {
Log.d("List sensors", "Name: "+currentSensor.getName() + " /Type_String: " +currentSensor.getStringType()+ " /Type_number: "+currentSensor.getType());
}
2- Then, try to find the sensorType of your PPG sensor. In your output, you will find one of the sensors containing the word ppg in it's type. For instance here is what the ppg sensor of my Huawei watch 2 looks like:
Name: AFE4405 light Sensor /Type_String: com.huawei.watch.ppg /Type_Number: 65537
3-Register your listener using the the type_number of your ppg sensor, mine is 65537 so I would do this:
sensorManager.registerListener(this,sensorManager.getDefaultSensor(65537),SensorManager.SENSOR_DELAY_NORMAL);
4-Listen to changes in your sensor data:
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == 65537) {
String msg = "PPG " + (int) event.values[0];
//Do something with your PPG signal
}
}
And you are all set. Hope it works for you.
D5 runs Android 4.4
I want to measure the heart rate, but standard way of registerListener is not working (not hardware problem, with inbuilt app is working).
I get all sensors from device and i found this:
{Sensor name="ULPSH Heart Rate M", vendor="QuickLogic Inc", version=1, type=87, maxRange=100.0, resolution=1.0, power=1.1, minDelay=0}
In android.hardware.Sensor i don't found this type id 87 so i tried the following:
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mHeartRate = mSensorManager.getDefaultSensor(87);
mSensorManager.registerListener(this, mHeartRate, SensorManager.SENSOR_DELAY_NORMAL);
....
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == 87) {
//do something
}
}
but unfortunately is not working, the measurement is not getting started.
I tried this code with another sensor (Step Counter, type 19) that works well.
Any idea what I'm doing wrong?
I have the same problem. I think the problem is the firmware. You also can't get access to gyro, barometer and etc.
I found in the Launcher app how you can access the last heart rate.
System.getInt(getContentResolver(), "last_heart_rate", 0);
I am using ACCELEROMETER sensors and have registered a listener for the same via
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAcceleratorSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAcceleratorSensor , SensorManager.SENSOR_DELAY_NORMAL);
This is how my onSensorChanged looks like
#Override
public final void onSensorChanged(SensorEvent event) {
int sensorType = event.sensor.getType();
switch(sensorType){
case Sensor.TYPE_ACCELEROMETER:
float valueX = event.values[0];
float valueY = event.values[1];
float valueZ = event.values[2];
Log.d(TAG, "Sensor Changed value:"+valueX+":"+valueY+":"+valueZ);
break;
}
However this is what I see in my logs
01-12 02:01:18.063 19691-19691/com.taxis.locationupdates2 D/LocationActivity: Sensor Changed value:2.0:2.0:2.0
01-12 02:01:18.129 19691-19691/com.taxis.locationupdates2 D/LocationActivity: Sensor Changed value:2.0:2.0:2.0
It keeps calling the onSensorChanged in infinite loop even though there is no change in the values. I havent tested it with a real device yet. Is there any settings to control the same.
That method is very poorly named.
From the android docs for onSensorChanged:
Called when there is a new sensor event. Note that "on changed" is
somewhat of a misnomer, as this will also be called if we have a new
reading from a sensor with the exact same sensor values (but a newer
timestamp).
The sensor documentation has the details about the same
http://developer.android.com/guide/topics/sensors/sensors_overview.html
The default data delay is suitable for monitoring typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other data delays, such as SENSOR_DELAY_GAME (20,000 microsecond delay), SENSOR_DELAY_UI (60,000 microsecond delay), or SENSOR_DELAY_FASTEST (0 microsecond delay). As of Android 3.0 (API Level 11) you can also specify the delay as an absolute value (in microseconds).
The delay that you specify is only a suggested delay. The Android system and other applications can alter this delay. As a best practice, you should specify the largest delay that you can because the system typically uses a smaller delay than the one you specify (that is, you should choose the slowest sampling rate that still meets the needs of your application). Using a larger delay imposes a lower load on the processor and therefore uses less power.
I have developed a few apps for the SmartWatch 1 that take advantage of the watch's gyroscope. I finally got a SmartWatch 2 to develop on, but I notice that the gyroscope is way less responsive. For instance on the SmartWatch 1 it seems that every movement no matter how slight is recorded. However on the SmartWatch 2 the readings seem to run on a 100 millisecond timer. Here is how I interact with the sensor:
private final AccessorySensorEventListener mListener = new AccessorySensorEventListener() {
public void onSensorEvent(AccessorySensorEvent mySensorEvent) {
sensorEvent = mySensorEvent;
float[] values = sensorEvent.getSensorValues();
currentX = values[0];
currentY = values[1];
currentZ = values[2];
}
}
I have also tried different variations for registering my sensor:
mSensor.registerInterruptListener(mListener);
-- and --
mSensor.registerListener(mListener, Sensor.SensorRates.SENSOR_DELAY_FASTEST, Sensor.SensorInterruptMode.SENSOR_INTERRUPT_DISABLED);
-- and --
mSensor.registerFixedRateListener(mListener, Sensor.SensorRates.SENSOR_DELAY_FASTEST);
All of these seem to give the same exact effect. Am I doing this wrong for the SmartWatch 2, or is the gyroscope in the SmartWatch 2 really just less responsive?
There isn't a gyroscope in the SmartWatch 2, but there is an accelerometer. The accelerometer is limited to a 10Hz sampling rate. This is why you are only seeing 10 samples per second. I don't know of any way to increase the rate any higher.
There is additional info in this post: Sony Smartwatch SW2 - accelerometer output rate