android gps机制分析--之三
来源:互联网 发布:招商银行java面试 编辑:程序博客网 时间:2024/06/07 12:39
1 gps打开/初始化
1.1 Java层分析
android系统中打开GPS的方法往数据库里面写值,
private void enableGps(boolean enable) {try {Settings.Secure.setLocationProviderEnabled(getContentResolver(),LocationManager.GPS_PROVIDER, enable);} catch (Exception e) {}}
最后往setting数据库中的location_providers_allowed字段写值。
putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider, userId);
LocationManagerService的systemRunning方法中会监听setting数据库中的location_providers_allowed字段值的变化,
mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true, new ContentObserver(mLocationHandler) { @Override public void onChange(boolean selfChange) { synchronized (mLock) { updateProvidersLocked(); } } }, UserHandle.USER_ALL);
如果该值有变化,则调用updateProvidersLocked方法。主要的流程图如下,
在updateProvidersLocked方法中,如果支持gps,调用updateProviderListenersLocked方法,
updateProviderListenersLocked(name, true);
updateProviderListenersLocked主要方法如下,
•••••boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name);••••if (enabled) { p.enable(); if (listeners > 0) { applyRequirementsLocked(provider); } } else { p.disable(); }
首先调用isAllowedByCurrentUserSettingsLocked方法读取数据库字段值,然后根据该值进行相应的打开/关闭GPS操作。
private boolean isAllowedByCurrentUserSettingsLocked(String provider) { if (mEnabledProviders.contains(provider)) { return true; } if (mDisabledProviders.contains(provider)) { return false; } // Use system settings ContentResolver resolver = mContext.getContentResolver(); return Settings.Secure.isLocationProviderEnabledForUser(resolver, provider, mCurrentUserId); }
Settings中的isLocationProviderEnabledForUser方法如下,
public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) { String allowedProviders = Settings.Secure.getStringForUser(cr, LOCATION_PROVIDERS_ALLOWED, userId); return TextUtils.delimitedStringContains(allowedProviders, ',', provider); }
GpsLocationProvider的enable方法如下,
@Override public void enable() { synchronized (mLock) { if (mEnabled) return; mEnabled = true; } sendMessage(ENABLE, 1, null); }
ProviderHandler对ENABLE消息处理如下,
case ENABLE: if (msg.arg1 == 1) { handleEnable(); } else { handleDisable(); } break;
handleEnable方法如下,
private void handleEnable() { if (DEBUG) Log.d(TAG, "handleEnable"); boolean enabled = native_init(); //初始化GPS HAL层模块 if (enabled) { mSupportsXtra = native_supports_xtra();//判断GPS模块是否支持Xtra // TODO: remove the following native calls if we can make sure they are redundant. if (mSuplServerHost != null) {// 设置SUPL服务器地址和端口 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); } if (mC2KServerHost != null) { //设置CDMA2000 native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); } mGpsMeasurementsProvider.onGpsEnabledChanged(); mGpsNavigationMessageProvider.onGpsEnabledChanged(); } else { synchronized (mLock) { mEnabled = false; } Log.w(TAG, "Failed to enable location provider"); } }
1.2 HAL初始化
com_android_server_location_GpsLocationProvider的android_location_GpsLocationProvider_init方法如下,
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj){ // this must be set before calling into the HAL library if (!mCallbacksObj) mCallbacksObj = env->NewGlobalRef(obj); // fail if the main interface fails to initialize if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) return JNI_FALSE; // if XTRA initialization fails we will disable it by sGpsXtraInterface to NULL, // but continue to allow the rest of the GPS interface to work. if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0) sGpsXtraInterface = NULL; if (sAGpsInterface) sAGpsInterface->init(&sAGpsCallbacks); if (sGpsNiInterface) sGpsNiInterface->init(&sGpsNiCallbacks); if (sAGpsRilInterface) sAGpsRilInterface->init(&sAGpsRilCallbacks); if (sGpsGeofencingInterface) sGpsGeofencingInterface->init(&sGpsGeofenceCallbacks); return JNI_TRUE;}
主要是向HAL层设置回调方法接口,当HAL层有情况需要通知JNI层时,就会回调这些方法。
这6组回调方法的定义,回调方法几乎完全一样。sGpsCallbacks的定义如下,
GpsCallbacks sGpsCallbacks = { sizeof(GpsCallbacks), location_callback, status_callback, sv_status_callback, nmea_callback, set_capabilities_callback, acquire_wakelock_callback, release_wakelock_callback, create_thread_callback, request_utc_time_callback,};
sGpsCallbacks中包含9个回调方法。
这样,HAL库就可以回调C方法了。
由此可见, com_android_server_location_GpsLocationProvider只是Java和HAL库之间的一个纽带。
1,Java中加载HAL库,并且对HAL库进行初始化。然后就可以对HAL的GPS发出指令,例如打开,关闭GPS等。这时数据流的方向为,
Java-->JNI--> GPS库
2,GPS库中执行打开/关闭动作,向Java上报卫星以及定位消息。这时数据流的方向为,
GPS库-->JNI--> Java
GPS库中对应的init方法为, loc.cpp 的loc_init方法,
static int loc_init(GpsCallbacks* callbacks){ int retVal = -1; ENTRY_LOG(); LOC_API_ADAPTER_EVENT_MASK_T event; if (NULL == callbacks) { LOC_LOGE("loc_init failed. cb = NULL\n"); EXIT_LOG(%d, retVal); return retVal; } event = LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT | LOC_API_ADAPTER_BIT_SATELLITE_REPORT | LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST | LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST | LOC_API_ADAPTER_BIT_IOCTL_REPORT | LOC_API_ADAPTER_BIT_STATUS_REPORT | LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT | LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST; // 继续注册回调 LocCallbacks clientCallbacks = {local_loc_cb, /* location_cb */ callbacks->status_cb, /* status_cb */ local_sv_cb, /* sv_status_cb */ callbacks->nmea_cb, /* nmea_cb */ callbacks->set_capabilities_cb, /* set_capabilities_cb */ callbacks->acquire_wakelock_cb, /* acquire_wakelock_cb */ callbacks->release_wakelock_cb, /* release_wakelock_cb */ callbacks->create_thread_cb, /* create_thread_cb */ NULL, /* location_ext_parser */ NULL, /* sv_ext_parser */ callbacks->request_utc_time_cb, /* request_utc_time_cb */ }; gps_loc_cb = callbacks->location_cb; gps_sv_cb = callbacks->sv_status_cb; // loc_eng_init以及里面的方法较复杂,暂不论述。 retVal = loc_eng_init(loc_afw_data, &clientCallbacks, event, NULL); loc_afw_data.adapter->mSupportsAgpsRequests = !loc_afw_data.adapter->hasAgpsExtendedCapabilities(); loc_afw_data.adapter->mSupportsPositionInjection = !loc_afw_data.adapter->hasCPIExtendedCapabilities(); loc_afw_data.adapter->mSupportsTimeInjection = !loc_afw_data.adapter->hasCPIExtendedCapabilities(); loc_afw_data.adapter->setGpsLockMsg(0); loc_afw_data.adapter->requestUlp(getCarrierCapabilities()); loc_afw_data.adapter->setXtraUserAgent(); if(retVal) { LOC_LOGE("loc_eng_init() fail!"); goto err; } loc_afw_data.adapter->setPowerVoteRight(loc_get_target() == TARGET_QCA1530); loc_afw_data.adapter->setPowerVote(true); LOC_LOGD("loc_eng_init() success!");err: EXIT_LOG(%d, retVal); return retVal;}
gps.h中有对应的GpsCallbacks结构,
typedef struct { /** set to sizeof(GpsCallbacks) */ size_t size; gps_location_callback location_cb; gps_status_callback status_cb; gps_sv_status_callback sv_status_cb; gps_nmea_callback nmea_cb; gps_set_capabilities set_capabilities_cb; gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_create_thread create_thread_cb; gps_request_utc_time request_utc_time_cb;} GpsCallbacks;
这样,HAL层的gps_location_callback方法就对应com_android_server_location_GpsLocationProvide
中的location_callback方法,其他的回调对应的也一样。
- android gps机制分析--之三
- android gps机制分析--之二
- android gps机制分析--之四
- android gps机制分析--之五
- android gps机制分析--之六
- android gps机制分析--之七
- android gps机制分析--之八
- android gps机制分析--之一
- Android GPS架构分析(三)
- Android GPS架构分析(三)
- Android GPS架构分析(三)
- Android架构分析之Android消息处理机制(三)
- Android GPS架构分析之二
- android gps机制分析--定位数据HAL处理
- android gps机制分析--定位数据传输到Java
- android gps机制分析--定位数据HAL处理
- Android的GPS的代码分析(三)
- Android的GPS的代码分析(三)
- 表单验证
- bash shell 学习笔记
- 算法:图的普里姆算法最小生成树-数据结构(22)
- 【剑指offer-解题系列(15)】反转链表
- html5调用手机相机并压缩、上传
- android gps机制分析--之三
- 女装大佬
- 1142: 简单的事情
- css 布局中的 BFC
- Largest Rectangle in Histogram
- LeetCode 338. Counting Bits
- Android开发常见问题之"Failed to convert @drawable/xx into a drawable Exception details are logged in Window
- ImageLoader+网络请求+ListView多条目加载
- java版本升级异常Unsupported major.minor version 52.0处理