Android GPS雜記(1)

來源:互聯網
上載者:User

1、GPS架構

 


2、GPS代碼簡介

2.1 標頭檔

我們先從標頭檔(hardware/libhardware/include/hardware/gps.h)入手,看一下android原生態代碼中提供了什麼結構體等。

結構體:GpsLocation  -- 提供了經緯度、速度、方位角、高度、精度、UTC時間戳記資訊;

GpsStatus  --  提供GPS定位狀態,一共有五種:

#define GPS_STATUS_NONE 0//未知狀態
#define GPS_STATUS_SESSION_BEGIN 1 //已經開始導航
#define GPS_STATUS_SESSION_END 2//停止導航
#define GPS_STATUS_ENGINE_ON 3//已經通電但沒有導航
#define GPS_STATUS_ENGINE_OFF 4//沒有通電狀態

   GpsSvInfo -- 可見衛星資訊,衛星偽隨機數、訊號強度、海拔、方位角(但是有人說是衛星編號,訊號強度,衛星仰望角,方位角,待求證!)

  GpsSvStatus --  可見衛星狀態。可見衛星數、一組可見衛星的衛星資訊(GpsSvInfo)、星曆(ephemeris)、曆書(almanac)、參與定位定位的衛星。

GpsCallbacks -- 回呼函數。其中包括8個回呼函數:location_callback、status_callback、sv_status_callback、nmea_callback、set_capabilities、acquire_wakelock、release_wakelock、create_thread。

GpsInterface -- 介面定義,包括8個介面:init、start、stop、cleanup、inject_time、inject_location、delete_aiding_data、set_position_mode。

(callback與interface可以這麼理解:callback在別的地方實現的,我來調用(call),以返回我的資訊(back);initerface是我實現的,提供了一個介面(face),供別人調用)

gps_device_t --繼承自hw_device_tcommon,硬體適配介面,向上層提供了重要的get_gps_interface介面。

2.2 模組和回呼函數的註冊

GPS採用的是HAL Stub架構,這種架構被概括為:三個結構體、兩個常量、一個函數,具體參考http://blog.csdn.net/mr_raptor/article/details/8074549,(感謝老師講解)這裡就不做介紹了。

註冊過程中,調用open_gps();得到device,而dev->get_gps_interface
 = gps__get_gps_interface,從而得到GpsInterface,上層即可使用init等8個介面了;上層在使用Init介面時傳入了gpsCallbacks。這樣上下就建立了聯絡,接下來gps_state_init初始化GPS串口,建立gps_state_thread,然後啟動for(;;)迴圈主控著NMEA資料的讀出、解析、上報等。

3、JNI中介層

GPSJNI適配層的源碼位於:frameworks/base/services/jni/com_android_server_location_GpsLocationProvider.cpp

 


首先看註冊JNI方法的函數定義:

[plain]  int register_android_server_location_GpsLocationProvider(JNIEnv* env) 

    return jniRegisterNativeMethods(env, "com/android/server/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 

 


此函數被同目錄下onload.cpp檔案調用,調用地方在:

[cpp]  extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) 

    JNIEnv* env = NULL; 
    jint result = -1; 
 
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 
        LOGE("GetEnv failed!"); 
        return result; 
    } 
    LOG_ASSERT(env, "Could not retrieve the env!"); 
 
    //...省略其他註冊代碼 
    register_android_server_location_GpsLocationProvider(env); 
 
    return JNI_VERSION_1_4; 


從這裡可以看到,JNI初始化的時候,即會進行JNI方法的註冊,從而使上層應用能通過JNI調用c/c++本地方法。

回到register_android_server_location_GpsLocationProvider函數,變數sMethods定義如下:

[cpp] static JNINativeMethod sMethods[] = { 
     /* name, signature, funcPtr */ 
    {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 
    {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 
    {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 
    {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 
    {"native_set_position_mode", "(IIIII)Z", (void*)android_location_GpsLocationProvider_set_position_mode}, 
    {"native_start", "()Z", (void*)android_location_GpsLocationProvider_start}, 
    {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 
    {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 
    {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 
    {"native_read_nmea", "([BI)I", (void*)android_location_GpsLocationProvider_read_nmea}, 
    {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 
    {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location}, 
    {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 
    {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 
    {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open}, 
    {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, 
    {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, 
    {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id}, 
    {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid}, 
    {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server}, 
    {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response}, 
    {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message}, 
    {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state}, 
    {"native_update_network_state", "(ZIZLjava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state }, 
}; 


JNI是framework與HAL的中間信使,這些函數值得我們認真研究。JNI中,函數的簽名的得到,可以參考http://hi.baidu.com/scuyangl/item/414a039590ef82b5cd80e5dd。在HAL與JNI間調用依靠callback和interface,在framework和JNI間依靠函數Regist(regist是JNI與framework的函數映射,framework可以通過對應的函數調用到JNI的對應函數)和GetMethodID(getMethodID得到的函數在framework實現,JNI可以使用)。
上面函數都是在該.cpp檔案下實現的,比如:


static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {

    return (sGpsInterface != NULL || get_gps_interface() != NULL);
}

4、Java Framework

  


 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.