我正在做一个项目,其中屏幕上的内容随移动设备轴的方向而变化。为此,我创建了一个类,该类通过访问传感器数据来计算方位角。此类还具有方法setLine
,当提供的gps坐标时,该方法在线方程a.x + b.y + c = 0
中返回a,b,c。这条线是移动设备的z轴。
所以我从另一个类创建了这个类的对象。但是每当我访问setLine
时,通过查看日志,我就会知道azimuthal = NULL
和oldAzimuthal = 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中实现您要尝试执行的操作,这将更加容易。