vamsidhar muthireddy vamsidhar muthireddy - 1 month ago 10
Java Question

Call sensor activity object from another class

I am working on a project in which the content on the screen changes with the direction of mobile's axis. For this, I created a class which calculates azimuthal angle by accessing sensor data. This class also has a method

setLine
which gives back a,b,c in line equation
a.x + b.y + c = 0
when supplied gps co-ordinates. This line is the z-axis of mobile.

So I created an object of this class from another class. But whenever I am accessing
setLine
, By seeing the log I got to know that
azimuthal = NULL
and
oldAzimuthal = Math.PI/180
which is what I set.

I don't understand this. When I created the
ViewAngleActivity
object, this should have already initialized sensors and I shouldn't be getting
NULL
for
azimuthal
.

Earlier when I used This
ViewAngleActivity
as the main class I didn't face such issue. I was properly getting
azimthal
.

Am I missing some concepts? Please help.

I am uploading the code for
ViewAngleActivity


public class ViewAngleActivity extends Activity implements SensorEventListener {


Float azimuth;
Float pitch;
Float roll;

float oldAzimuth;

private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("gettingViewAngle:","in onCreateSensor got Created");
}

protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}

protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}

public void onAccuracyChanged(Sensor sensor, int accuracy) { }

float[] mGravity;
float[] mGeomagnetic;

public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;

if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];

if (SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic)) {

// orientation contains azimut, pitch and roll
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);

oldAzimuth = azimuth;
azimuth = orientation[0];
pitch = orientation[1];
roll = orientation[2];

// at this point, orientation contains the azimuth(direction), pitch and roll values.

Log.d("onSensorChanged:", "azimuth = "+ azimuth);
Log.d("onSensorChanged:", "oldAzimuth = "+ oldAzimuth);
}

}
}

/**
* This method calculates line equation of mobile axis
* @param currentLatitude
* @param currentLongitude
* @return co-efficients of the line a.x + b.y + c = 0
*/
public double[] setLine(Double currentLatitude, Double currentLongitude){

double angle = 1;
double a,b,c;
double[] coEfficients = {1, 1, 0};
Log.d("setLine:", "azimuth = "+ azimuth);
Log.d("setLine:", "oldAzimuth = "+ oldAzimuth);

if(azimuth!= null) {
angle = (float) azimuth;
if (angle == 0){
angle = Math.PI/180;
}
if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:Using azimuth", "azimuth = "+ angle);

coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;

}
else{
angle = (float) oldAzimuth;
if (angle == 0){
angle = Math.PI/180;
}

if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:UsingOldAzimuth", "oldAzimuth = "+ angle);

coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;
}



return coEfficients;
}

}


The object I created from other class is as follows

private ViewAngleActivity viewAngleActivity;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

viewAngleActivity = new ViewAngleActivity();

//other parts of the code//

}

@Override
public void method1{
method2;
}

public void method1{
double[] coEfficients = viewAngleActivity.setLine(currentLatitude,currentLongitude);
}

Answer
  • You're only creating an instance of ViewAngleActivity, it's never really added to the window.
  • Your onCreate() and onResume() methods never get called, they are only called when your Activity is added to the window and goes through the Activity Lifecycle
  • Since you're instantiating your mSensorManager instance inside onCreate(), it never gets created and is still null.
  • Since onResume() isn't called (see second point up there), then your viewAngleActivity instance (which is also your SensorEventListener interface) never gets registered to mSensorManager, and as such the method onSensorChanged(SensorEvent evt) inside your ViewAngleActivity instance never gets called. Since that's where you're setting azimuth it's still going to be NULL cause that method is never called.

You might want to try a different approach, probably move all the code in your ViewAngleActivity's onCreateView() methods to a constructor like so:

//note the context parameter, pass this one when you create your ViewAngleActivity instance
public ViewAngleActivity(Context context){
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        Log.d("gettingViewAngle:","in onCreateSensor got Created");
        //then you use your context to reg.
        mSensorManager.registerListener(context, accelerometer, SensorManager.SENSOR_DELAY_UI);
        mSensorManager.registerListener(context, magnetometer, SensorManager.SENSOR_DELAY_UI);
    }

Please read more about Android's Activity Lifecycle and how they are added on screen. Note that with the above approach, you'd have to handle unregistering your SensorEventListener, cause obviously onPause() would never be called in ViewAngleActivity.

//this is how you'd probably go about it:
viewAngleActivty.mSensorManager.unregisterListener(viewAngleActivity);

Or instead, implement what you're trying to do in the new Activity you're using as your MainActivity, that would be even easier.

Comments