2013-03-22 8 views
12

Chciałbym wiedzieć, jak uzyskać prędkość pojazdu za pomocą telefonu, siedząc w pojeździe za pomocą GPS. Czytałem, że akcelerometr nie jest bardzo dokładny. Inną sprawą jest; GPS będzie dostępny podczas siedzenia w pojeździe. Czy nie będzie miał takiego samego efektu jak w budynku?Określanie prędkości pojazdu za pomocą GPS w Androidzie

Oto kod, który próbowałem, ale zamiast tego skorzystałem z usługi NETWORK PROVIDER. Docenimy pomoc. Dzięki ...

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) {} 

    } 
} 

Odpowiedz

16

GPS działa dobrze w pojeździe. Ustawienie NETWORK_PROVIDER może nie być wystarczająco dokładne, aby uzyskać niezawodną prędkość, a lokalizacje z NETWORK_PROVIDER mogą nawet nie zawierać prędkości. Możesz sprawdzić, czy z location.hasSpeed() (location.getSpeed() zawsze zwróci 0).

Jeśli okaże się, że location.getSpeed() nie jest wystarczająco dokładna, lub jest niestabilna (to jest drastycznie), można obliczyć prędkość samodzielnie, biorąc średnią odległość między kilkoma lokalizacjami GPS i podzielić przez czas, który upłynął.

+0

Niż, ja, że ​​obliczenia prędkości ręcznie, dopóki nie znaleziono funkcji komfortu. Cóż, dostawca NETWORK podał mi wartość 0.0. Sądzę, że oznacza to, że nie ma prędkości. Dzięki jeszcze raz. –

+0

jakie będą jednostki dla location.getSpeed ​​()? km/h, M/h, ft/s, mtrs/s. – Prasad

+0

W dokumentacji podano metry na sekundę – Samuel

16

for more information onCalculate Speed from GPS Location Change in Android Mobile Device view this link

Głównie istnieją dwa sposoby, aby obliczyć prędkość z telefonu komórkowego.

  1. Oblicz prędkość z akcelerometru
  2. prędkość liczona od technologii GPS

przeciwieństwie Akcelerometr z technologii GPS, jeśli masz zamiar obliczyć prędkość należy włączyć połączenia danych i połączenia GPS.

Tutaj obliczyć prędkość za pomocą połączenia GPS. W tej metodzie wykorzystujemy częstotliwość, z jaką punkty lokalizacji GPS zmieniają się podczas jednego okresu. Wtedy, jeśli mamy rzeczywistą odległość między punktami geograficznej lokalizacji, możemy uzyskać prędkość. Ponieważ mamy dystans i czas. Prędkość = odległość/czas Ale uzyskanie odległości między dwoma punktami lokalizacji nie jest łatwe. Ponieważ świat jest celem w kształcie, odległość między dwoma punktami geo różni się od miejsca do miejsca i kąta do kąta.Więc musimy użyć “Haversine Algorithm”

enter image description here

najpierw musimy dać zgody na danych Get położenie w pliku manifestu

Bądź GUI enter image description here

enter image description here

enter image description here

<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?"/> 

Następnie zrobić interfejs do uzyskać prędkość

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); 

} 

Implementacja logiki, aby uzyskać prędkość za pomocą GPS Lokalizacja

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; 
     } 



} 

Kombajny logiki 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 

     } 



} 

Jeśli chcesz przekonwertować metry/sekundę, aby kmph-1 to trzeba multipl liczników/Second odpowiedź od 3,6

Prędkość od kmph-1 = 3,6 * (prędkość od ms-1)

0
public class MainActivity extends Activity implements LocationListener { 

dodać narzędzi LocationListener obok działalności

LocationManager lm =(LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 
     this.onLocationChanged(null); 

LocationManager.GPS_PROVIDER, 0, 0, Pierwszy zera oznacza MinTime a drugi dla minDistance w którym zaktualizowanie wartości. Zero oznacza w zasadzie natychmiastowe aktualizacje, które mogą być szkodliwe dla żywotności baterii, więc możesz go dostosować.

 @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) { 


} 

Nie zapomnij Uprawnienia

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
0

Możemy użyć 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(); 
      } 
