在我們的s5pv210平臺上使用了Locosys LS2005B的GPS模組(atheros ar1520芯片),現在對Android2.3.4下的Settings->Location & security->Use GPS satellites復選框進行操作,會出現以下問題:當系統啟動后,復選框是選中狀態(即系統關閉前也是選中的),然后把復選框去掉,再重新選中,GPS就無法再次啟動了,而如果啟動前是未選中,那么重啟系統后第一次選中是正常的,后期再按上面步驟重新操作,也是無法再次重啟GPS的,后來跟代碼發現每次去掉GPS復選框時會調用到gps庫的cleanup函數,而該函數會把相應的變量全部清空,再次選中時并沒有去重新調用初始化函數,故無法再次啟動,相關的文件涉及到frameworks/base/services/jni/com_android_server_location_GpsLocationProvider.cpp,去掉選框時會調用如下函數:
static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj)
{
const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
interface->cleanup();
}
而再次啟動時會調用到:
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{
const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return false;
if (!sGpsDebugInterface)
sGpsDebugInterface = (const GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE);
return true;
}
上面我們都發現有GetGpsInterface函數的調用來獲取GPS接口,而該函數的實現如下:
static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) {
// this must be set before calling into the HAL library
if (!mCallbacksObj)
mCallbacksObj = env->NewGlobalRef(obj);
if (!sGpsInterface) {
sGpsInterface = get_gps_interface();
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) {
sGpsInterface = NULL;
return NULL;
}
}
return sGpsInterface;
}
通過對比,該函數會判斷sGpsInterface是否為NULL來決定是否再次調用init初始化函數,故我在android_location_GpsLocationProvider_cleanup函數的最后添加了sGpsInterface = NULL;語句,讓每次重新選中后會再次調用初始化函數,故可以解決該問題。
而上面的設置在系統每次啟動時并沒有關聯上,即系統每次啟動后并不會根據上面的復選框狀態去設置GPS是否啟動,故最終我在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中添加如下函數:
private void setGpsOnoff(){
ContentResolver resolver = mContext.getContentResolver();
String gpsOnoff = Settings.System.getString(resolver,Settings.Secure.LOCATION_PROVIDERS_
Slog.w(ActivityManagerService.TAG,"gpsOnoff="+gpsOnoff);
Settings.System.putString(resolver,Settings.Secure.LOCATION_PROVIDERS_ALLOWED,gpsOnoff);
}
并在public final class ActivityManagerService extends ActivityManagerNative函數的開頭添加對其調用,至此就把該問題也解決了。