onSensorChanged() is not called - java

I'm having a lot of trouble tonight with sensors, but it appear it is because of onSensorChanged() is not called. Sorry for the eventual duplicate question, but I didn't see any solutions.
Here's my code :
public SensorManager manager;
public Sensor rotation_vector;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = (SensorManager)getSystemService(SENSOR_SERVICE);
rotation_vector = manager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
#Override
public void onSensorChanged(SensorEvent event) {
int xValue = (int) event.values[0];
int yValue = (int) event.values[1];
int zValue = (int) event.values[2];
Toast.makeText(getApplicationContext(),"this doesn't appear...",Toast.LENGTH_LONG);
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//TODO: we'll see later about it
}
public void onPause() {
/*Et on le dés-enregistre quand on sort de l'activité, pour économiser de la batterie*/
super.onPause();
manager.unregisterListener(this);
}
#Override
protected void onResume() {
/*On enregistre le sensor quand l'utilisateur revient sur l'activité*/
super.onResume();
manager.registerListener(this, rotation_vector, SensorManager.SENSOR_DELAY_NORMAL);
if (null != rotation_vector) {
} else {
Toast.makeText(getApplicationContext(),
"There is no gyroscope on your device",
Toast.LENGTH_LONG).show();
}
}
I have seen a lot of similar code on different forums, but appart from there and some others topic without solutions, I haven't seen such a problem yet...
Do I have to add something in AndroidManifest ?
Is it a common problem ?
It there a solution ?
Thanks,
Thomas
(sorry for my bad english, I'm French^^)

I was not working with Sensors so far, but it looks like you have obtained SensorManager but did not register any listener for changes that should occur. Just ask yourself how could be onSensorChanged called?
Have a look at the sample on official android tutorial site about sensors and you could see this in onResume() method:
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
}
Also don't forget to study whole page it can help you a lot.
Edit:
I had to copy paste your sources because I haven't seen any problem. There are 2 basicaly:
Toast is not appearing because you haven't told him to... Toast.show() will display it. But you rather use Log to output changes into console. It's up to you
Do not retype float into int in onSensorChanged() method because all values are 0 or (1/-1 if you are lucky)
So result is following:
#Override
public void onSensorChanged(SensorEvent event) {
float xValue = event.values[0];
float yValue = event.values[1];
float zValue = event.values[2];
Log.d(LOG_TAG, "x:"+xValue +";y:"+yValue+";z:"+zValue);
}
other methods are correct

Your device probably does not have Sensor.TYPE_ROTATION_VECTOR. You should check rotation_vector for null.

Related

TYPE_STEP_COUNTER sensor not found in NEXUS5X 29API