0

wyjaśniam poniżej Jak zdobyć aktualną prędkość Użytkownika z wykorzystaniem GPS w Android urządzenia za pomocą Android Location Manager. Uzyskanie aktualnej prędkości może być wykorzystywane na wiele sposobów dla użytkowników.

Wykonaj proste kroki, aby uzyskać aktualną prędkość za pomocą GPS

Tworzenie nowego projektu. Dodaj uprawnienia w pliku AndroidManifest.xml.

<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” /> 
<uses-permission android:name=”android.permission. ACCESS_COARSE_LOCATION” /> 
<uses-permission android:name=”android.permission.INTERNET” /> 

jak wyższe wersje Androida potrzebują pozwolenia w aplikacji tak będziemy żądać App pozwolenie ten sposób,

try { 
    if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 101); 
    } 
} catch (Exception e){ 
    e.printStackTrace(); 
} 

ACCESS_COARSE_LOCATION jest używana, gdy używamy sieci dostawcy lokalizacji dla naszej aplikacji na Androida. Ale ACCESS_FINE_LOCATION zapewnia zezwolenia obu dostawcom. Uprawnienie INTERNET jest obowiązkowe do korzystania z operatora sieci. Sprawdź GPS w Włączony lub Nie, używając Menedżera lokalizacji.

isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

Utwórz GPSManager.java i zaimplementuj GpsStatus.Listener. Zapewni to oddzwonienia, aby uzyskać aktualizacje połączenia GPS.

public class GPSManager implements android.location.GpsStatus.Listener 
{ 
     private static final int gpsMinTime = 500; 
     private static final int gpsMinDistance = 0; 

     private static LocationManager locationManager = null; 
     private static LocationListener locationListener = null; 
     private static GPSCallback gpsCallback = null; 
     Context mcontext; 
     public GPSManager(Context context) { 
      mcontext=context; 
       GPSManager.locationListener = new LocationListener() { 
         @Override 
         public void onLocationChanged(final Location location) { 
           if (GPSManager.gpsCallback != null) { 
             GPSManager.gpsCallback.onGPSUpdate(location); 
           } 
         } 

         @Override 
         public void onProviderDisabled(final String provider) { 
         } 

         @Override 
         public void onProviderEnabled(final String provider) { 
         } 

         @Override 
         public void onStatusChanged(final String provider, final int status, final Bundle extras) { 
         } 
       }; 
     } 
     public void showSettingsAlert(){ 
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(mcontext); 
      // Setting Dialog Title 
      alertDialog.setTitle("GPS is settings"); 
      // Setting Dialog Message 
      alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); 
      // On pressing Settings button 
      alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog,int which) { 
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        mcontext.startActivity(intent); 
       } 
      }); 
      // on pressing cancel button 
      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
       dialog.cancel(); 
       } 
      }); 
      // Showing Alert Message 
      alertDialog.show(); 
     } 
     public GPSCallback getGPSCallback() 
     { 
       return GPSManager.gpsCallback; 
     } 

     public void setGPSCallback(final GPSCallback gpsCallback) { 
       GPSManager.gpsCallback = gpsCallback; 
     } 

     public void startListening(final Context context) { 
       if (GPSManager.locationManager == null) { 
         GPSManager.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 
       } 

       final Criteria criteria = new Criteria(); 

       criteria.setAccuracy(Criteria.ACCURACY_FINE); 
       criteria.setSpeedRequired(true); 
       criteria.setAltitudeRequired(false); 
       criteria.setBearingRequired(false); 
       criteria.setCostAllowed(true); 
       criteria.setPowerRequirement(Criteria.POWER_LOW); 

       final String bestProvider = GPSManager.locationManager.getBestProvider(criteria, true); 

      if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       ActivityCompat.requestPermissions((Activity) context, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101); 
      } 
       if (bestProvider != null && bestProvider.length() > 0) { 
         GPSManager.locationManager.requestLocationUpdates(bestProvider, GPSManager.gpsMinTime, 
             GPSManager.gpsMinDistance, GPSManager.locationListener); 
       } 
       else { 
         final List<String> providers = GPSManager.locationManager.getProviders(true); 
         for (final String provider : providers) 
         { 
           GPSManager.locationManager.requestLocationUpdates(provider, GPSManager.gpsMinTime, 
               GPSManager.gpsMinDistance, GPSManager.locationListener); 
         } 
       } 
     } 
     public void stopListening() { 
       try 
       { 
         if (GPSManager.locationManager != null && GPSManager.locationListener != null) { 
           GPSManager.locationManager.removeUpdates(GPSManager.locationListener); 
         } 
         GPSManager.locationManager = null; 
       } 
       catch (final Exception ex) { 
        ex.printStackTrace(); 
       } 
     } 

     public void onGpsStatusChanged(int event) { 
      int Satellites = 0; 
      int SatellitesInFix = 0; 
      if (ActivityCompat.checkSelfPermission(mcontext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mcontext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       ActivityCompat.requestPermissions((Activity) mcontext, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101); 
      } 
      int timetofix = locationManager.getGpsStatus(null).getTimeToFirstFix(); 
      Log.i("GPs", "Time to first fix = "+String.valueOf(timetofix)); 
      for (GpsSatellite sat : locationManager.getGpsStatus(null).getSatellites()) { 
       if(sat.usedInFix()) { 
        SatellitesInFix++;    
       } 
       Satellites++; 
      } 
      Log.i("GPS", String.valueOf(Satellites) + " Used In Last Fix ("+SatellitesInFix+")"); 
     } 
} 

