Android GPS学習ノート—GpsLP初期化
目次:
frameworks\base\services\core\java\com\android\server\location
GpsLocationProvider自体には、次のような初期化コードがあります.
GpsLocationProviderのコンストラクション関数を見てみましょう.
参考文献:『Android:WiFi、NFC、GPSボリュームを深く理解する』
frameworks\base\services\core\java\com\android\server\location
GpsLocationProvider自体には、次のような初期化コードがあります.
//GpsLP native , class_init_native JNI
static { class_init_native(); }
GpsLocationProviderのコンストラクション関数を見てみましょう.
public GpsLocationProvider(Context context, ILocationManager ilocationManager,
Looper looper) {
mContext = context;
/**
NTP Network Time Protocol, 。 UTC。 ,GpsLP
NtpTrustedTime , SNTP NTP 。
**/
mNtpTime = NtpTrustedTime.getInstance(context);
mILocationManager = ilocationManager;
mLocation.setExtras(mLocationExtras);
// Create a wake lock
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
mWakeLock.setReferenceCounted(true);
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
// App ops service to keep track of who is accessing the GPS
mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(
Context.APP_OPS_SERVICE));
// Battery statistics service to be notified when GPS turns on or off
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
// GPS , reloadGpsProperties
mProperties = new Properties();
reloadGpsProperties(mContext, mProperties);
// GPS HAL NI
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
mSuplEsEnabled);
// construct handler, listen for events
mHandler = new ProviderHandler(looper);
//SUPL , listenForBroadcasts
listenForBroadcasts();
// PASSIVE_PROVIDER
mHandler.post(new Runnable() {
@Override
public void run() {
LocationManager locManager =
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
final long minTime = 0;
final float minDistance = 0;
final boolean oneShot = false;
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
LocationManager.PASSIVE_PROVIDER,
minTime,
minDistance,
oneShot);
request.setHideFromAppOps(true);
// NetworkLP
// GpsLP NetworkLP , GPS HAL
locManager.requestLocationUpdates(
request,
new NetworkLocationListener(),
mHandler.getLooper());
}
});
}
関数reloadGpsPropertiesファイルetc/gps.confにはGPS関連パラメータがロードされており、SUPLサーバーのアドレス、ポート番号などが含まれている.コードは以下の通りである. private void reloadGpsProperties(Context context, Properties properties) {
Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
loadPropertiesFromResource(context, properties);
boolean isPropertiesLoadedFromFile = false;
final String gpsHardware = SystemProperties.get("ro.hardware.gps");
if (!TextUtils.isEmpty(gpsHardware)) {
final String propFilename =
PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
isPropertiesLoadedFromFile =
loadPropertiesFromFile(propFilename, properties);
}
// GPS
if (!isPropertiesLoadedFromFile) {
loadPropertiesFromFile(DEFAULT_PROPERTIES_FILE, properties);
}
Log.d(TAG, "GPS properties reloaded, size = " + properties.size());
// , JNI HAL
setSuplHostPort(properties.getProperty("SUPL_HOST"),
properties.getProperty("SUPL_PORT"));
//C2K CDMA2000 ,C2K_HOST C2K_PORT GPS ,
mC2KServerHost = properties.getProperty("C2K_HOST");
String portString = properties.getProperty("C2K_PORT");
if (mC2KServerHost != null && portString != null) {
try {
mC2KServerPort = Integer.parseInt(portString);
} catch (NumberFormatException e) {
Log.e(TAG, "unable to parse C2K_PORT: " + portString);
}
}
try {
// Convert properties to string contents and send it to HAL.
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
properties.store(baos, null);
native_configuration_update(baos.toString());
Log.d(TAG, "final config = " + baos.toString());
} catch (IOException ex) {
Log.w(TAG, "failed to dump properties contents");
}
// SUPL_ES configuration.
String suplESProperty = mProperties.getProperty("SUPL_ES");
if (suplESProperty != null) {
try {
mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1);
} catch (NumberFormatException e) {
Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
}
}
}
次にlistenForBroadcasts関数を見てみましょう.その内容は次のとおりです.private void listenForBroadcasts() {
IntentFilter intentFilter = new IntentFilter();
//SUPL INIT 。 , IntentFilter
//127.0.0.1 。7275 OMA-SUPL
intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
intentFilter.addDataScheme("sms");
intentFilter.addDataAuthority("localhost","7275");
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
//SUPL INIT WAP , MIME "application/vnd.omaloc-supl-init"
intentFilter = new IntentFilter();
intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
try {
intentFilter.addDataType("application/vnd.omaloc-supl-init");
} catch (IntentFilter.MalformedMimeTypeException e) {
Log.w(TAG, "Malformed SUPL init mime type");
}
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
// ALARM 、
intentFilter = new IntentFilter();
intentFilter.addAction(ALARM_WAKEUP);
intentFilter.addAction(ALARM_TIMEOUT);
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(SIM_STATE_CHANGED);
// TODO: remove the use TelephonyIntents. We are using it because SIM_STATE_CHANGED
// is not reliable at the moment.
intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE);
intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
}
GpsLPが指定されたデータメールまたはWAPプッシュメールを受信すると、checkSmsSuperInitまたはcheckWapSuperInit関数が呼び出されます.この2つの関数の機能は比較的簡単で、メールの内容をGPS HAL層に伝達し、以下はそれらのコードである. private void checkSmsSuplInit(Intent intent) {
SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
for (int i=0; i <messages.length; i++) {
byte[] supl_init = messages[i].getUserData();
native_agps_ni_message(supl_init,supl_init.length);
}
}
private void checkWapSuplInit(Intent intent) {
byte[] supl_init = (byte[]) intent.getExtra("data");
native_agps_ni_message(supl_init,supl_init.length);
}
GpsLP初期化完了.参考文献:『Android:WiFi、NFC、GPSボリュームを深く理解する』