I am trying to read both gyroscope and linear_acclerometer data in the highest sample rate on my Moto 360 . I will press a button on the handheld, which will register sensors on the watch and start loggging all the sensor data, and when I press another button, the watch will unregister these sensors and stop logging.
However, the sensor value will become a constant value sometimes. I found if I restart the watch, the sensor will start working and generate meaningful sensor value again.
Does anyone has encounter the similar problem or have some ideas on why this may happen ?
private void startSensorListeners() {
Log.d(TAG, "startSensorListeners");
isCollecting = true;
//Register the motion Sensor Listener
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SENSOR_DELAY);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SENSOR_DELAY);
}
public void stopSensorListeners() {
isCollecting = false;
mSensorManager.unregisterListener(this);
}
public final void onSensorChanged(SensorEvent event) {
if(!isCollecting){
mSensorManager.unregisterListener(this, event.sensor);
return ;
}
// Save sensordata into local files, I also output the values[] in event on the logcat to monitor the sensor values in the realtime.
saveData(event);
}
Thanks
I don't have an actual answer for this. I'm just sharing my problem because I feel like they are very similar. The problem occurs on a Moto 360 and was not tested on another device.
I use the Magnetic sensor.
mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
I register my Fragment as a listener to new values.
mSensorManager.registerListener(this, mMagneticSensor, SensorManager.SENSOR_DELAY_NORMAL);
I was developing an application. At the beginning, they were changing as expected but, after ~an hour, the values from the sensor just froze, remaining exactly the same no matter what.
I suspect two things: battery level and data rate renewal.
Maybe the battery dropped below some acceptable level (was around 25% when it stopped working)... it would be weird but it would not a big surprise.
Secondly, I remember having changed SensorManager.SENSOR_DELAY_NORMAL) to SensorManager.SENSOR_DELAY_UI) at some point, not long before the values froze. Perhaps it's a coincidence. The SensorManager.SENSOR_DELAY_UI is a faster data rate renewal than SensorManager.SENSOR_DELAY_NORMAL and as I was modifying a bitmap each time I got a new value. Maybe a buffer was full and wasn't emptied...maybe
Anyway, if I got some news on this subject I will update this post.
Related
I bought a Huawei Watch 2 because I'm working on an app that reads steps and heart rate.
Before opting for the Google Fitness API, I wanted to try accessing raw data directly from the watch sensors.
The heart rate sensor doesn't seem to be working no matter what i try. I've already put "uses-permission android:name="android.permission.BODY_SENSORS"" in my AndroidManifest file. My main activity extends the WearableActivity class and implements the SensorEventListener interface.
This is what I have in the onCreate() method regarding sensors:
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorSteps = mSensorManager.getDefaultSensor(TYPE_STEP_COUNTER);
mSensorHeart = mSensorManager.getDefaultSensor(TYPE_HEART_RATE);
String sensor_error = getResources().getString(R.string.error_no_sensor);
if (mSensorSteps == null) {
mTextSensorSteps.setText(sensor_error);
}
if (mSensorHeart == null) {
mTextSensorHeart.setText(sensor_error);
}
There is a string resource that says "No Sensor" if it can't detect the sensor, and both the step and heart rate sensors have their own textviews, mTextSensorSteps and mTextSensorHeart.
In the onStart() and onStop() methods I've registered and unregistered the listeners for the sensors.
Here's what I have in the onSensorChanged() method (the onAccuracyChanged() method is empty):
#Override
public void onSensorChanged(SensorEvent event) {
int sensorType = event.sensor.getType();
float currentValue = event.values[0];
switch (sensorType) {
case Sensor.TYPE_STEP_COUNTER:
// Event came from the steps sensor.
mTextSensorSteps.setText(getResources().getString(R.string.steps_label, currentValue));
break;
case Sensor.TYPE_HEART_RATE:
// Event came from the heart rate sensor.
mTextSensorHeart.setText(getResources().getString(R.string.heart_label, currentValue));
break;
default:
// do nothing
}}
These are my string resources:
<string name="error_no_sensor">No Sensor</string>
<string name="heart_label">Heart: %1$.2f</string>
<string name="steps_label">Steps: %1$.2f</string>
The code works for every sensor except for the heart rate sensor. If it is a sensor not present in the watch, I get a "No Sensor" error. If I try it with the gyroscope it works. If I try it with the accelerometer it works. When I write TYPE_HEART_RATE, the textview just shows "Heart: %1$.2f".
I even tried using the number IDs of the sensors instead of the names, I know that TYPE_STEP_COUNTER is 19 and TYPE_HEART_RATE is 21. Same result: it works with steps, gyroscope (I think its ID is 4 or something like that), accelerometer, but not with the heart rate sensor. I even tried to modify the Switch case in the onSensorChanged() method to work like this:
if (sensorType == 21) {
mTextSensorHeart.setText(getResources().getString(R.string.heart_label, currentValue));
}
I removed the switch case and just used some ifs, same thing. The heart rate sensor is the only one not working.
I created another android project that shows a list of the sensor that are in the watch, and I noticed that the heart rate sensor is the only one that hasn't "vendor="Huawei SensorHub"". Here's what I found:
{sensor
name="ADPD153GGRI",
vendor="ANALOG DEVICES",
version=1,
type=21,
maxRange=255.0
...
}
while all the other sensors have "Huawei SensorHub" as vendor.
I can't find the sensor model on the Analog Devices site (this is the closest one I found, but it doesn't really help) and from here I really don't know what else to do. Maybe since it's a non original huawei sensor, the values[0] array of the sensor event doesn't work?
I really don't know what to do.
In API 23 the body sensor moved to a runtime permission. If you go into settings, apps and notifications, app info, select your app, then permissions. You should see the sensor permission disabled. You can enable it there for testing but should implement the runtime permission model outlined here. https://developer.android.com/training/articles/wear-permissions
i want to get and move needle on co-ordinates as per user rotates or move device as compass does also as this app is doing already.you can see what i want to say on this link https://play.google.com/store/apps/details?id=com.plaincode.clinometer&hl=en but now at this time i am not able to understand on this context. i am unable to find hint for how to start..is their is any api to get and make it work or need to implement accelerometer on a very extensive level to get it done. please guide me if u have any code or link regarding this..thank in advance
I was looking for this solution more than a year ago and for that somehow i managed to do this similar this way. and source for that which i managed to do is -- link to source
You should start creating an activity that implements SensorEventListener, including the two following methods:
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// add your code
// event.values[] contains the 3 accelerometer values
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
// add your code
}
As second step, start with the implementation of accelerometers into the Activity:
private SensorManager mSensorManager;
private Sensor mRotationSensor;
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Then register a sensor listener on it (you could do in onResume):
mSensorManager.registerListener(this, mRotationSensor, 16000);
// 16000 microseconds
and unregister it (in onPause):
mSensorManager.unregisterListener(this);
Please note that, if you want a very accurate measurement of angles and slopes in the 3 dimensions, you should implement a calibration routine of the onboard accelerometers, that usually need a small compensation in gain, offset and angle.
You can read a simple but complete usage of Accelerometers on the free and opensource BasicAirData Clinometer: https://github.com/BasicAirData/Clinometer
The app includes also a calibration routine.
I am developing an android app for my project, I need to find room temperature as part of it. I am using Droid 2 A955 model for testing.
My Questions are:
What sensors need to be available in my Android phone to perform
this temperature sensing task?
Can Ambient Light Sensor (available in Droid 2) help in doing this
task?
Is there any Android api to find/sense room temperature
programmatically in my android code?
Thanks in advance for your help.
To answer all three of your questions in one fell swoop, no, I don't believe so. There can be a temperature sensor in android devices, but it senses the temperature of the battery, not the outside temperature. It would not provide an accurate gauge for that purpose.
I'm not sure how an ambient light sensor would help with temperature, it can be very bright out but it could be in an air conditioned room.
Lastly: there are lots of examples of temperature apps, but again, most are related to the battery.
Edit: Official documentation says:
Device implementations MAY but SHOULD NOT include a thermometer (i.e. temperature sensor.) If a device implementation does include a
thermometer, it MUST measure the temperature of the device CPU. It MUST NOT measure any other temperature. (Note that this sensor type is
deprecated in the Android 2.3 APIs.)
Update:
API level 14 (i.e. Android 4.0) onwards, support for measuring ambient temperature has been added (via TYPE_AMBIENT_TEMPERATURE). [Android doc reference]
This, however, will work only on devices with ambient temperature sensor.
It seems that there is a new sensor in the API.
This one is for the ambient temperature, but probably there are just a few devices with this implemented.
UPDATE: it seems that the Galaxy S4 is the first phone integrating ambient temperature sensor
You'll want to check out the Sensor reference docs. Offhand, I don't think there are accessible temperature sensors on-board most handhelds though.
Take a look at the Sensor class in the documentation.
You need to do something along the lines of this:
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mTemp;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mtemp = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mTemp, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
This should give you access to the temperature sensors in it's own activity.
Play with this and see what you can find. The documentation has great examples for other types of sensors, the temp sensor should be even simpler than most of the provided ones.
Hope this helps!
You can use the iCelsius Wireless from Kickstarter. It has an API. It is impossible to measure accurately temperature using an internal sensor from a SmartPhone. It will always be few degree to high.
i have same your question long time ago. And what my found is :
check this offical site for Environment sensor
this tuts for environment sensor : Ambient Temperature (room temp) Ambient Light ... Tutsplus. on my phone only Ambient Light work
now as i know only samsung galaxy S4 have Ambient Temperature. if you have S4 search Holo Ambient Temperature on gg playstore .
this sounds interesting:
http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_AMBIENT_TEMPERATURE
from API >= 13
There is the age old method of letting the phone and a "good" thermometer stabilize at room temperature (a few hours) and read both.
Then put it outside in a nice wintry garage at about 35F let it stabilize. Then pray for linearity.
Empirical is always nice. I am very interested in measuring a constant temperature in an empty house, and watch for the temperature dropping (or rising!!)
Bradshaw at Buzzards Bay
Try this one:
private float temperature = 0;
In onCreate put wìthis code:
SensorManager mySensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor AmbientTemperatureSensor
= mySensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
if (AmbientTemperatureSensor != null) {
mySensorManager.registerListener(
AmbientTemperatureSensorListener,
AmbientTemperatureSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
And the method below:
private final SensorEventListener AmbientTemperatureSensorListener
= new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
temperature = event.values[0];
}
}
};
I am trying to register multiple sensor listeners in one sensor manager, but this code won't work:
boolean linearAccelerationRegistered = mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
boolean rotationVecRegistered = mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_FASTEST);
It only registers accelerometer. It registered rotation when I commented out the first statement
Technically you register only one listener to the sensor manager, but this listener listens to multiple sensors.
My first idea was, that you have to use different listener classes for each sensor. I had a sample activity at hand, where I made use of four sensors. I registered each of them with a different listener at the sensor manager. That worked. Now I tried your approach with one listener for all of them and that worked as well.
Its hard to tell what might went wrong with only these two lines. Maybe you think, the orientation sensor wasn't registered, because the listener received multiple value changes from the accelerometer in a row, before the orientation changes were queued!?
If you have one listener instance for multiple sensors, you should inspect the SensorEvent to find out, which of the sensors reported the change:
public void onSensorChanged(SensorEvent event) {
Sensor source = event.sensor;
if (source.equals(mAccelerometer)) {
// do your stuff
} else if (source.equals(mOrientation)) {
// do your stuff
}
}
Try to register each sensor with it's own listener and see, if you get different results (but it should also work the way you pointed out...):
mSensorManager.registerListener(mAccelerometerListener, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(mOrientationListener, mOrientation, SensorManager.SENSOR_DELAY_FASTEST);
I'm making my first Android application. As a toy problem to learn the system I want to make a simple app that display as text which direction the phone is pointing using the built in compass.
How do I access the compass from my code, and have my code be aware of direction changes?
I believe I'll need the SensorManager class but I'm confused how to use it. How do I tell it I want the compass sensor? How do I tell it to do an action (update text) on a direction change?
// First, get an instance of the SensorManager
SensorManager sMan = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// Second, get the sensor you're interested in
Sensor magnetField = sMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// Third, implement a SensorEventListener class
SensorEventListener magnetListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do things if you're interested in accuracy changes
}
public void onSensorChanged(SensorEvent event) {
// implement what you want to do here
}
};
// Finally, register your listener
sMan.registerListener(magnetListener, magnetField, SensorManager.SENSOR_DELAY_NORMAL);
However, please note that this is actually a magnetic sensor; therefore if you have magnetic interference around you, it may be pointing to the wrong direction. Also, you need to know the difference between True North and Magnetic North. Since this code uses magnetic sensor, you obtain the Magnetic North, but if you need to calculate the True North, you would need to do some adjustments with GeomagneticField.getDeclination().
Have a look at the API demos. There is an application that has already been written which access the compass and accelerometer. Maybe that will give you a better idea on how you can go about your task.
you shall find it in:
/android-sdk-linux_86/samples/android-8/ApiDemos/src/com/example/android/apis/os/sensor.java
hope it helps.
First you should check if a compass sensor is present on the system
PackageManager m = getPackageManager();
if(!m.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)) {
Log.d("COMPASS_SENSOR", "Device has no compass");
}