location.getSpeed () возвращает только то, что было установлено с помощью location.setSpeed (). Это значение, которое вы можете установить для объекта местоположения.
Чтобы вычислить скорость с помощью GPS, вам нужно будет сделать небольшую математику:
Speed = distance / time
необходимо выполнить:
(currentGPSPoint - lastGPSPoint) / (time between GPS points)
Все преобразованы в ft / sec или, тем не менее, вы хотите показать скорость. Так я сделал это, когда сделал приложение для бегунов.
В частности, вам нужно будет рассчитать абсолютные расстояния:
(sqrt((currentGPSPointX - lastGPSPointX)^2) + (currentGPSPointY - lastGPSPointY)^2)) / (time between GPS points)
Это может помочь сделать новый TrackPoint или что-то еще, что сохраняет местоположение GPS и время, в которое он был взят внутри.
(1) Я считаю, что вы можете использовать метод requestLocationUpdates()
, а затем создать класс LocationListener с методом onLocationChange, установленным для отображения getSpeed()
. Вот как я недавно видел это с помощью Location.getLatitude и Location.getLongitude, поэтому считаю, что вы можете просто использовать getSpeed () таким же образом, правильно?
(2) После простого чтения окна описания eclipse , хотя я вижу, что он говорит точно, что сказал предыдущий человек: «if hasSpeed () является ложным, возвращается 0.0f». Но, возможно, это поможет: http://www.ehow.com/how_5708473_convert-latitude-feet.html :)
Эй, я тоже страдал от того же, но теперь я решил его решить!
speed=location.getSpeed()*18/5
Также укажите interval
как 1000*2
и fastest interval
как 1000*1
. ] для большей точности
18/5
? Кроме того, как это помогает решить проблему & quot; getSpeed()
возвращает 0 & quot; i>?
– juzraai
15 July 2018 в 17:25
Я также столкнулся с этой проблемой раньше, надеюсь, это поможет.
Он возвращает 0, потому что ваше устройство не может получить блокировку на GPS или не может подключиться к GPS.
Я попытался получить скорость с помощью старого устройства lenovo, и он возвращает 0, потому что он не может заблокировать gps.
Я попытался использовать галактическую галактику samsung, и она вернула мою скорость (имеет лучший GPS-датчик) .
Датчик GPS в вашем телефоне может быть не очень хорошим, или вы находитесь в зоне с слабым сигналом GPS, например, внутри дома или здания.
Ответ Imbru выглядит действительно хорошим, но это не очень полезно, если вы работаете с блоками.
Вот что я сделал с вычислить скорость в метрах в секунду (м / с).
new LocationListener() {
private Location lastLocation = null;
private double calculatedSpeed = 0;
@Override
public synchronized void onLocationChanged(Location location) {
if (lastLocation != null) {
double elapsedTime = (location.getTime() - lastLocation.getTime()) / 1_000; // Convert milliseconds to seconds
calculatedSpeed = lastLocation.distanceTo(location) / elapsedTime;
}
this.lastLocation = location;
double speed = location.hasSpeed() ? location.getSpeed() : calculatedSpeed;
/* There you have it, a speed value in m/s */
. . .
}
. . .
}
location.hasSpeed()==false
. Некоторые люди также сообщали, что location.getSpeed()
всегда возвращают 0, даже если location.hasSpeed()==true
. Таким образом, я бы использовал location.hasSpeed() && location.getSpeed()>0
как условие.
– Julien Kronegg
15 April 2018 в 05:30
Я базово вычисляю мгновенную скорость, а затем использую метод setSpeed (), чтобы добавить его в местоположение. Его довольно точно, потому что я сравнивал его внутри транспортного средства, где я мог проверить тахеометр.
private double calculateInstantaneousSpeed(Location location) {
double insSpeed = 0;
if (y1 == null && x1 <= -1) {
//mark the location y1 at time x1
y1 = location;
x1 = duration.getDurationAsSeconds();
} else {
//mark the location y2 at time x2
y2 = location;
x2 = duration.getDurationAsSeconds();
//calculate the slope of the curve (instantaneous speed)
dy = y1.distanceTo(y2);
dx = x2 - x1;
insSpeed = dy / dx;
y1 = y2;
x1 = x2;
}
Singleton.getInstance().instantaneousSpeedSamples.add(insSpeed);
//System.out.println("Instantaneous Speed m/s: "+insSpeed);
return insSpeed;
}
getspeed () работает отлично. Вам не нужно делать математику, используя формулу расстояния. Это уже есть в speedpeed. Пока есть широта и долгота, скорость будет достигнута.
На сферическом расстоянии планеты следует рассчитывать с помощью этих формул:
private static Double distance(Location one, Location two) {
int R = 6371000;
Double dLat = toRad(two.getLatitude() - one.getLatitude());
Double dLon = toRad(two.getLongitude() - one.getLongitude());
Double lat1 = toRad(one.getLatitude());
Double lat2 = toRad(two.getLatitude());
Double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
Double d = R * c;
return d;
}
private static double toRad(Double d) {
return d * Math.PI / 180;
}
Есть мой пользовательский LocationListener, используемый для получения скорости вручную и по объекту местоположения, если имеет скорость.
new LocationListener() {
private Location mLastLocation;
@Override
public void onLocationChanged(Location pCurrentLocation) {
//calcul manually speed
double speed = 0;
if (this.mLastLocation != null)
speed = Math.sqrt(
Math.pow(pCurrentLocation.getLongitude() - mLastLocation.getLongitude(), 2)
+ Math.pow(pCurrentLocation.getLatitude() - mLastLocation.getLatitude(), 2)
) / (pCurrentLocation.getTime() - this.mLastLocation.getTime());
//if there is speed from location
if (pCurrentLocation.hasSpeed())
//get location speed
speed = pCurrentLocation.getSpeed();
this.mLastLocation = pCurrentLocation;
////////////
//DO WHAT YOU WANT WITH speed VARIABLE
////////////
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
метод getSpeed () действительно работает отлично, но вам нужно использовать высокий интервал запроса, например, 1 секунду, и вам нужна высокая точность, сначала я делал 3-секундный интервал и PRIORITY_BALANCED_POWER_ACCURACY, и я продолжал получать 0 значений, пока не меняю, как я говорю , Я использую платный провайдер местоположения api.
public class Main3Activity extends AppCompatActivity {
private FusedLocationProviderClient mFusedLocationClient;
private int speed;
private double lat;
private double lng;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
@Override
protected void onResume() {
super.onResume();
if(!runtime_permissions()) {
requestLocations();
}
}
@Override
protected void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}
@SuppressLint("MissingPermission")
private void requestLocations(){
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);;
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
LocationCallback mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
List<Location> locationList = locationResult.getLocations();
if (locationList.size() > 0) {
//The last location in the list is the newest
Location location = locationList.get(locationList.size() - 1);
lat = location.getLatitude();
lng = location.getLongitude();
//speed in km/h
speed = (int) ((location.getSpeed() * 3600) / 1000);
}
}
};
private boolean runtime_permissions() {
if(Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},100);
return true;
}
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 100){
if( grantResults[0] == PackageManager.PERMISSION_GRANTED){
onResume();
}else{
runtime_permissions();
}
}
}
}