Reputation: 93
I am writing an app which collects android sensor data and sends it to a server. I have started with Accelerometer and Magnetometer and following the tutorials online, I have written a little code. The problem is that accelerometer works but the magnetometer does not. Please look at the code below.
MainActivity.java
package com.example.aliraza.wirelesshints;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.hardware.SensorManager;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.example.aliraza.wirelesshints.MyAccelerometer;
public class MainActivity extends AppCompatActivity{
static TextView textView2, textView4;
MyAccelerometer myAccel;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView2 = (TextView) findViewById(R.id.textView2);
textView4 = (TextView) findViewById(R.id.textView4);
myAccel = new MyAccelerometer(this);
}
@Override
protected void onResume() {
super.onResume();
myAccel.sensorManager.registerListener((SensorEventListener) myAccel, myAccel.accelerometer,SensorManager.SENSOR_DELAY_UI);
myAccel.sensorManager.registerListener((SensorEventListener) myAccel, myAccel.magnetometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
// unregister listener
super.onPause();
myAccel.sensorManager.unregisterListener((SensorEventListener) myAccel);
}
}
MyAccelerometer.java (contains magnetometer code as well)
package com.example.aliraza.wirelesshints;
import android.content.Context;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;
public class MyAccelerometer implements SensorEventListener {
Context mContext;
SensorManager sensorManager;
Sensor accelerometer;
Sensor magnetometer;
float[] mGravity;
float[] mGeomagnetic;
StringBuilder sb1, sb2;
public MyAccelerometer(Context context){
this.mContext = context;
sensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
@Override
public void onSensorChanged(SensorEvent event) {
sb1 = new StringBuilder();
sb2 = new StringBuilder();
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if (mGravity != null) {
mGravity = event.values;
sb1.append("x = ");
sb1.append(mGravity[0]);
sb1.append(", y = ");
sb1.append(mGravity[1]);
sb1.append(", z = ");
sb1.append(mGravity[2]);
MainActivity.textView2.setText(sb1.toString());
}
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
if (event.sensor == magnetometer) {
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
sb2.append("azimuth = ");
sb2.append(orientation[0]);
sb2.append(", pitch = ");
sb2.append(orientation[1]);
sb2.append(", roll = ");
sb2.append(orientation[2]);
MainActivity.textView4.setText(sb2.toString());
}
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
If I run the above code the emulator and my actual phone show no output as shown below
If I comment out the following if condition statement without the internal code from MyAccelerometer.java, the accelerometer readings become visible
if (mGravity != null) {
As shown below
But if I do the same with Magnetometer part i.e. the following if condition statement
if (mGravity != null && mGeomagnetic != null) {
nothing happens, in fact if I do anything, magnetometer readings just wont show in emulator and phone.
I think the code does not go into the following condition
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
I will really appreciate some help. Sorry for the incredibly long post.
Thanks
Upvotes: 0
Views: 746
Reputation: 113
You might have a problem with the getDefaultSensor()-method. Basically that should be a description of the sensor, but not necessarily a reference to the sensor itself. You are probably better off not checking for the sensor itself, but for the sensor type (like you ALSO do).
Also your gravity!=null condition will always be false, because gravity is only set IF gravity is not null. So it will never be set, if you start with it being null. Unless you want to control logging the input by setting it to null, you should not check for this. Also note, that setting your "gravity" variable to something does not set the values of that variable, it sets the pointer. So you set your pointer to the sensor values given by android. It might work, but it's probably a better idea to either set the components individually on a pre-created array, or simply clone() the incoming data.
Removing both conditions, this code should work. Try Log.d("", ""+event.sensor.getType()) in your sensor event handler outside of any if-structures, and check if it shows 2 different values. Then you can be sure that you registered the sensors correctly, and your problem is processing.
Upvotes: 1