最近在做一個 Android 項目,需要用到GPS擷取位置資訊,從 API 查了一下,發現擷取位置資訊僅需極其簡單的一句即可:
複製代碼 代碼如下:getLastKnownLocation(LocationManager.GPS_PROVIDER),
於是高興地不得了。可是一寫進代碼裡,傳回值(Location 類型)居然一直為null..鬱悶的不得了。在網上查了好久,發現好多人都和我一樣糾結於這個問題上,有人說是因為GPS沒開啟,也有人說是相關許可權沒加上..可是我的明明已經在設定裡開啟,許可權自然也加上了。在api上糾結了半天,終於找出原因了,原來要開啟GPS其實在於這句:
複製代碼 代碼如下:
setTestProviderEnabled("gps",true);
而跟手機上的設定沒多大關係(起碼在My Phone上測是這樣的)。手機上的設定關閉了,這一句照樣能開啟;而即使手機設定開啟了,沒這一句也是白搭。與這句對應的是
複製代碼 代碼如下:
setTestProviderEnabled("gps",false);
用來關閉GPS.
GPS開啟後可以用上面的方法擷取Location了嗎?還是不可以!確切地說是有時候可以,因為這個函數擷取的是上次已經獲得的位置資訊,設想如果此程式第一次跑,先前並沒有擷取過位置資訊,當然傳回值為null了。經仔細查看api,在 複製代碼 代碼如下:requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
裡發現了這樣一句話:It may take a while to receive the most recent location. If an immediate location is required, applications may use the getLastKnownLocation(String) method. 因此為了擷取位置資訊,應該用此方法為manager設定監聽器,在監聽器中onLocationChanged(Location location)裡擷取。
測試代碼如下:複製代碼 代碼如下:public void onLocationChanged(Location location)
{
Log.i("onLocationChanged", "come in");
if (location != null)
{
Log.w("Location","Current altitude = "+ location.getAltitude());
Log.w("Location","Current latitude = "+ location.getLatitude());
}
}
經過測試,經過一段時間後可以擷取Location(擷取時間與minTime、minDistance相關)。還需注意的一個問題是在設定了監聽器後,刪除監聽器之前不能用上面的方法關閉gps,否則會報錯。因此關閉gps的方法是
複製代碼 代碼如下:
manager.removeUpdates (listener);//listener 即為監聽器執行個體
manager.setTestProviderEnabled("gps",false);
以下是測試代碼,要求的權限有:複製代碼 代碼如下:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
複製代碼 代碼如下:import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
public class audio extends Activity
{
/** Called when the activity is first created. */
LocationManager locationManager;
LocationListener llistener;
String provider;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String serviceName = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(serviceName);
locationManager.setTestProviderEnabled("gps", true);
provider = locationManager.getBestProvider(criteria, true);
Log.d("provider", provider);
llistener = new LocationListener() {
@Override
public void onLocationChanged(Location location)
{
// TODO Auto-generated method stub
Log.i("onLocationChanged", "come in");
if (location != null)
{
Log.w("Location", "Current altitude = "
+ location.getAltitude());
Log.w("Location", "Current latitude = "
+ location.getLatitude());
}
locationManager.removeUpdates(this);
locationManager.setTestProviderEnabled(provider, false);
}
@Override
public void onProviderDisabled(String provider)
{
// TODO Auto-generated method stub
Log.i("onProviderDisabled", "come in");
}
@Override
public void onProviderEnabled(String provider)
{
// TODO Auto-generated method stub
Log.i("onProviderEnabled", "come in");
}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras)
{
// TODO Auto-generated method stub
Log.i("onStatusChanged", "come in");
}
};
locationManager.requestLocationUpdates(provider, 1000, (float) 1000.0, llistener);
}
protected void onDestroy()
{
locationManager.removeUpdates(llistener);
locationManager.setTestProviderEnabled(provider, false);
super.onDestroy();
}