Android的GPS的代码分析(五)

来源:互联网 发布:vue.js 字符串换行符 编辑:程序博客网 时间:2024/06/05 06:18
分析完了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 ?: 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 ( ) ; 
    }

原创粉丝点击