从另一个类调用传感器活动对象

时间:2016-10-28 19:04:03

标签: java android

我正在开展一个项目,其中屏幕上的内容随着移动轴的方向而变化。为此,我创建了一个通过访问传感器数据来计算方位角的类。这个类还有一个方法setLine,当提供gps坐标时,它会在行等式a.x + b.y + c = 0中给出a,b,c。这条线是移动的z轴。

所以我从另一个类创建了这个类的对象。但每当我访问setLine时,通过查看日志,我就会知道azimuthal = NULLoldAzimuthal = Math.PI/180这就是我设置的内容。

我不明白这一点。当我创建ViewAngleActivity对象时,这应该已经初始化了传感器,我不应该NULL获得azimuthal

早些时候,当我使用This ViewAngleActivity作为主要课程时,我没有遇到这样的问题。我正好得到azimthal

我错过了一些概念吗?请帮忙。

我正在上传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;
    }

}

我从其他类创建的对象如下

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);
  }

1 个答案:

答案 0 :(得分:1)

  • 您只是创建 ViewAngleActivity 的实例,它从未真正添加到窗口中。
  • 您的onCreate()onResume()方法永远不会被调用,只有在您的活动被添加到窗口并通过Activity Lifecycle
  • 时才会调用它们
  • 由于您在onCreate()内实例化了 mSensorManager 实例,因此它永远不会被创建并且仍为空。
  • 由于未调用onResume()(请参见第二点),您的 viewAngleActivity 实例(也是您的SensorEventListener接口)永远不会注册到 mSensorManager ,因此,ViewAngleActivity实例中的方法onSensorChanged(SensorEvent evt)永远不会被调用。由于那是你设置方位角的地方,它仍然是NULL,因为永远不会调用该方法。

您可能想尝试不同的方法,可能会将ViewAngleActivity的onCreateView()方法中的所有代码移动到类似的构造函数中:

//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);
    }

请详细了解Android Activity Lifecycle及其在屏幕上的添加方式。请注意,使用上述方法,您必须处理取消注册 SensorEventListener 的原因,因为显然{<1}}永远不会在 ViewAngleActivity 中调用。

onPause()

或者,在您使用的新活动中实施您尝试执行的操作作为MainActivity,这将更加容易。