android gps 代码 分析

更新时间:2023-05-29 10:16:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

android

几个主要的文件及目录:

frameworks/base/location/* (client部分)

frameworks/base/core/jni/android_location_GpsLocationProvider.cpp (JNI 部分)

frameworks/base/services/java/com/android/serverLocationManagerService.java(server 部分) hardware/libhardware_legacy/gps/* (hardware 接口部分)

一是:控制通道,也就是由app层发起的比如enable或disable的控制命令。

example代码调用LocationManager.java ,再通过IPC来实现真正的调用。LocationManager.java 主要负责通信。具体的实现在LocationManagerService.java中。

接口文件是ILocationManager.aidl。在service中根据provider来创建了一个GpsLocationProvider.java,并通过JNI调

android_location_GpsLocationProvider.cpp,该文件再通过GPSInterface来调用硬件的具体实现代码。 二是:

enable后的Location数据和状态上报。对于数据的上报过程,主要就是关注几个callback函数。主要代码分析如下:

在 GpsLocationProvider.java文件中enable()一个GpsLocationProvider时,会启动一个

GpsEventThread,该线程主要就是调用了native_wait_for_event();通过JNI调用到了

anroid_location_GpsLocationProvider.cpp中的

android_location_GpsLocationProvider_wait_for_event();而该event的触发是由来自硬件驱动 Location数据包的上报,底层的硬件驱动程序会把raw gps

data通过pipe或其他的方式,送出来,这个要看gps驱动的实现了,我们通过自己实现的GpsInterface 来解析raw gps data并调用loaction_callback()来触发event并copy

Location数据,等待到event后再调用GpsLocationProvider.java中的reportLocation()上报Location.

除了框架代码外,我们自己需要实现的代码也分为两块,一个是app层的代码,app层我也提供一个简单的代码例子,请参考以下代码:

public class LocationSample extends Activity implements LocationListener {

private LocationManager lm;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(yout.main);

lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,1l,1l,this);

}

public void onLocationChanged(Location location) {

// TODO Auto-generated method stub

Log.d(TAG,"location: ");

}

public void onProviderDisabled(String provider) {

// TODO Auto-generated method stub

Log.d(TAG,"provider disable");

}

public void onProviderEnabled(String provider) {

// TODO Auto-generated method stub

android

Log.d(TAG,"provider enable");

}

public void onStatusChanged(String provider, int status, Bundle extras) {

// TODO Auto-generated method stub

Log.d(TAG,"status changed");

}

}

另外一部分就是hardware/libhardware_legacy/gps

部分的实现,这个主要就是实现一个gps.h里面的几个数据结构:

typedef struct {

gps_location_callback location_cb;

gps_status_callback status_cb;

gps_sv_status_callback sv_status_cb;

} GpsCallbacks;

typedef struct {

int (*init)( GpsCallbacks* callbacks );

int (*start)( void );

int (*stop)( void );

void (*set_fix_frequency)( int frequency );

void (*cleanup)( void );

int (*inject_time)(GpsUtcTime time, int64_t timeReference,

int uncertainty);

void (*delete_aiding_data)(GpsAidingData flags);

int (*set_position_mode)(GpsPositionMode mode, int fix_frequency);

const void* (*get_extension)(const char* name);

} GpsInterface;

typedef struct {

uint16_t flags;

double latitude;

double longitude;

double altitude;

float speed;

float bearing;

float accuracy;

GpsUtcTime timestamp;

} GpsLocation;

在GpsInterface->init()的时候要把上层的GpsCallbacks传进来,然后start后,从驱动那里poll获得gps raw data,并对raw data进行解析并填充GpsLocation数据结构,然后调用location_cb 上报location 数据。

//初始化的时候,得到GpsInterface,调用init,

static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) {

if (!sGpsInterface)

sGpsInterface = gps_get_interface();

return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0);

}

GpsCallbacks sGpsCallbacks = {

android

location_callback,

status_callback,

sv_status_callback,

};

//并且打开串口,注册sGpsCallbacks

qemu_gps_init(GpsCallbacks* callbacks)

----> GpsState* s = _gps_state;

----> gps_state_init(s);

----> s->callbacks = *callbacks;

//打开串口,创建线程

gps_state_init( GpsState* state )

-----> state->fd = qemu_channel_open_gps

-----> pthread_create( &state->thread, NULL, gps_state_thread, state )

static void location_callback(GpsLocation* location)

{

pthread_mutex_lock(&sEventMutex);

sPendingCallbacks |= kLocation;

memcpy(&sGpsLocation, location, sizeof(sGpsLocation));

pthread_cond_signal(&sEventCond); //同步西面的函数

pthread_mutex_unlock(&sEventMutex);

}

//下面这个函数就是由上层的 java调用的,并且等待底层的硬件发送数据,其中由EventCond同步

static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj) {

pthread_mutex_lock(&sEventMutex);

pthread_cond_wait(&sEventCond, &sEventMutex);

// copy and clear the callback flags

int pendingCallbacks = sPendingCallbacks;

sPendingCallbacks = 0;

// copy everything and unlock the mutex before calling into Java code to avoid the possibility // of timeouts in the GPS engine.

memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));

memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));

memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));

pthread_mutex_unlock(&sEventMutex);

if (pendingCallbacks & kLocation) {

env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,

(jdouble)titude, (jdouble)sGpsLocationCopy.longitude, (jdouble)sGpsLocationCopy.altitude,

(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,

(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp); }

android

if (pendingCallbacks & kStatus) {

env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status); }

if (pendingCallbacks & kSvStatus) {

env->CallVoidMethod(obj, method_reportSvStatus);

}

if (pendingCallbacks & kXtraDownloadRequest) {

env->CallVoidMethod(obj, method_xtraDownloadRequest);

}

if (pendingCallbacks & kDisableRequest) {

// don't need to do anything - we are just poking so wait_for_event will return. }

}

//hardware 那部分有个线程gps_state_thread 一直在读串口的内容并进行解析,最后解析到location的信息 由cpp文件的GpsCallbacks sGpsCallbacks = { location_callback....}同步上层的线程

gps_state_thread

----->nmea_reader_addc

----->nmea_reader_parse

------> location_callback

------->数据上报

本文来源:https://www.bwwdw.com/article/wap4.html

Top