Utwórz interfejs wywołania zwrotnego GPSCallback.java, aby otrzymywać aktualizacje GPS z modułu GPSManager.

public interface GPSCallback 
{ 
public abstract void onGPSUpdate(Location location); 
} 

Wreszcie, pobierz aktualną prędkość z lokalizacji. stosując

speed = location.getSpeed(); 
currentSpeed = round(speed,3,BigDecimal.ROUND_HALF_UP); 
kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP); 

końcowy, MainActivity.java

public class MainActivity extends Activity implements GPSCallback{ 
    private GPSManager gpsManager = null; 
    private double speed = 0.0; 
    Boolean isGPSEnabled=false; 
    LocationManager locationManager; 
    double currentSpeed,kmphSpeed; 
    TextView txtview; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     txtview=(TextView)findViewById(R.id.info); 
     try { 
      if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 101); 
      } 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 

public void getCurrentSpeed(View view){ 
txtview.setText(getString(R.string.info)); 
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE); 
gpsManager = new GPSManager(MainActivity.this); 
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
if(isGPSEnabled) { 
gpsManager.startListening(getApplicationContext()); 
gpsManager.setGPSCallback(this); 
} else { 
gpsManager.showSettingsAlert(); 
} 
} 

@Override 
public void onGPSUpdate(Location location) { 
speed = location.getSpeed(); 
currentSpeed = round(speed,3,BigDecimal.ROUND_HALF_UP); 
kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP); 
txtview.setText(kmphSpeed+"km/h"); 
} 

@Override 
protected void onDestroy() { 
gpsManager.stopListening(); 
gpsManager.setGPSCallback(null); 
gpsManager = null; 
super.onDestroy(); 
} 

public static double round(double unrounded, int precision, int roundingMode) { 
BigDecimal bd = new BigDecimal(unrounded); 
BigDecimal rounded = bd.setScale(precision, roundingMode); 
return rounded.doubleValue(); 
} 
} 

odniesienia: Get current User Speed using GPS in Android

Powiązane problemy