有关从 Android 移动设备中的 GPS 位置变化计算速度的更多信息,请查看此链接
主要有两种方法可以从手机计算速度。
- 从加速度计计算速度
- 利用 GPS 技术计算速度
与 GPS Technology 的加速度计不同,如果您要计算速度,则必须启用数据连接和 GPS 连接。
在这里,我们将使用 GPS 连接计算速度。在这种方法中,我们使用 GPS 位置点在单个时间段内变化的频率。然后,如果我们有地理位置点之间的真实距离,我们就可以得到速度。因为我们有距离和时间。
速度 = 距离/时间
但是获得两个位置点之间的距离并不是很容易。因为世界在形状上是一个目标,所以两个地理点之间的距离因地而异,因角度而异。所以我们必须使用 “Haversine Algorithm”</a>
首先,我们必须授予在 Manifest 文件中获取位置数据的权限
制作图形用户界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/txtCurrentSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="000.0 miles/hour"
android:textAppearance="?android:attr/textAppearanceLarge" />
<CheckBox android:id="@+id/chkMetricUnits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Use metric units?"/>
然后做一个接口来获取速度
package com.isuru.speedometer;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
public interface IBaseGpsListener extends LocationListener, GpsStatus.Listener {
public void onLocationChanged(Location location);
public void onProviderDisabled(String provider);
public void onProviderEnabled(String provider);
public void onStatusChanged(String provider, int status, Bundle extras);
public void onGpsStatusChanged(int event);
}
使用 GPS 位置实现获取速度的逻辑
import android.location.Location;
public class CLocation extends Location {
private boolean bUseMetricUnits = false;
public CLocation(Location location)
{
this(location, true);
}
public CLocation(Location location, boolean bUseMetricUnits) {
// TODO Auto-generated constructor stub
super(location);
this.bUseMetricUnits = bUseMetricUnits;
}
public boolean getUseMetricUnits()
{
return this.bUseMetricUnits;
}
public void setUseMetricunits(boolean bUseMetricUntis)
{
this.bUseMetricUnits = bUseMetricUntis;
}
@Override
public float distanceTo(Location dest) {
// TODO Auto-generated method stub
float nDistance = super.distanceTo(dest);
if(!this.getUseMetricUnits())
{
//Convert meters to feet
nDistance = nDistance * 3.28083989501312f;
}
return nDistance;
}
@Override
public float getAccuracy() {
// TODO Auto-generated method stub
float nAccuracy = super.getAccuracy();
if(!this.getUseMetricUnits())
{
//Convert meters to feet
nAccuracy = nAccuracy * 3.28083989501312f;
}
return nAccuracy;
}
@Override
public double getAltitude() {
// TODO Auto-generated method stub
double nAltitude = super.getAltitude();
if(!this.getUseMetricUnits())
{
//Convert meters to feet
nAltitude = nAltitude * 3.28083989501312d;
}
return nAltitude;
}
@Override
public float getSpeed() {
// TODO Auto-generated method stub
float nSpeed = super.getSpeed() * 3.6f;
if(!this.getUseMetricUnits())
{
//Convert meters/second to miles/hour
nSpeed = nSpeed * 2.2369362920544f/3.6f;
}
return nSpeed;
}
}
将逻辑结合到 GUI
import java.util.Formatter;
import java.util.Locale;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
public class MainActivity extends Activity implements IBaseGpsListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
this.updateSpeed(null);
CheckBox chkUseMetricUntis = (CheckBox) this.findViewById(R.id.chkMetricUnits);
chkUseMetricUntis.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
MainActivity.this.updateSpeed(null);
}
});
}
public void finish()
{
super.finish();
System.exit(0);
}
private void updateSpeed(CLocation location) {
// TODO Auto-generated method stub
float nCurrentSpeed = 0;
if(location != null)
{
location.setUseMetricunits(this.useMetricUnits());
nCurrentSpeed = location.getSpeed();
}
Formatter fmt = new Formatter(new StringBuilder());
fmt.format(Locale.US, "%5.1f", nCurrentSpeed);
String strCurrentSpeed = fmt.toString();
strCurrentSpeed = strCurrentSpeed.replace(' ', '0');
String strUnits = "miles/hour";
if(this.useMetricUnits())
{
strUnits = "meters/second";
}
TextView txtCurrentSpeed = (TextView) this.findViewById(R.id.txtCurrentSpeed);
txtCurrentSpeed.setText(strCurrentSpeed + " " + strUnits);
}
private boolean useMetricUnits() {
// TODO Auto-generated method stub
CheckBox chkUseMetricUnits = (CheckBox) this.findViewById(R.id.chkMetricUnits);
return chkUseMetricUnits.isChecked();
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if(location != null)
{
CLocation myLocation = new CLocation(location, this.useMetricUnits());
this.updateSpeed(myLocation);
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onGpsStatusChanged(int event) {
// TODO Auto-generated method stub
}
}
如果要将米/秒转换为 kmph-1,则需要将 3.6 中的米/秒答案相乘
kmph-1 的速度 = 3.6 *(ms-1 的速度)