AR10
AR10

Reputation: 93

Android Accelerometer and Magnetometer readings simultaneously

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

Nothing works

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

Accelerometer works

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

Answers (1)

Marius
Marius

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

Related Questions