我正在做一个项目,其中屏幕上的内容随移动设备轴的方向而变化。为此,我创建了一个类,该类通过访问传感器数据来计算方位角。此类还具有方法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);
  }

最佳答案

您只是在创建ViewAngleActivity的实例,而从未将其真正添加到窗口中。
您的onCreate()onResume()方法永远不会被调用,仅当您的Activity添加到窗口并通过Activity Lifecycle时才被调用
由于您要在onCreate()中实例化mSensorManager实例,因此它永远不会创建,并且仍然为null。
由于未调用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,因为显然onPause()永远不会在ViewAngleActivity中被调用。

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


或者,相反,在用作MainActivity的新Activity中实现您要尝试执行的操作,这将更加容易。

08-06 11:14