我想知道如何使用gps坐在车内时使用手机获得车辆的速度。我已经读过加速度计不是很准确。另一件事是;坐在车内时可以访问GPS。你在建筑物里会不会产生同样的效果?
以下是我尝试过的一些代码,但我使用的是NETWORK PROVIDER。我将非常感谢您的帮助。感谢...
package com.example.speedtest;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
LocationManager locManager;
LocationListener li;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
li=new speed();
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, li);
}
class speed implements LocationListener{
@Override
public void onLocationChanged(Location loc) {
Float thespeed=loc.getSpeed();
Toast.makeText(MainActivity.this,String.valueOf(thespeed), Toast.LENGTH_LONG).show();
}
@Override
public void onProviderDisabled(String arg0) {}
@Override
public void onProviderEnabled(String arg0) {}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
}
}
答案 0 :(得分:24)
主要有两种方法可以通过手机计算速度。
与GPS技术的加速度计不同,如果您要计算速度,则必须启用数据连接和GPS连接。
在这里,我们将使用GPS连接计算速度。 在这种方法中,我们使用GPS位置点在单个时间段内的频率变化。然后,如果我们有地理位置点之间的真实距离,我们就可以获得速度。因为我们有距离和时间。 速度=距离/时间 但是,获得两个位置点之间的距离并不容易。因为世界是形状的目标,所以两个地理点之间的距离在不同地方和角度与角度之间是不同的。所以我们必须使用“Haversine Algorithm”
首先,我们必须在清单文件
中授予获取位置数据的权限
<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
}
}
如果你想将Meters / Second转换为kmph-1,那么你需要将米/秒的答案乘以3.6
速度来自kmph-1 = 3.6 *(速度来自ms-1)
答案 1 :(得分:23)
GPS在车辆中工作正常。 NETWORK_PROVIDER
设置可能不够准确,无法获得可靠的速度,NETWORK_PROVIDER
的位置可能甚至不包含速度。您可以使用location.hasSpeed()
检查(location.getSpeed()
将始终返回0)。
如果您发现location.getSpeed()
不够准确,或者它不稳定(即剧烈波动),那么您可以通过获取几个GPS位置之间的平均距离并除以经过的时间来自行计算速度。
答案 2 :(得分:2)
public class MainActivity extends Activity implements LocationListener {
在Activity
旁边添加实现LocationListenerLocationManager lm =(LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
this.onLocationChanged(null);
LocationManager.GPS_PROVIDER,0,0,第一个零代表minTime,第二个代表minDistance,您可以在其中更新值。零意味着基本上即时更新,这可能对电池寿命有害,因此您可能需要调整它。
@Override
public void onLocationChanged(Location location) {
if (location==null){
// if you can't get speed because reasons :)
yourTextView.setText("00 km/h");
}
else{
//int speed=(int) ((location.getSpeed()) is the standard which returns meters per second. In this example i converted it to kilometers per hour
int speed=(int) ((location.getSpeed()*3600)/1000);
yourTextView.setText(speed+" km/h");
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
}
不要忘记权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
答案 3 :(得分:1)
我们可以使用location.getSpeed();
try {
// Get the location manager
double lat;
double lon;
double speed = 0;
LocationManager locationManager = (LocationManager)
getActivity().getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, false);
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location = locationManager.getLastKnownLocation(bestProvider);
try {
lat = location.getLatitude();
lon = location.getLongitude();
speed =location.getSpeed();
} catch (NullPointerException e) {
lat = -1.0;
lon = -1.0;
}
mTxt_lat.setText("" + lat);
mTxt_speed.setText("" + speed);
}catch (Exception ex){
ex.printStackTrace();
}