2013-03-22 22 views
12

Tôi muốn biết cách để có được tốc độ của một chiếc xe sử dụng điện thoại của bạn trong khi ngồi trong xe bằng cách sử dụng gps. Tôi đã đọc rằng gia tốc không phải là rất chính xác. Cái khác là; sẽ có thể truy cập GPS khi ngồi trong xe. Nó sẽ không có tác dụng tương tự như khi bạn đang ở trong một tòa nhà?Xác định tốc độ của một chiếc xe sử dụng GPS trong android

Dưới đây là một số mã tôi đã thử nhưng tôi đã sử dụng NETWORK PROVIDER thay thế. Tôi sẽ đánh giá cao sự trợ giúp. Cảm ơn ...

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

    } 
} 

Trả lời

16

GPS hoạt động tốt trong xe. Cài đặt NETWORK_PROVIDER có thể không đủ chính xác để có tốc độ đáng tin cậy và các vị trí từ NETWORK_PROVIDER thậm chí không thể chứa tốc độ. Bạn có thể kiểm tra rằng với location.hasSpeed() (location.getSpeed() sẽ luôn trả về 0).

Nếu bạn thấy rằng location.getSpeed() không đủ chính xác hoặc không ổn định (tức là dao động mạnh) thì bạn có thể tự tính tốc độ bằng cách lấy khoảng cách trung bình giữa một vài vị trí GPS và chia cho thời gian trôi qua.

+0

Thanx, tôi đã nghĩ đến việc tính toán tốc độ bằng tay cho đến khi tôi tìm thấy chức năng convinience. Nhà cung cấp NETWORK đã cho tôi một giá trị 0.0. Tôi đoán điều này có nghĩa là nó không có tốc độ. Cảm ơn một lần nữa. –

+0

những gì sẽ là đơn vị cho location.getSpeed ​​()? km/h, M/h, ft/giây, mtrs/sec – Prasad

+0

Tài liệu cho biết số mét trên giây – Samuel

16

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

Chủ yếu có hai cách để tính tốc độ từ điện thoại di động.

  1. Tính tốc độ từ tốc
  2. tốc độ Tính từ Công nghệ GPS

Không giống như gia tốc kế từ công nghệ GPS nếu bạn đang đi để tính toán tốc độ bạn phải kích hoạt kết nối dữ liệu và kết nối GPS.

Tại đây, chúng tôi sẽ tính tốc độ sử dụng kết nối GPS. Trong phương pháp này, chúng tôi sử dụng tần suất các điểm GPS Location đang thay đổi trong một khoảng thời gian. Sau đó, nếu chúng ta có khoảng cách thực sự giữa các điểm địa lý chúng ta có thể có được tốc độ. Bởi vì chúng ta có khoảng cách và thời gian. Tốc độ = khoảng cách/thời gian Nhưng nhận được khoảng cách giữa hai điểm vị trí không phải là rất dễ dàng. Bởi vì thế giới là một mục tiêu trong hình dạng khoảng cách giữa hai điểm địa lý khác nhau từ nơi này đến nơi khác và góc tới góc.Vì vậy, chúng ta phải sử dụng “Haversine Algorithm”

enter image description here

Đầu tiên chúng ta phải cung cấp cho phép dữ liệu có được vị trí trong tập tin Manifest

Tận dụng 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?"/> 

Sau đó thực hiện một giao diện để có được tốc độ

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

} 

Thực hiện logic để đạt được tốc độ bằng cách sử dụng GPS Location

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



} 

Kết hợp logic để 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 

     } 



} 

Nếu bạn muốn chuyển đổi Mét/Second để kmph-1 thì bạn cần phải multipl Meters/câu trả lời thứ hai từ 3,6

Tốc độ từ kmph-1 = 3.6 * (Tốc độ từ ms-1)

0
public class MainActivity extends Activity implements LocationListener { 

thêm dụng cụ LocationListener bên cạnh Hoạt động

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

LocationManager.GPS_PROVIDER, 0, 0, zero đầu tiên là viết tắt của minTime và điều thứ hai cho minDistance trong đó bạn cập nhật giá trị của bạn. Zero có nghĩa là bản cập nhật tức thời cơ bản có thể gây hại cho thời lượng pin, vì vậy bạn có thể muốn điều chỉnh nó.

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


} 

Đừng quên Quyền

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

Chúng ta có thể sử dụng 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

Tôi giải thích bên dưới Cách nhận tốc độ hiện tại của Người dùng bằng GPS trong thiết bị Android Bằng cách sử dụng Trình quản lý vị trí của Android. Tốc độ hiện tại có thể được sử dụng theo nhiều cách cho người dùng.

Làm theo các bước đơn giản để nhận tốc độ hiện tại bằng cách sử dụng GPS

Tạo dự án mới. Thêm quyền trong tệp 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” /> 

Như phiên bản cao hơn của Android cần sự cho phép trong ứng dụng vì vậy chúng tôi sẽ yêu cầu sự cho phép ứng dụng theo cách này,

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 được sử dụng khi chúng ta sử dụng nhà cung cấp vị trí mạng cho ứng dụng Android của chúng tôi. Tuy nhiên, ACCESS_FINE_LOCATION đang cấp quyền cho cả hai nhà cung cấp. Sự cho phép INTERNET là phải cho việc sử dụng nhà cung cấp mạng. Kiểm tra GPS trong Đã bật hoặc Không bằng cách sử dụng Trình quản lý vị trí.

isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

Tạo GPSManager.java và triển khai GpsStatus.Listener. Điều này sẽ cung cấp các cuộc gọi lại để nhận cập nhật kết nối 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+")"); 
     } 
} 

Tạo giao diện gọi lại GPSCallback.java để nhận cập nhật GPS từ GPSManager.

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

Cuối cùng, nhận tốc độ hiện tại từ Vị trí. sử dụng,

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

cuối cùng, 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(); 
} 
} 

tham khảo: Get current User Speed using GPS in Android

Các vấn đề liên quan