分享

Android GPS架构分析(五)

 tracyf 2012-11-13
Android GPS架构分析
Daniel Wood 20101224
转载时请注明出处和作者
文章出处:http://danielwood.
作者:Daniel Wood
--------------------------------------------------------------------------------
分析完了enable函数以后就轮到enableLocationTracking函数了。
GpsLocationProvider.java

public void enableLocationTracking(boolean enable) {
        synchronized (mHandler) {
            mHandler.removeMessages(ENABLE_TRACKING);
            Message m = Message.obtain(mHandler, ENABLE_TRACKING);
            m.arg1 = (enable ? 1 : 0);
            mHandler.sendMessage(m);
        }
    }

同样地,也采取Handler的方式。调用的是handleEnableLocationTracking函数。

private void handleEnableLocationTracking(boolean enable) {
        if (enable) {
            mTTFF = 0;
            mLastFixTime = 0;
            startNavigating();
        } else {
            mAlarmManager.cancel(mWakeupIntent);
            mAlarmManager.cancel(mTimeoutIntent);
            stopNavigating();
        }
    }

调用startNavigating函数。

private void startNavigating() {
        if (!mStarted) {
            if (DEBUG) Log.d(TAG, "startNavigating");
            mStarted = true;
            int positionMode;
            if (Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) {
                positionMode = GPS_POSITION_MODE_MS_BASED;
            } else {
                positionMode = GPS_POSITION_MODE_STANDALONE;
            }

            if (!native_start(positionMode, false, 1)) {
                mStarted = false;
                Log.e(TAG, "native_start failed in startNavigating()");
                return;
            }

           ...

startNavigating函数中,最有作用的语句就是调用native方法native_start。调用到了JNI层的android_location_GpsLocationProvider_start函数。

android_location_GpsLocationProvider.cpp

static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode,
        jboolean singleFix, jint fixFrequency)
{
    int result = sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 : fixFrequency));
    if (result) {
        return false;
    }
    return (sGpsInterface->start() == 0);
}

接下去就会调用sGpsInterface接口的实现gps_qemu.c中具体实现的函数。

static int
qemu_gps_start()
{
    GpsState* s = _gps_state;
    if (!s->init) {
        D("%s: called with uninitialized state !!", __FUNCTION__);
        return -1;
    }
    D("%s: called", __FUNCTION__);
    gps_state_start(s);
    return 0;
}

通过向底层发送命令,CMD_START来启动gps。其实这个所谓的底层就是在enable/init函数中启动的等待数据的线程。

static void
gps_state_start( GpsState* s )
{
    char cmd = CMD_START;
    int ret;
    do { ret=write( s->control[0], &cmd, 1 ); }
    while (ret < 0 && errno == EINTR);
    if (ret != 1)
        D("%s: could not send CMD_START command: ret=%d: %s",
          __FUNCTION__, ret, strerror(errno));
}

数据监听线程

static void*
gps_state_thread( void* arg )
{
    ...
// now loop
    for (;;) {
     ...
   if (cmd == CMD_QUIT) {
   D("gps thread quitting on demand");
       goto Exit;
    }else

   if (cmd == CMD_START) {

      if (!started) {
       D("gps thread starting  location_cb=%p",     state>callbacks.location_cb);
      started = 1;
  nmea_reader_set_callback( reader, state->callbacks.location_cb );
 } }
  else if (cmd == CMD_STOP) {

...

}

其实就是注册了一个回调函数,location_cb 这个回调函数就是对底层location数据上报的回调函数。

    在enableLocationTracking函数调用完成以后,基本上gps服务已经启动完成了,也就是 LocationManagerService中的updateProvidersLocked函数的完成,也就是loadProviders函数的完 成,也就是initialize函数的完成,也就是run函数的完成,也就是2.2中反馈机制systemReady的完成。

void systemReady() {
        // we defer starting up the service until the system is ready 
        Thread thread = new Thread(null, this, "LocationManagerService");
        thread.start();
    }


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多