目录:

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卷》


更多相关文章

  1. Android开发傻瓜入门-开发自己的手机短信发送程序
  2. Android UI架构(四)--SurfaceFlinger的初始化.md
  3. Android(java)学习笔记86:案例短信发送器
  4. android 在新建短信时,加入名称为","(英文逗号)的联系人时,应用崩
  5. Android调用系统短信功能发送短信
  6. 浅谈android系统java调用C++函数传参过程
  7. Android 的AT命令协议栈初始化
  8. Android 短信数据库详细总结分析

随机推荐

  1. Android(安卓)更换系统字体......
  2. 设置Android程序图标
  3. android通用文件操作
  4. Android中调用webservice小结
  5. Android(安卓)Content Provider[转]
  6. Android(安卓)设置EditText光标位置、粗
  7. Android(安卓)利用Annotation Processing
  8. android 双卡手机发短信/判断手机是否为
  9. Android(安卓)OpenGL入门
  10. Android中style和theme的区别