0

在我的应用程序中,我需要实施实时位置跟踪并查找人员总行程。我曾尝试使用Google位置管理器API。旅行时,我可以成功从设备获取位置信息。但源和目的地之间的距离是错误的。这似乎并不准确。这里是我的后台服务的代码,它提取位置并计算距离。实时位置跟踪

public class MyService extends Service { 
    private static final String TAG = "gpstest"; 
    private static final int LOCATION_INTERVAL = 3000; 
    private static final float LOCATION_DISTANCE = 5; 
    LocationListener[] mLocationListeners = new LocationListener[]{ 
      new LocationListener(LocationManager.GPS_PROVIDER), 
      new LocationListener(LocationManager.NETWORK_PROVIDER), 
    }; 
    Location mLastLocation; 
    private LocationManager mLocationManager = null; 
    private double lat; 
    private double log; 
    private RetrofitClient.APIServiceGetDistanceMap apiServiceGetDistanceMap; 
    private RetrofitClient.MakeMyTrip makeMyTrip; 
    private String id; 
    private String t_id; 
    private boolean isStop = false; 
    private double srclat; 
    private double srclog; 
    private double destlat; 
    private double destlog; 
    private double total; 

    @Override 
    public IBinder onBind(Intent arg0) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.e(TAG, "onStartCommand"); 

     lat = intent.getDoubleExtra("lat", 0); 
     log = intent.getDoubleExtra("log", 0); 

     if (mLastLocation != null) { 
      mLastLocation.setLatitude(0); 
      mLastLocation.setLongitude(0); 
     } 

     super.onStartCommand(intent, flags, startId); 
     return START_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     Log.e(TAG, "onCreate"); 

     PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE); 
     PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG"); 
     wl.acquire(720000000); 

     WifiManager wm = (WifiManager) getApplicationContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
     WifiManager.WifiLock wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "TAG"); 
     wifiLock.acquire(); 


     SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("my", Context.MODE_PRIVATE); 
     String username = sharedPref.getString("user_name", null); 
     id = String.valueOf(sharedPref.getInt("id", 0)); 
     t_id = sharedPref.getString("t_id", ""); 

     initializeLocationManager(); 
     apiServiceGetDistanceMap = RetrofitClient.getDistanceMap(Constants.MAP_URL); 
     makeMyTrip = RetrofitClient.makeTrip(Constants.BASE_URL); 
     try { 
      mLocationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
        mLocationListeners[1]); 
     } catch (java.lang.SecurityException ex) { 
      Log.i(TAG, "fail to request location update, ignore", ex); 
     } catch (IllegalArgumentException ex) { 
      Log.d(TAG, "network provider does not exist, " + ex.getMessage()); 
     } 
     try { 
      mLocationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
        mLocationListeners[0]); 
     } catch (java.lang.SecurityException ex) { 
      Log.i(TAG, "fail to request location update, ignore", ex); 
     } catch (IllegalArgumentException ex) { 
      Log.d(TAG, "gps provider does not exist " + ex.getMessage()); 
     } 
    } 

    @Override 
    public void onDestroy() { 
     Log.e(TAG, "onDestroy"); 
     super.onDestroy(); 


     if (mLocationManager != null) { 
      for (int i = 0; i < mLocationListeners.length; i++) { 
       try { 
        mLocationManager.removeUpdates(mLocationListeners[i]); 
       } catch (Exception ex) { 
        Log.i(TAG, "fail to remove location listners, ignore", ex); 
       } 
      } 


     } 
    } 

    private void initializeLocationManager() { 
     Log.e(TAG, "initializeLocationManager"); 
     if (mLocationManager == null) { 
      mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
     } 
    } 

    protected boolean isBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > LOCATION_INTERVAL; 
     boolean isSignificantlyOlder = timeDelta < -LOCATION_INTERVAL; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
      // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 10; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

    /** 
    * Checks whether two providers are the same 
    */ 
    private boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    private class LocationListener implements android.location.LocationListener { 


     public LocationListener(String provider) { 
      Log.e(TAG, "LocationListener " + provider); 
      mLastLocation = new Location(provider); 
//   mLastLocation.setLatitude(lat); 
//   mLastLocation.setLongitude(log); 
     } 

     @Override 
     public void onLocationChanged(final Location location) { 
      Log.e(TAG, "onLocationChanged: " + location); 

      if (mLastLocation != null) { 
       String source = String.valueOf(mLastLocation.getLatitude()).concat(",").concat(String.valueOf(mLastLocation.getLongitude())); 


       String destination = String.valueOf(String.valueOf(location.getLatitude())).concat(",").concat(String.valueOf(location.getLongitude())); 
       apiServiceGetDistanceMap.getMapDate(source, destination, "driving").enqueue(new Callback<MapData>() { 
        @Override 
        public void onResponse(Call<MapData> call, Response<MapData> response) { 
         ArrayList<Row> rowArrayList = new ArrayList<Row>(); 
         if (response.isSuccessful()) { 

          rowArrayList = (ArrayList<Row>) response.body().getRows(); 
          double distance = 0; 


          if (rowArrayList.size() > 0) { 

           for (int i = 0; i < rowArrayList.size(); i++) { 


            for (int j = 0; j < rowArrayList.get(i).getElements().size(); j++) { 

             if (rowArrayList.get(i).getElements().get(j).getDistance() != null) { 
              distance = distance + rowArrayList.get(i).getElements().get(j).getDistance().getValue(); 

             } 

            } 

           } 

           Log.e("source..lat", "" + mLastLocation.getLatitude()); 
           Log.e("source..log", "" + mLastLocation.getLongitude()); 
           Log.e("destination..lat", "" + location.getLatitude()); 
           Log.e("destination..log", "" + location.getLongitude()); 
           Log.e("distance:", "" + distance/1000); 

           final double dist = distance/1000; 

           //call service to send location 

           srclat = mLastLocation.getLatitude(); 
           srclog = mLastLocation.getLongitude(); 
           destlat = mLastLocation.getLatitude(); 
           destlog = mLastLocation.getLongitude(); 
           total = dist; 

           Travel travel = new Travel(); 
           travel.setId(id); 
           travel.setTid(t_id); 
           travel.setSrcLat(String.valueOf(mLastLocation.getLatitude())); 
           travel.setSrcLog(String.valueOf(mLastLocation.getLongitude())); 
           travel.setDestLat(String.valueOf(location.getLatitude())); 
           travel.setDestLog(String.valueOf(location.getLongitude())); 
           travel.setDist(String.valueOf(dist)); 

           // check for accuracy of location 
           Log.e("meter", String.valueOf(distance)); 
           double speed = distance/(location.getTime() - mLastLocation.getTime()); 

           if (isBetterLocation(location, mLastLocation) && speed > 3 && distance < 300) { 
            if (mLastLocation.getLatitude() != 0 && mLastLocation.getLongitude() != 0 && location.getLatitude() != 0 && location.getLongitude() != 0) { 

             if (mLastLocation.getLatitude() != location.getLatitude() && mLastLocation.getLongitude() != location.getLongitude()) { 
              makeMyTrip.makeTrip(id, t_id, String.valueOf(mLastLocation.getLatitude()), String.valueOf(mLastLocation.getLongitude()), 
                String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()), String.valueOf(dist)).enqueue(new Callback<MyRes>() { 
               @Override 
               public void onResponse(Call<MyRes> call, Response<MyRes> response) { 


               } 

               @Override 
               public void onFailure(Call<MyRes> call, Throwable t) { 

               } 
              }); 


             } 


            } 
           } 

           mLastLocation.set(location); 
          } 


         } 


        } 

        @Override 
        public void onFailure(Call<MapData> call, Throwable t) { 
         mLastLocation.set(location); 
        } 
       }); 

      } 


     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      Log.e(TAG, "onProviderDisabled: " + provider); 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      Log.e(TAG, "onProviderEnabled: " + provider); 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      Log.e(TAG, "onStatusChanged: " + provider); 
     } 
    } 


} 
+0

你如何测量位置之间的距离? –

+0

从谷歌距离矩阵api .. –

回答

2

你必须采取两步经纬度之间的步骤距离意味着以前的纬度和新的纬度使用这个公式。在添加所有距离时,可以给你准确的距离。如果您需要更高的准确度,请增加时间和速度因素。

public static float getDistanceInMiles(double currentLatitude, double currentLongitude, double newLatitude, double newLongitude) { 
    double latitude = newLatitude; 
    double longitude = newLongitude; 
    float distance = 0; 
    Location crntLocation = new Location("crntlocation"); 
    crntLocation.setLatitude(currentLatitude); 
    crntLocation.setLongitude(currentLongitude); 
    Location newLocation = new Location("newlocation"); 
    newLocation.setLatitude(latitude); 
    newLocation.setLongitude(longitude); 
    distance = crntLocation.distanceTo(newLocation); 
    //distance =crntLocation.distanceTo(newLocation)/1000; // in km 
    return distance; 
} 
+0

我已经计算了一步一步的距离从以前的经纬度和新经纬度,但位置坐标得到了很多次错误和结果之间的距离给错了。所以我如何过滤错误的坐标location.I也有使用谷歌文档过滤功能。但不能正常工作.. –

+0

你必须添加时间和速度因素,以获得准确的结果 –

+0

需要时间,当你获得前一个和新的纬度和计算速度使用s = d/t并将该速度与车辆速度进行比较,例如,如果车辆速度为70公里/小时,则计算速度,如果速度超过该速度,则车辆速度忽略该点。 –