I am doing a step counter project in an android studio with Nexus5X API29. I need to use sensors for this. I wrote the sensor codes as below, but it still gives 'Sensor not found' error. Is there any way to fix this?
public class MainActivity extends AppCompatActivity implements SensorEventListener {
TextView tv_steps;
SensorManager sensorManager;
Sensor sensor;
boolean running = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_main );
tv_steps = (TextView) findViewById ( R.id.tv_steps );
sensorManager = (SensorManager) getSystemService ( Context.SENSOR_SERVICE);
}
#Override
protected void onResume() {
super.onResume ();
running = true;
Sensor countSensor = sensorManager.getDefaultSensor ( sensor.TYPE_STEP_COUNTER );
if(countSensor!= null){
sensorManager.registerListener ( this,countSensor,SensorManager.SENSOR_DELAY_UI );
}else {
Log.d ("Main Activity","SENSOR NOT FOUND" );
}
}
#Override
protected void onPause() {
super.onPause ();
running = false;
//if you unregister the hardware will stop detecting steps
}
#Override
public void onSensorChanged(SensorEvent event) {
if (running){
tv_steps.setText ( String.valueOf ( event.values[0] ) );
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
In Manifest file I also implemnent permission like this:
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" android:required="true"/>
I suggest you test this app on a real device. Usually, emulators don't have certain functionalities like sensors or text-to-speech.
If it still doesn't work, make sure your physical device has step sensors.

How do I reset my step counter to 0 every time the app launches?

How do I reset my step counter to 0 every time my app launches? If I close my app and relaunch It, the counter continues from where it previously left off. I would like it to start over. I have already tried setting my steps taken textview to 0 every time my app launches but it doesn't change anything.
public class HomeActivity extends AppCompatActivity implements SensorEventListener {
private TextView stepsTakenTextView;
private TextView distanceTraveledTextView;
private SensorManager sensorManager;
private Boolean running = false;
private UserModel userModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
stepsTakenTextView = findViewById(R.id.stepsTakenTextView);
distanceTraveledTextView = findViewById(R.id.distanceTraveledTextView);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
running = true;
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if(countSensor != null){
sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
}else{
Toast.makeText(this, "Sensor not found", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPause() {
super.onPause();
running = false;
}
#Override
public void onSensorChanged(SensorEvent event) {
if(running){
float stepsTaken= event.values[0];
The sensor will only be restarted when the device is rebooted.
Android Sensor API
A sensor of this type returns the number of steps taken by the user since the last reboot
while activated. The value is returned as a float (with the fractional
part set to zero) and is reset to zero only on a system reboot...
Instead, you can do the following:
As soon as you start the app, save the first value returned by the sensor.
Every time the sensor emits a new value, subtract the initial value from it.

SensorManager only working on some devices

I have the following code to get the x and y angle of my device and it is working fine on my phone, but not my tablet (Samsung galaxy tab e). I was wondering if anyone had any idea as to what could be causing it to work on one device but not another.
I did also ensure that screen rotation was enabled on both. My assumption is that the tablet is lacking a sensor, and what I'm looking for most is a workaround. Any help would be much appreciated. Thanks in advance!
Source code:
double yAngle;
double xAngle;
#Override
protected void onResume() {
super.onResume();
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),RATE);
}
#Override
public void onSensorChanged(SensorEvent event) {
float[] rotationMatrix;
rotationMatrix = new float[16];
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
determineOrientation(rotationMatrix);
lblY.setText(String.format("%.1f", yAngle));
lblX.setText(String.format("%.1f", xAngle));
}
private void determineOrientation(float[] rotationMatrix){
//CREATING FLOAT ARRAY OF ORIENTATION VALUES
float [] orientationValues = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationValues);
yAngle = Math.toDegrees(orientationValues[2]);
xAngle = Math.toDegrees(orientationValues[1]);
}
You can use adb shell pm list features to check all sensors and other features supported.

How to get degrees by Accelerometer data (Java libGDX)

how can I get degrees from the values of the Accelerometer ? I'm useing libGDX and code in Java with Android Studio.
I ve got a sprite animation, which walks straight. The point of View is orthogonal from top, and I want to rotate the sprite when I tilt the smartphone.
How can I get the 360° degrees on the screen, for example like a compass just instead that it points to north it should point to the direction where the smartphone is tilted. How is it possible with the Accelerometer Sensor ? Or what other possibility do I have ?
Sorry for my English
A simple way of doing this is to use a SensorManager and implement SensorEventListener. The basic idea is you use the SensorManager to register the Orientation sensor and then respond to changes in the orientation of the device in the onSensorChanged delegate method implemented with SensorEventListener. Make sure you unregister the listener onPause() or else it will kill your battery.
As a high level example:
public class SensorActivity extends Activity implements SensorEventListener {
private Sensor mOrientationSensor;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SensorManager mSensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
mOrientationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
#Override
public void onResume() {
super.onResume();
if (mSensorManager != null) {
mSensorManager.registerListener(this, mOrientationSensor, SensorManager.SENSOR_DELAY_UI);
}
}
#Override
public void onPause() {
super.onPause();
mSensorManager.unregisterListener(this, mOrientationSensor);
}
#Override
public void onSensorChanged(SensorEvent event) {
float degree = Math.round(event.values[0]);
// do something here
}
note: The orientation sensor has been deprecated, although I still think it works best. The updated approach is below if you'd like to try that.
From the android documentation: https://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-orient
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private final float[] mAccelerometerReading = new float[3];
private final float[] mMagnetometerReading = new float[3];
private final float[] mRotationMatrix = new float[9];
private final float[] mOrientationAngles = new float[3];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
// You must implement this callback in your code.
}
#Override
protected void onResume() {
super.onResume();
// Get updates from the accelerometer and magnetometer at a constant rate.
// To make batch operations more efficient and reduce power consumption,
// provide support for delaying updates to the application.
//
// In this example, the sensor reporting delay is small enough such that
// the application receives an update before the system checks the sensor
// readings again.
mSensorManager.registerListener(this, Sensor.TYPE_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, Sensor.TYPE_MAGNETIC_FIELD,
SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
}
#Override
protected void onPause() {
super.onPause();
// Don't receive any more updates from either sensor.
mSensorManager.unregisterListener(this);
}
// Get readings from accelerometer and magnetometer. To simplify calculations,
// consider storing these readings as unit vectors.
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, mAccelerometerReading,
0, mAccelerometerReading.length);
}
else if (event.sensor == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, mMagnetometerReading,
0, mMagnetometerReading.length);
}
}
// Compute the three orientation angles based on the most recent readings from
// the device's accelerometer and magnetometer.
public void updateOrientationAngles() {
// Update rotation matrix, which is needed to update orientation angles.
mSensorManager.getRotationMatrix(mRotationMatrix, null,
mAccelerometerReading, mMagnetometerReading);
// "mRotationMatrix" now has up-to-date information.
mSensorManager.getOrientation(mRotationMatrix, mOrientationAngles);
// "mOrientationAngles" now has up-to-date information.
}
}

True and magnetic heading of compass in android?

I want to get true and magnetic heading of compass in android.
I have read many tutorials but not give my required output.
It gives just heading.
My code is here...
public class MainActivity extends Activity implements SensorEventListener {
// device sensor manager
private SensorManager mSensorManager;
TextView tvHeading;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TextView that will tell the user what degree is he heading
tvHeading = (TextView) findViewById(R.id.tvHeading);
// initialize your android device sensor capabilities
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
// for the system's orientation sensor registered listeners
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME);
}
#Override
protected void onPause() {
super.onPause();
// to stop the listener and save battery
mSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent event) {
// get the angle around the z-axis rotated
float degree = Math.round(event.values[0]);
tvHeading.setText("Heading: " + Float.toString(degree) + " degrees");
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// not in use
}
}
This code give accurate value for a compass.
How can i modify this code for getting magnetic heading and true heading?
what is missing here?
Any one can help me.
Thanks

Categories