星期六, 10月 15, 2011

Location and Maps (三)

Android應用程式學習筆記

Defining a Model for the Best Performance

以定位為基礎的應用程式現在已司空見慣,但是由於不到理想準確度、用戶移動、眾多獲得位置的方法、保存電力,因此取得用戶位置變得複雜。為克服取得一個好的用戶位置又兼顧維護電力的障礙,你必須定義兼容的模型,模型指定應用程式如何取得用戶位置。模型包括何時開始及停止監聽更新,何時使用緩存的位置數據。


Flow for obtaining user location

以下是獲得用戶位置的典型流程:

  1. 開始應用程式。
  2. 一段時間後,開始監聽預期位置提供器的更新。
  3. 維護篩選出新的"目前最佳估計"位置,但缺乏固定準確度。
  4. 停止監聽更新。
  5. 利用最後最佳位置估計的優勢。
圖一演示在時間軸上的模型,視覺化應用程式何時監聽位置更新及事件發生的時間。



Deciding when to start listening for updates

你可能會想在應用程式啟動時就開始監聽更新,或只在用戶激活某功能時。小心較長的監聽位置窗口消耗較多的電力,但較短又無法達到足夠的準確度。

如上述,你可以呼叫requestLocationUpdates()方法監聽位置更新。


LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or, use GPS location data:
// LocationProvider locationProvider = LocationManager.GPS_PROVIDER;

locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);

Getting a fast fix with the last known location

你的位置監聽器鳩收第一個位置所花的時間通常為用戶等待時間過長,直到更加正確的位置提供給你的位置監聽器,你應該呼叫getLastKnownLocation()方法使用暫存的位置。


LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or use LocationManager.GPS_PROVIDER
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

Deciding when to stop listening for updates

 決定新的修復的邏輯不再需要根據你的應用程式從簡單到複雜的,何時獲得定位和何時需要使用定位之間最短的距離,改善估計的準確度,永遠都要注意長時間的監聽會消耗許多電力,所以當你取得你需要的資訊,就應該呼叫removeUpdates(PendingIntent)立即停止監聽更新。


// Remove the listener you previously added
locationManager.removeUpdates(locationListener);



Maintaining a current best estimate

你也許會期望大部分的位置修復是準確的,然而,因為位置修復的準確度多變,大部分的修復都不是最佳的,你必須有邏輯地從許多標準選擇位置修復,標準也依應用程式的使用與測試領域變化。

以下有幾個步驟可以驗證位置修復的準確度:

  • 檢查檢索的位置是否明顯的比前一次估計的新。
  • 檢查定位聲明的準確度是否比前一次估計的來的更好或更糟。
  • 檢查新的位置是哪一個提供器及決定更相信哪一個提供器。
以下是邏輯的闡述例子:


private static final int TWO_MINUTES = 1000 * 60 * 2;
/** Determines whether one Location reading is better than the current Location fix
  * @param location  The new Location that you want to evaluate
  * @param currentBestLocation  The current Location fix, to which you want to compare the new one
  */
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 > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    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 > 200;

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


Adjusting the model to save battery and data exchange

當你測試你的應用程式,你可能發現你的模型要提供優異的定位及優異的表現需要一些調整,這裡也一些事你可能需要改變找出兩著之間的平衡。

Reduce the size of  the window

較小的監聽位置更新視窗意味著與GPS和Network location services較少的互動,因此保住電池的壽命,但是它也提供較少的位置選擇最佳的估計。

Set the location providers to return updates less frequently

減少新的更新出現在視窗的頻率也可以改善電池的壽命,但是準確度較低,這兩者之間的權衡依賴你的應用程式如何使用,你可以減少更新頻率,透過呼叫requestLocationUpdates()方法中的參數。

Restrict a set of providers

依據你的應用程式使用或是準確度的需求的環境,選擇只採用Network location provider或是只採用GPS,取代兩者皆採用,

沒有留言:

張貼留言