2015-11-19 189 views
2

嗨,我想做一個應用程序的GPS檢測。 它工作正常。但經過一段時間沒有任何事情發生或ANR錯誤即將到來。 如果我增加LocationRequest.setInterval值(說1分)那麼這個問題是解決,但由於這個我不能夠準確地繪製折線,因爲距離增加兩個位置請請幫助我。Android的GPS跟蹤問題

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, 
      GoogleApiClient.OnConnectionFailedListener, LocationListener { 
     private Button btnShowLocation; 
     private String TAG = "app"; 
     private GoogleMap mGoogleMap; 
     private String mLastUpdateTime; 
     private TextView tvText; 
     private Marker mapMarker; 
     private List<Location> loc = new ArrayList<>(); 
     float distance, changeDistance; 
     private Location mCurrentLocation; 
     private List<Marker> marker; 

     double latitude; 
     double longitude; 
     private static final long INTERVAL = 3000; //3 sec 
     private static final long FASTEST_INTERVAL = 2500; 
     private GoogleApiClient mGoogleApiClient; 
     private LocationRequest mLocationRequest; 


     protected void createLocationRequest() { 
      mLocationRequest = new LocationRequest(); 
      mLocationRequest.setInterval(INTERVAL); 
      mLocationRequest.setSmallestDisplacement(5); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
      mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 

     } 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      btnShowLocation = (Button) findViewById(R.id.textview1); 

      marker = new ArrayList<>(); 
      try { 

       initilizeMap(); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      tvText = (TextView) findViewById(R.id.text1); 
      if (!isGooglePlayServicesAvailable()) { 
       finish(); 
      } 
      createLocationRequest(); 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addApi(LocationServices.API) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .build(); 

      updateUI(); 



     } 

     private void initilizeMap() { 
      mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(
        R.id.map)).getMap(); 
      // mGoogleMap.clear(); 
      mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
      addMarker(mGoogleMap.getMyLocation()); 
      if (mGoogleMap == null) { 
       Toast.makeText(getApplicationContext(), 
         "Sorry! unable to create maps", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 

     private void addMarker(Location loc) { 
      MarkerOptions options = new MarkerOptions(); 
      options.icon(BitmapDescriptorFactory.defaultMarker()); 
      LatLng currentLatLng = new LatLng(loc.getLatitude(), loc.getLongitude()); 
      options.position(currentLatLng); 
      mapMarker = mGoogleMap.addMarker(options); 
      mapMarker.setDraggable(true); 
      mapMarker.showInfoWindow(); 

      marker.add(mapMarker); 
      Log.d("size marker", marker.size() + " "); 
      long atTime = mCurrentLocation.getTime(); 
      mLastUpdateTime = DateFormat.getTimeInstance().format(new Date(atTime)); 
      mapMarker.setTitle(mLastUpdateTime + " distance " + distance + "m"); 

      mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 
        15)); 


     } 


     @Override 
     public void onStart() { 
      super.onStart(); 
      Log.d(TAG, "onStart fired "); 
      mGoogleApiClient.connect(); 

     } 

     @Override 
     public void onStop() { 
      super.onStop(); 
      Log.d(TAG, "onStop fired "); 
      mGoogleApiClient.disconnect(); 
      Log.d(TAG, "isConnected : " + mGoogleApiClient.isConnected()); 
     } 

     private boolean isGooglePlayServicesAvailable() { 
      int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
      if (ConnectionResult.SUCCESS == status) { 
       return true; 
      } else { 
       GooglePlayServicesUtil.getErrorDialog(status, this, 0).show(); 
       return false; 
      } 
     } 

     @Override 
     public void onConnected(Bundle bundle) { 
      Log.d(TAG, "onConnected - isConnected: " + mGoogleApiClient.isConnected()); 
      startLocationUpdates(); 

     } 

     protected void startLocationUpdates() { 
      PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, mLocationRequest, this); 

     } 

     @Override 
     public void onConnectionSuspended(int i) { 

     } 

     @Override 
     public void onConnectionFailed(ConnectionResult connectionResult) { 
      Log.d(TAG, "Connection failed: " + connectionResult.toString()); 
     } 

     @Override 
     public void onLocationChanged(Location location) { 
      Log.d(TAG, "Firing onLocationChanged"); 

      mCurrentLocation = location; 
      if (loc.size() > 0) 
       if (mCurrentLocation.getTime() <= loc.get(loc.size() - 1).getTime()) return; 

      loc.add(mCurrentLocation); 
      updateUI(); 


      addMarker(loc.get(0)); 

      Log.d(TAG, loc.size() + " " + marker.size()); 

      Log.d("distance", changeDistance + " "); 
      for (int i = 0; i < loc.size(); i++) { 

       if (mCurrentLocation != loc.get(i)) { 
        if (loc.size() == 1 || loc.size() == 0) { 
         distance = getDistance(loc.get(0).getLatitude(), loc.get(0).getLongitude(), mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()); 
        } else { 
         mGoogleMap.addPolyline(new PolylineOptions().geodesic(true) 
           .add(new LatLng(loc.get(i).getLatitude(), loc.get(i).getLongitude()), new LatLng(loc.get(i + 1).getLatitude(), loc.get(i + 1).getLongitude())) 
           .width(3) 
           .color(Color.BLUE)); 
         Log.d("distance1", distance + " i " + i); 
         distance = getDistance(loc.get(i).getLatitude(), loc.get(i).getLongitude(), loc.get(i + 1).getLatitude(), loc.get(i + 1).getLongitude()); 
         if (marker.size() > 2) 
          remove(i); 
        } 

       } 
      } 
      addMarker(loc.get(loc.size() - 1)); 
      Log.d("distance new", distance + " i "); 
      changeDistance = changeDistance + distance; 
      Log.d("changeDistance ", changeDistance + ""); 

      mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
      updateUI(); 

     } 

     private void remove(int i) { 
      mapMarker = marker.get(i); 
      mapMarker.remove(); 
      marker.remove(mapMarker); 
     } 

     private void updateUI() { 
      Log.d(TAG, "UI update initiated"); 
      if (null != mCurrentLocation) { 
       float distnceInKm = changeDistance/1000; 
       Log.d("distance km", distnceInKm + ""); 
       String lat = String.valueOf(mCurrentLocation.getLatitude()); 
       String lng = String.valueOf(mCurrentLocation.getLongitude()); 
       latitude = mCurrentLocation.getLatitude(); 
       longitude = mCurrentLocation.getLongitude(); 
       tvText.setText("At Time: " + mLastUpdateTime + "\n" + 
         "Latitude: " + lat + "\n" + 
         "Longitude: " + lng + "\n" + 
         "Accuracy: " + mCurrentLocation.getAccuracy() + "\n" + 
         "Provider: " + mCurrentLocation.getProvider() + "\n" + 
         "Distance " + distnceInKm + " km"); 

      } else { 
       tvText.setText("location is null "); 
       Log.d(TAG, "location is null "); 

      } 
     } 

     public float getDistance(double lat1, double lon1, double lat2, double lon2) { 
      android.location.Location homeLocation = new android.location.Location(""); 
      homeLocation.setLatitude(lat1); 
      homeLocation.setLongitude(lon1); 

      android.location.Location targetLocation = new android.location.Location(""); 
      targetLocation.setLatitude(lat2); 
      targetLocation.setLongitude(lon2); 

      return targetLocation.distanceTo(homeLocation); 
     } 

    } 
+0

嘗試使用線程來運行你的GPS跟蹤代碼.. ..所以你的主線將保持自由.. – sud

+0

所以我怎麼能在這裏使用線程..你能解釋更多...作爲服務? –

+0

不要在主線程中運行所有內容。嘗試實現線程。 –

回答

2

在這裏你可以叫你的線程asynctask-

new AsyncCaller().execute(); 

寫信您的GPS操作代碼doInBackground(Void... params)方法

private class AsyncCaller extends AsyncTask<Void, Void, Void> 
{ 
    ProgressDialog pdLoading = new ProgressDialog(AsyncExample.this); 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

     //this method will be running on UI thread 
     pdLoading.setMessage("\tLoading..."); 
     pdLoading.show(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     //this method will be running on background thread so don't update UI frome here 
     //do your long running http tasks here like gps operations of yours,you dont want to pass argument and u can access the parent class' variable url over here 


     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

     //this method will be running on UI thread 

     pdLoading.dismiss(); 
    } 

    } 
}