4

我想创建一个 Android 指南针 - 仅基于 GPS。我正在为其开发的设备没有任何加速度计或磁场传感器,这就是我必须仅依赖 android.location 类的原因。

到目前为止,访问 LocationManager 以显示当前 GPS 坐标对我来说效果很好(见下文)。我正在努力寻找最好的方法。我正在考虑电路角度计算 - 使用当前坐标和地理北坐标作为已知值来计算方向。

任何人都可以建议这种方法是否有意义甚至共享代码?

这是我到目前为止得到的代码:

public class CompassActivity extends Activity implements LocationListener {


Compass myCompass;
private TextView mInfoText;
private LocationManager mLoc;

private static final Integer MINIMUM_UPDATE_INTERVAL = 5000; //update every 5s
private static final Integer MINIMUM_UPDATE_DISTANCE = 5; //update every 5m

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_compass);
    myCompass = (Compass)findViewById(R.id.mycompass);

    mInfoText = (TextView) findViewById(R.id.infotext);
    mLoc = (LocationManager) getSystemService(LOCATION_SERVICE);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.compass, menu);
    return true;
}

@Override
protected void onResume() {
    mLoc.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_UPDATE_INTERVAL, MINIMUM_UPDATE_DISTANCE, this);
    super.onResume();

}

@Override
protected void onPause() {
    mLoc.removeUpdates(this);
    super.onPause();
}

@Override
protected void onStop() {
    finish();
    super.onStop();
}

@Override
public void onLocationChanged(Location loc) { //display coordinates
    System.out.println(loc.toString());
    String title = "Current location: ";
    final StringBuilder sb = new StringBuilder(title);
    sb.append("Longitude: ");
    sb.append(loc.getLongitude());
    sb.append("Latitude: ");
    sb.append(loc.getLatitude());
    runOnUiThread(new Runnable() {

        @Override
        public void run() {
            mInfoText.setText(sb.toString());
        }
    });
}

@Override
public void onProviderDisabled(String provider){ // message if GPS is disabled
    Toast.makeText(this, "GPS disabled", Toast.LENGTH_LONG).show();
    AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
    alertbox.setMessage("Please activate GPS!");
    alertbox.setNeutralButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
            finish();
        }
    }
    );
    alertbox.show();
}


@Override
public void onProviderEnabled(String provider) {
    Toast.makeText(this, "GPS enabled", Toast.LENGTH_LONG).show();
}


@Override
public void onStatusChanged(String provider, int status, Bundle b) { // called upon GPS status changes
    switch (status) {
    case LocationProvider.OUT_OF_SERVICE:
        Toast.makeText(this, "Status changed: out of service", Toast.LENGTH_LONG).show();
        break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
        Toast.makeText(this, "Status changed: temporarily unavailable", Toast.LENGTH_LONG).show();
        break;
    case LocationProvider.AVAILABLE:
        Toast.makeText(this, "Status changed: available", Toast.LENGTH_LONG).show();
        break;
    }

}

}

4

1 回答 1

0

You simply cannot show the user the direction the device is facing at the moment. But if you have the possibility to get the GPS provided location of the device, you can show which direction the device moved.

If you get location updates, you need two locations to calculate the bearing between this two:

double x = Math.cos(lat2) * Math.sin(lng1-lng2);
double y = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lng1-lng2);
double bearing = Math.atan2(x, y);

Hope this helps!

于 2016-08-10T13:23:00.850 回答