2013-10-20 24 views
2

我有一個Android應用程序與谷歌地圖和自動位置更新通過谷歌播放服務的新位置API。谷歌播放服務的位置停止位置更新的簡歷,無需撥打電話

實現就像這樣: https://developer.android.com/training/location/receive-location-updates.html

我專門欲接收GPS /準確位置。

它正常工作100%,GPS圖標位於上方,位置每隔幾秒進入一次,無後顧之憂。

奇怪的問題似乎是,如果您切換到Google地圖,請稍等,然後切換回我的應用程序,然後我的應用程序再獲取一個位置更新,然後停止接收更新。

我的應用正在停止位置更新onPause/onStop,並重新連接並重新啓動onStart/onResume。

我的調試Toast在從Google地圖切換回來後顯示「已連接」,並再次顯示「已更新的位置」,然後停止更新。 onDisconnected()沒有被調用,而mLocationClient.isConnected()的檢查報告爲'true'。

我已經添加了一個黑客解決方法,每隔幾秒鐘運行一次定時器處理程序,如果在最近10秒內未找到某個位置,它會在下面調用stopPauseLocation()和checkStartLocation()解決問題和地點再次開始。顯然這是一個醜陋的黑客攻擊,我對此並不滿意。

它似乎就像一個錯誤,谷歌地圖和我自己的應用程序之間有衝突,但是,我不能爲我的生活找出一個真正的解決方案。

任何想法?

這是關鍵的代碼片段:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Create the LocationRequest object 
    mLocationRequest = LocationRequest.create(); 
    // Use high accuracy 
    mLocationRequest.setPriority(
      LocationRequest.PRIORITY_HIGH_ACCURACY); 
    // Set the update interval to 2 seconds 
    mLocationRequest.setInterval(2000); 
    // Set the fastest update interval to 1 second 
    mLocationRequest.setFastestInterval(1000); 
    /* 
    * Create a new location client, using the enclosing class to 
    * handle callbacks. 
    */ 
    mLocationClient = new LocationClient(this, this, this); 

    mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
} 

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

    // Check our connection to play services 
    checkStartLocation(); 
} 

/* 
* Called when the Activity is no longer visible at all. 
* Stop updates and disconnect. 
*/ 
@Override 
protected void onStop() { 
    stopPauseLocation(); 
} 

/* 
* Called by Location Services when the request to connect the 
* client finishes successfully. At this point, you can 
* request the current location or start periodic updates 
*/ 
@Override 
public void onConnected(Bundle dataBundle) { 
    // Display the connection status 
    Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show(); 
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 

    super.onStop(); 
} 

private void stopPauseLocation() 
{ 
    // If the client is connected 
    if (mLocationClient.isConnected()) { 
     /* 
     * Remove location updates for a listener. 
     * The current Activity is the listener, so 
     * the argument is "this". 
     */ 
     mLocationClient.removeLocationUpdates(this); 
    } 
    /* 
    * After disconnect() is called, the client is 
    * considered "dead". 
    */ 
    mLocationClient.disconnect(); 
} 

/** 
* Helper to check if we're connected to play, and try to connect if not 
*/ 
protected void checkStartLocation() { 
    if (!mLocationClient.isConnected()) 
    { 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationClient.connect(); 
    } 
} 

/* 
* Called by Location Services when the request to connect the 
* client finishes successfully. At this point, you can 
* request the current location or start periodic updates 
*/ 
@Override 
public void onConnected(Bundle dataBundle) { 
    // Display the connection status 
    Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show(); 
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
} 

@Override 
public void onDisconnected() { 
    // Display the connection status 
    Toast.makeText(this, "Disconnected.",Toast.LENGTH_SHORT).show(); 
} 

/* 
* Called by Location Services if the attempt to connect to 
* Location Services fails. 
*/ 
@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Toast.makeText(this, "onConnectionFailed", Toast.LENGTH_SHORT).show(); 
} 

// Define the callback method that receives location updates 
@Override 
public void onLocationChanged(Location location) { 
    // Report to the UI that the location was updated 
    String msg = "Updated Location: " + 
      Double.toString(location.getLatitude()) + "," + 
      Double.toString(location.getLongitude()); 
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); 
} 

回答

2

我解決此發現的唯一的方法是一個黑客,但這是黑客,我想出的最好的版本。

以下代碼將每10秒檢查一次位置更新(然後逐漸增加15s,20s,最多30s)。如果沒有收到位置,它會調用removeLocationUpdates()和requestLocationUpdates(),這似乎解決了我的問題。

private Handler locationCheck = null; 
// Track the time of the last location update 
private long lastLocationUpdate = System.currentTimeMillis(); 
private long lastLocationWaitTime = 0; 
// How long to wait until we reconnect (10 sec) 
private long WAIT_LOCATION_AGE_START = 10000; 
// Increments of how much longer to wait before next check 
// Increments on every failure to give the system more time to recover 
private long WAIT_LOCATION_AGE_INCREMENT = 5000; 
// Max time to wait 
private long MAX_WAIT_LOCATION_AGE = 30000; 

Add to onCreate in your class: 
locationCheck = new Handler(); 

Add to onResume/onStart: 
lastLocationUpdate = System.currentTimeMillis(); 
lastLocationWaitTime = WAIT_LOCATION_AGE_START; 
locationCheck.removeCallbacks(locationCheckRunnable); 
locationCheck.postDelayed(locationCheckRunnable, 1000); 

Add to onStop/onPause: 
locationCheck.removeCallbacks(locationCheckRunnable); 

private Runnable locationCheckRunnable = new Runnable() { 
    @Override 
    public void run() { 
     if ((System.currentTimeMillis() - lastLocationUpdate) > lastLocationWaitTime) 
     { 
      // Verify our connection 
      checkStartLocation(); 
      // Reset the timer 
      lastLocationUpdate = System.currentTimeMillis(); 
      // On next check wait a bit longer 
      lastLocationWaitTime += WAIT_LOCATION_AGE_INCREMENT; 
      lastLocationWaitTime = Math.min(lastLocationWaitTime, MAX_WAIT_LOCATION_AGE); 
      // Re-request location updates 
      mLocationClient.removeLocationUpdates(MyParentClassName.this); 
      mLocationClient.requestLocationUpdates(mLocationRequest, LocationSocialBaseScreen.this); 
     } 

     locationCheck.postDelayed(this, 1000); 
    } 
}; 

@Override 
public void onLocationChanged(Location location) { 
    lastLocationUpdate = System.currentTimeMillis(); 
} 
相關問題