Android GPS学习笔记—GpsLP初始化
2015-07-07 15:13
405 查看
目录:
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推送短信后,checkSmsSuplInit或checkWapSuplInit函数将被调用。这两个函数的功能比较简单,就是将短信的内容传递到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卷》
相关文章推荐
- Please ensure that adb is correctly located at 'D:\android-sdk-windows\platform-tools\adb.exe' and c
- android:duplicateParentState
- Android Accessibility API的研究与应用(一)
- Android 图片缓存处理
- android如何查看cpu的占用率和内存泄漏
- Android解决部分控件无法充满屏幕
- Android KeyCode列表
- [转载] Android Studio Rendering Problems "android.support.v7.internal.widget.ActionBarOverlayLayout"
- android:padding和android:layout_margin的区别
- Android学习之智能聊天机器人(图灵机器人)
- Android自定义消息推送
- Android 开发环境下载地址
- Android MediaPlayer使用注意
- android调用照相机简单demo
- android apk重签名方法
- Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解
- Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解
- android新版本support包V7后自定义actionbar左边有一块空白无法填充
- 【android】Android ADB 端口占用问题解决方案
- android Toast大全(五种情形)建立属于你自己的Toast