日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

android系统学习笔记十一

發(fā)布時間:2025/5/22 windows 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android系统学习笔记十一 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Gps??(global???Position??System?全球定位系統(tǒng))和定位部分

除此之外還有利用基站(cell)定位的AGPS等設(shè)備

?定們系列統(tǒng)的基本架構(gòu)

?主要數(shù)據(jù)來源有兩個:?GPS定位和network定位(基于cellwifi熱點的定位)

定位部分的結(jié)構(gòu)如圖

??定位系統(tǒng)的驅(qū)動層

?Network定位的底層驅(qū)動和適配層實際上就是RILwifi框架的組成部分

?Cell定位就是利用基站的cellID以及LAC實現(xiàn)

?Wifi則是利用熱點的相關(guān)信息?如名字?mac地址?ip地址實現(xiàn)

?GPS?設(shè)備分為硬GPS?和軟GPS?

???硬GPS上電就可以直接輸出NMEA?數(shù)據(jù)

???軟GPS需要主控芯片控制其運行狀態(tài),需要主控方進行計算才能得到NMEA數(shù)據(jù)

?GPS本地實現(xiàn)

GPS的本地實現(xiàn)部分主要是GPS適配層,頭文件的路徑為:\hardware\libhardware\include\hardware

該目錄下的gps.h提供了JNI層調(diào)用的接口,該文件定義的常量,包括位置模式、狀態(tài)值、定位標(biāo)志、幫助數(shù)據(jù)

//定義了標(biāo)準(zhǔn)GPS接口的結(jié)構(gòu)體

typedef?struct?{

????/**?set?to?sizeof(GpsInterface)?*/

????size_t??????????size;

????/**

?????*?Opens?the?interface?and?provides?the?callback?routines

?????*?to?the?implemenation?of?this?interface.

????????初始化GPS,設(shè)置回調(diào)函數(shù)

?????*/

????int???(*init)(?GpsCallbacks*?callbacks?);

/**?Starts?navigating.?*/?

//開始導(dǎo)航

????int???(*start)(?void?);

/**?Stops?navigating.?*/

//停止導(dǎo)航

????int???(*stop)(?void?);

/**?Closes?the?interface.?*/

//關(guān)閉接口

????void??(*cleanup)(?void?);

/**?Injects?the?current?time.?*/

//設(shè)請求頻率

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

?????????????????????????int?uncertainty);

????/**?Injects?current?location?from?another?location?provider

?????*??(typically?cell?ID).

?????*??latitude?and?longitude?are?measured?in?degrees

?????*??expected?accuracy?is?measured?in?meters

?????*/

????int??(*inject_location)(double?latitude,?double?longitude,?float?accuracy);

????/**

?????*?Specifies?that?the?next?call?to?start?will?not?use?the

?????*?information?defined?in?the?flags.?GPS_DELETE_ALL?is?passed?for

?????*?a?cold?start.

?????*/

????//刪除幫助信息

????void??(*delete_aiding_data)(GpsAidingData?flags);

????/**

?????*?min_interval?represents?the?time?between?fixes?in?milliseconds.

?????*?preferred_accuracy?represents?the?requested?fix?accuracy?in?meters.

?????*?preferred_time?represents?the?requested?time?to?first?fix?in?milliseconds.

?????*/

????//設(shè)置位置模式

????int???(*set_position_mode)(GpsPositionMode?mode,?GpsPositionRecurrence?recurrence,

????????????uint32_t?min_interval,?uint32_t?preferred_accuracy,?uint32_t?preferred_time);

/**?Get?a?pointer?to?extension?information.?*/

//獲得擴展消息的指針

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

}?GpsInterface;

//表示GPS的定位信息

typedef?struct?{

????/**?set?to?sizeof(GpsLocation)?*/

????size_t??????????size;

/**?Contains?GpsLocationFlags?bits.?*/

//標(biāo)志位

????uint16_t????????flags;

/**?Represents?latitude?in?degrees.?*/

//表示緯度

????double??????????latitude;

/**?Represents?longitude?in?degrees.?*/

//表示經(jīng)度

????double??????????longitude;

????/**?Represents?altitude?in?meters?above?the?WGS?84?reference

?????*?ellipsoid.?*/

?????//WGS84坐標(biāo)系統(tǒng)表示的高度信息

????double??????????altitude;

/**?Represents?speed?in?meters?per?second.?*/

//速度??m/s

????float???????????speed;

/**?Represents?heading?in?degrees.?*/

//表示方向

????float???????????bearing;

/**?Represents?expected?accuracy?in?meters.?*/

//表示精度

????float???????????accuracy;

/**?Timestamp?for?the?location?fix.?*/

//表示時間戮

????GpsUtcTime??????timestamp;

}?GpsLocation;

當(dāng)上層調(diào)用:GpsInterface.init時,會調(diào)用一個gpscallbacks結(jié)構(gòu)指針,注冊到適配層

//位置信息的回調(diào)函數(shù)

typedef?void?(*?gps_location_callback)(GpsLocation*?location);

//?狀態(tài)信息的回調(diào)函數(shù)

typedef?void?(*?gps_status_callback)(GpsStatus*?status);

//SV狀態(tài)信息的回調(diào)函數(shù)

typedef?void?(*?gps_sv_status_callback)(GpsSvStatus*?sv_info);

??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;

}?GpsCallbacks;

GPS的部分源代碼路徑為:\hardware\qcom\gps

GPS組件的目標(biāo)文件是;libhardware_legacy.so

Gps_qemu.c文件是基于模擬器環(huán)境的GPS適配層,在編寫特定的GPS?適配層時,可以以gps_quemu.c中的大部分處理流程作為基礎(chǔ)進行改寫,它實現(xiàn)了一套NMEA解析機制,以及gps.h中的gpsInterface接口,

gpsInterface?接口比較簡單,包括啟動/停止和上報頻率等接口,

NEMA解析是核心,是基于文本塊的算法

因為是模擬,所以NMEA數(shù)據(jù)需要從一個socket接口gps_fd傳輸進來.??在獨立線程中進行解析

NMEA數(shù)據(jù)最終會解析成gps.h中定義的gpsLocation的格式

GPS?部分JNI的實現(xiàn)

代碼的路徑為:\frameworks\base\services\jni\com_android_server_location_GpsLocationProvider.cpp

JNI層直接與GPS驅(qū)動層打交道,它訪問適配層定義的GpaInterface?實現(xiàn)自已的gpscallbacksGPS適配層調(diào)用

部分代碼如下:

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,

};

JNI實現(xiàn)了一個native_wait_for_event函數(shù),上層如果需要獲得消息,則在獨立線程中調(diào)用此函數(shù)阻塞

如果上層有NMEA解析完成并回調(diào),通過線程同步機制,使等待的native_wait_for_event的線程取得上報數(shù)據(jù),完成一次數(shù)據(jù)上報

Xtra是部分增強型GPS的機制,可以提前從網(wǎng)上下載數(shù)據(jù)

定位系統(tǒng)的java實現(xiàn)

代碼路徑為:\frameworks\base\location\java\android\location

ILocationManagerandroid?定們系統(tǒng)的核心

LocationServiceManager是定位系統(tǒng)的服務(wù)器端,它在目錄:\frameworks\base\services\java\com\android\server下

LocationProviderProxy?mNetworkLocationProvider;

?????LocationProviderInterface?mGpsLocationProvider;

**************************************************************

2.3中的變化

**************************************************************

\frameworks\base\services\java\com\android\server\location目錄下的GpsLocationProvider.java它直接繼承

LocationProviderInterface(23之前可能是LocationProviderImpl),?它提供了底層的控制接口,同時開啟一個gpsEventThread通過輪詢native_wait_for_event來取得底層上報的數(shù)據(jù)

App發(fā)出定位申請,啟動定位服務(wù)線程,此線程會在APP?framwork中調(diào)用location?provider

通過被native方法調(diào)用到JNI,?JNI獲得gpsInterface并傳給接口一個回調(diào)函數(shù)的實現(xiàn)

gpsInterface就是HAL層最主要的實現(xiàn)

?

上層實現(xiàn)的思路

1、獲取GPSLocation?Provider

?2、將此Provider傳入到requestLocationUpdates()方法,讓Android系統(tǒng)獲知搜索位置方式。

?3、創(chuàng)建實現(xiàn)了GpsStatus.Listener接口的對象,重寫onGpsStatusChanged()方法,向LocationManager添加次監(jiān)聽器,檢測衛(wèi)星狀態(tài)。(可選步驟)

Android?GPS?架構(gòu)分析

Framework?:?

?代碼路徑為:

1?\frameworks\base\location\java\android\location

?供api調(diào)用

?2?frameworks\base\location\java\com\android\internal\location

?這個目錄是frameworklocation服務(wù)的內(nèi)部實現(xiàn)

3?\frameworks\base\services\java\com\android\server

??這是location服務(wù)對內(nèi)部實現(xiàn)的一個封裝

JNI層:

?代碼路徑:

22版本中

frameworks/base/core/jni/android_location_GpsLocationProvider.cpp

2.3版式本中

\frameworks\base\services\jni\com_android_server_location_GpsLocationProvider.cpp

上層承接freanwork,下層調(diào)用HAL

HAL硬件抽象層:?

代碼路徑

?2.3?

?\hardware\libhardware\include\hardware

/framework/base/services/jni/com_android_server_location_GpsLocationProvider.cpp

?相當(dāng)于linux應(yīng)用程序的一個接口,直接操作硬件設(shè)備

底層幾個重要和數(shù)據(jù)結(jié)構(gòu)

1?gpsInterface?是最重要的數(shù)據(jù)結(jié)構(gòu),它是底層實現(xiàn)的接口,如果要porting到自已的板子上,就要實現(xiàn)這這些接口,

??該接口的定義在gps.h,模擬器實現(xiàn)在gps_qemu.c

?typedef?struct?{???

????size_t??????????size;????

????int???(*init)(?GpsCallbacks*?callbacks?);

????????int???(*start)(?void?);

????????int???(*stop)(?void?);

????void??(*cleanup)(?void?);

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

?????????????????????????int?uncertainty);

????int??(*inject_location)(double?latitude,?double?longitude,?float?accuracy);??

????void??(*delete_aiding_data)(GpsAidingData?flags);???

????int???(*set_position_mode)(GpsPositionMode?mode,?GpsPositionRecurrence?recurrence,

????????????uint32_t?min_interval,?uint32_t?preferred_accuracy,?uint32_t?preferred_time);

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

}?GpsInterface;

2?gpscallbacks回調(diào)函數(shù)結(jié)構(gòu)體,定義同上,實現(xiàn)在com_android_server_android_location_GpsLocationProvider.cpp

typedef?struct?{

????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;

????//以下幾個回調(diào)函數(shù)是在2.3以后添加的回調(diào)函數(shù)

????gps_set_capabilities?set_capabilities_cb;

????gps_acquire_wakelock?acquire_wakelock_cb;

????gps_release_wakelock?release_wakelock_cb;

????gps_create_thread?create_thread_cb;

}?GpsCallbacks;

3?Gpslocation表示loaction數(shù)據(jù)信息?2.32.2多了個size屬性

typedef?struct?{

????//2.3之后添加

??????size_t??????????size;?

????uint16_t????????flags;????

????double??????????latitude;??

????double??????????longitude;???

????double??????????altitude;?

????float???????????speed;???

????float???????????bearing;??

????float???????????accuracy;???

????GpsUtcTime??????timestamp;

}?GpsLocation;

Gps的定位服務(wù)(locationManager)的啟動過程

LocationManager這項服務(wù)是systemServer.java?來啟動,也就是在系統(tǒng)啟動之后就啟動

systemServer.java?[framework/base/services/java/com/android/server]?

public?static?final?void?init2()?{

Slog.i(TAG,?"Entered?the?Android?system?server!");?

Thread?thr?=?new?ServerThread();?

thr.setName("android.server.ServerThread");?

thr.start();?

}

ServerThread線程的run函數(shù)中LocationManager服務(wù)的代碼段如下:?

try?{

????????????????Slog.i(TAG,?"Location?Manager");?

????????????????location?=?new?LocationManagerService(context);?

????????????????ServiceManager.addService(Context.LOCATION_SERVICE,?location);?

????????????}?catch?(Throwable?e)?{?

????????????????Slog.e(TAG,?"Failure?starting?Location?Manager",?e);?

}

run函數(shù)的后半部分,是服務(wù)對系統(tǒng)的反饋,就是systemReady()函數(shù)。?LocationManager服務(wù)的反饋函數(shù)如下:

final?LocationManagerService?locationF?=?location;

其中的locationF?LocationManagerServicefinal類型,就是一旦賦值,不能更改。

if?(locationF?!=?null)?locationF.systemReady();

LocationManagerService代碼路徑如下:\frameworks\base\services\java\com\android\server

構(gòu)造器如下:

???public?LocationManagerService(Context?context)?{

????????super();

????????mContext?=?context;

????????Resources?resources?=?context.getResources();

????????mNetworkLocationProviderPackageName?=?resources.getString(

????????????????com.android.internal.R.string.config_networkLocationProvider);

????????mGeocodeProviderPackageName?=?resources.getString(

????????????????com.android.internal.R.string.config_geocodeProvider);

????????mPackageMonitor.register(context,?true);

????????if?(LOCAL_LOGV)?{

????????????Slog.v(TAG,?"Constructed?LocationManager?Service");

????????}

????}

void?systemReady()?{

????????//?we?defer?starting?up?the?service?until?the?system?is?ready?

????????Thread?thread?=?new?Thread(null,?this,?"LocationManagerService");

????????thread.start();

????}

?在run函數(shù)中,又調(diào)用了initialize?函數(shù)

?public?void?run()

????{

????????Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

????????Looper.prepare();

????????mLocationHandler?=?new?LocationWorkerHandler();

????????initialize();//************************

????????Looper.loop();

????}

??private?void?initialize()?{

????????//?Create?a?wake?lock,?needs?to?be?done?before?calling?loadProviders()?below

????????PowerManager?powerManager?=?(PowerManager)?mContext.getSystemService(Context.POWER_SERVICE);

????????mWakeLock?=?powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,?WAKELOCK_KEY);

????????//?Load?providers

????????//重要方法

????????loadProviders();

????????//?Register?for?Network?(Wifi?or?Mobile)?updates

????????IntentFilter?intentFilter?=?new?IntentFilter();

????????intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

????????//?Register?for?Package?Manager?updates

????????intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);

????????intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);

????????intentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);

????????mContext.registerReceiver(mBroadcastReceiver,?intentFilter);

????????IntentFilter?sdFilter?=?new?IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);

????????mContext.registerReceiver(mBroadcastReceiver,?sdFilter);

????????//?listen?for?settings?changes

????????ContentResolver?resolver?=?mContext.getContentResolver();

????????Cursor?settingsCursor?=?resolver.query(Settings.Secure.CONTENT_URI,?null,

????????????????"("?+?Settings.System.NAME?+?"=?)",

????????????????new?String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},

????????????????null);

????????mSettings?=?new?ContentQueryMap(settingsCursor,?Settings.System.NAME,?true,?mLocationHandler);

????????SettingsObserver?settingsObserver?=?new?SettingsObserver();

????????mSettings.addObserver(settingsObserver);

????}

初始化函數(shù)中,最重要的便是?loadProviders()函數(shù)。

private?void?loadProviders()?{

????????synchronized?(mLock)?{?

????????????if?(sProvidersLoaded)?{?

????????????????return;?

????????????}?

????????????//?Load?providers

????????????loadProvidersLocked();?

????????????sProvidersLoaded?=?true;?

????????}?

????}

?

?private?void?loadProvidersLocked()?{

????????try?{

????????????_loadProvidersLocked();

????????}?catch?(Exception?e)?{

????????????Slog.e(TAG,?"Exception?loading?providers:",?e);

????????}

}

_loadProvidersLocked函數(shù),?

?private?void?_loadProvidersLocked()?{

????????//?Attempt?to?load?"real"?providers?first

????????//取得GPS的接口

????????if?(GpsLocationProvider.isSupported())?{

????????????//?Create?a?gps?location?provider

????????????GpsLocationProvider?gpsProvider?=?new?GpsLocationProvider(mContext,?this);

????????????mGpsStatusProvider?=?gpsProvider.getGpsStatusProvider();

????????????mNetInitiatedListener?=?gpsProvider.getNetInitiatedListener();

????????????addProvider(gpsProvider);

????????????mGpsLocationProvider?=?gpsProvider;

????????}

????????//?create?a?passive?location?provider,?which?is?always?enabled

????????PassiveProvider?passiveProvider?=?new?PassiveProvider(this);

????????addProvider(passiveProvider);

????????mEnabledProviders.add(passiveProvider.getName());

????????//?initialize?external?network?location?and?geocoder?services

????????if?(mNetworkLocationProviderPackageName?!=?null)?{

????????????mNetworkLocationProvider?=

????????????????new?LocationProviderProxy(mContext,?LocationManager.NETWORK_PROVIDER,

????????????????????????mNetworkLocationProviderPackageName,?mLocationHandler);

????????????addProvider(mNetworkLocationProvider);

????????}

????????if?(mGeocodeProviderPackageName?!=?null)?{

????????????mGeocodeProvider?=?new?GeocoderProxy(mContext,?mGeocodeProviderPackageName);

????????}

????????updateProvidersLocked();

????}

GpsLocationProvider.isSupported()得到了HAL層的GPS接口gpsInterface

調(diào)用到gps.cpp[hardware/libhardware_legacy/gps]中的gps_get_interface()

GpsLocationProvider的路徑為:\frameworks\base\services\java\com\android\server\location

?部分代碼如下:

???public?static?boolean?isSupported()?{

????????//調(diào)用的是本地方法

????????return?native_is_supported();

????}

函數(shù)中只有一句話,?這調(diào)用了native方法,既Jni層定義的方法。native_is_supported對應(yīng)在

framework/base/services/jni/com_android_server_location_GpsLocationProvider.cpp文件中的android_location_GpsLocationProvider_is_supported方法。

?部分代碼如下;

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

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

}

get_gps_interface()的具體代碼如下:

static?const?GpsInterface*?get_gps_interface()?{

????int?err;

????hw_module_t*?module;

????const?GpsInterface*?interface?=?NULL;

????err?=?hw_get_module(GPS_HARDWARE_MODULE_ID,?(hw_module_t?const**)&module);

????if?(err?==?0)?{

????????hw_device_t*?device;

????????err?=?module->methods->open(module,?GPS_HARDWARE_MODULE_ID,?&device);

????????if?(err?==?0)?{

????????????gps_device_t*?gps_device?=?(gps_device_t?*)device;

????????????interface?=?gps_device->get_gps_interface(gps_device);

????????}

????}

????return?interface;

}

?get_gps_interface去打開模組,之后打開設(shè)備,然后通過設(shè)備區(qū)調(diào)用HAL層中的get_gps_interfacegps_device

gps.c(代碼路徑為:\hardware\qcom\gps\loc_api\libloc_api)中實現(xiàn)的gps__get_gps_interfacey調(diào)用了loc_eng.cpp

gps.c部分代碼如下:

const?GpsInterface*?gps__get_gps_interface(struct?gps_device_t*?dev)

{

????return?get_gps_interface();

}

loc_eng.cpp的部分代碼如下:

static?const?GpsInterface?sLocEngInterface?=

{

????sizeof(GpsInterface),

????loc_eng_init,

????loc_eng_start,

????loc_eng_stop,

????loc_eng_cleanup,

????loc_eng_inject_time,

????loc_eng_inject_location,

????loc_eng_delete_aiding_data,

????loc_eng_set_position_mode,

????loc_eng_get_extension,

};

經(jīng)過以的操作我們就獲得了GPS的接口,?locationManagerService.java,如果找到了硬件,并取得了接口后,接著執(zhí)行下一句

?GpsLocationProvider?gpsProvider?=?new?GpsLocationProvider(mContext,?this);

GpsLocationProvider的代碼路徑為:frameworks\base\services\java\com\android\server\location

?public?GpsLocationProvider(Context?context,?ILocationManager?locationManager)?{

????????mContext?=?context;

????????//mLocationManager就是第二個參數(shù).也就是locationManagerService

????????mLocationManager?=?locationManager;

????????mNIHandler?=?new?GpsNetInitiatedHandler(context);

????????mLocation.setExtras(mLocationExtras);

....................

}

_loadProvidersLocked函數(shù),在構(gòu)造完成后,將其add到全局變量ArrayList<LocationProviderInterface>?mProviders中,備以后調(diào)用.

接著啟動了兩個線程,但是可惜的是這兩個服務(wù)都無法啟動,因為他們是通過配置文件conifg.xml?得到服務(wù)的名字,然后啟動服務(wù)的。但是在這個配置文件中,兩個服務(wù)的名字都是null

配置文件的路徑為;framework/base/core/res/res/values

部分代碼如下:

<!--?Component?name?of?the?service?providing?network?location?support.?-->

????<string?name="config_networkLocationProvider">@null</string>

????<!--?Component?name?of?the?service?providing?geocoder?API?support.?-->

????<string?name="config_geocodeProvider">@null</string>

這就是為什么在調(diào)用getFromLocationName和?getFromLocation時會提示service?not?available,2.2就存在的bug

_loadProvidersLocked函數(shù)的最后調(diào)用的是updateProvidersLocked();也在這個類中

部分代碼如下:

?private?void?updateProvidersLocked()?{

????????boolean?changesMade?=?false;

????????for?(int?i?=?mProviders.size()?-?1;?i?>=?0;?i--)?{

????????????LocationProviderInterface?p?=?mProviders.get(i);

????????????boolean?isEnabled?=?p.isEnabled();

????????????String?name?=?p.getName();

????????????boolean?shouldBeEnabled?=?isAllowedBySettingsLocked(name);

????????????if?(isEnabled?&&?!shouldBeEnabled)?{

????????????????updateProviderListenersLocked(name,?false);

????????????????changesMade?=?true;

????????????}?else?if?(!isEnabled?&&?shouldBeEnabled)?{

????????????????updateProviderListenersLocked(name,?true);

????????????????changesMade?=?true;

????????????}

????????}

????????if?(changesMade)?{

????????????mContext.sendBroadcast(new?Intent(LocationManager.PROVIDERS_CHANGED_ACTION));

????????}

????}

mProviders里面應(yīng)該存在一個gpsProvider?PassiveProvider,而gpsProvider是未被enable的。而passiveProviderenable的。

這邊我們對gpsProvider進行討論,他執(zhí)行的是updateProviderListenersLockedname,true)?然后當(dāng)有發(fā)生改變,就是changesMade=true時,它發(fā)送了廣播,內(nèi)容是告訴大家LocationManager發(fā)生了變化,讓需要的接收者自己接收。?

?updateProviderListenersLocked(name,?false)函數(shù)的部分代碼如下:

????private?void?updateProviderListenersLocked(String?provider,?boolean?enabled)?{

????????int?listeners?=?0;

????????LocationProviderInterface?p?=?mProvidersByName.get(provider);

????????if?(p?==?null)?{

????????????return;

????????}

????????ArrayList<Receiver>?deadReceivers?=?null;

????????

????????ArrayList<UpdateRecord>?records?=?mRecordsByProvider.get(provider);

????????if?(records?!=?null)?{

????????????final?int?N?=?records.size();

????????????for?(int?i=0;?i<N;?i++)?{

????????????????UpdateRecord?record?=?records.get(i);

????????????????//?Sends?a?notification?message?to?the?receiver

????????????????if?(!record.mReceiver.callProviderEnabledLocked(provider,?enabled))?{

????????????????????if?(deadReceivers?==?null)?{

????????????????????????deadReceivers?=?new?ArrayList<Receiver>();

????????????????????}

????????????????????deadReceivers.add(record.mReceiver);

????????????????}

????????????????listeners++;

????????????}

????????}

????????if?(deadReceivers?!=?null)?{

????????????for?(int?i=deadReceivers.size()-1;?i>=0;?i--)?{

????????????????removeUpdatesLocked(deadReceivers.get(i));

????????????}

????????}

????????//如果為真則啟動gas

????????if?(enabled)?{

????????????p.enable();

????????????if?(listeners?>?0)?{

????????????????p.setMinTime(getMinTimeLocked(provider),?mTmpWorkSource);

????????????????p.enableLocationTracking(true);

????????????}

????????}?else?{

????????????p.enableLocationTracking(false);

????????????p.disable();

????????}

????}

if(enable)中,如果enable?為真,則啟動GPS,調(diào)用p.enable()方法,該方法的實現(xiàn)是在

GpsLocationProvider.java類中他繼承了LocationProviderInterface

代碼路徑為:\frameworks\base\services\java\com\android\server\location

部分代碼如下:

???public?void?enable()?{

????????synchronized?(mHandler)?{

????????????sendMessage(ENABLE,?1,?null);

????????}

????}

?

???//每次進入此消息,就是清除之前所有消息發(fā)送消息交給handlerMassage處理

??private?void?sendMessage(int?message,?int?arg,?Object?obj)?{

????????//?hold?a?wake?lock?while?messages?are?pending

????????synchronized?(mWakeLock)?{

????????????mPendingMessageBits?|=?(1?<<?message);

????????????mWakeLock.acquire();

????????????mHandler.removeMessages(message);

????????????Message?m?=?Message.obtain(mHandler,?message);

????????????m.arg1?=?arg;

????????????m.obj?=?obj;

????????????mHandler.sendMessage(m);

????????}

????}

handlerMessage?中的處理.?調(diào)用handleEnable();

?public?void?handleMessage(Message?msg)?{

????????????int?message?=?msg.what;

????????????switch?(message)?{

????????????????case?ENABLE:

????????????????????if?(msg.arg1?==?1)?{

????????????????????????handleEnable();

????????????????????}?else?{

????????????????????????handleDisable();

????????????????????}

????????????????????break;

???????}

??????handleEnable?主要作了兩件事,

????????1?調(diào)用本地方法?native_init(),初始化gps

?????????本地方法的具體實現(xiàn)是在com_android_server_location_GpsLocationProvider.cpp,

??????????部分內(nèi)容為下:

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

{

????//取得接口,并初始化gps?

????const?GpsInterface*?interface?=?GetGpsInterface(env,?obj);

????if?(!interface)

????????return?false;

????if?(!sGpsDebugInterface)

???????sGpsDebugInterface?=?(const???GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE);

????return?true;

}

????????2?試圖啟動AGPS服務(wù)

???代碼如下:

?private?void?handleEnable()?{

????????if?(DEBUG)?Log.d(TAG,?"handleEnable");

????????if?(mEnabled)?return;

????????//調(diào)用本地方法初始化GPS

????????mEnabled?=?native_init();

????????

????????//試圖啟動AGPS服務(wù)

????????if?(mEnabled)?{

????????????mSupportsXtra?=?native_supports_xtra();

????????????if?(mSuplServerHost?!=?null)?{

????????????????native_set_agps_server(AGPS_TYPE_SUPL,?mSuplServerHost,?mSuplServerPort);

????????????}

????????????if?(mC2KServerHost?!=?null)?{

????????????????native_set_agps_server(AGPS_TYPE_C2K,?mC2KServerHost,?mC2KServerPort);

????????????}

????????}?else?{

????????????Log.w(TAG,?"Failed?to?enable?location?provider");

????????}

????}

取得接口的方法中,也調(diào)用了?get_gps_interface

代碼如下:

static?const?GpsInterface*?GetGpsInterface(JNIEnv*?env,?jobject?obj)?{

????//?this?must?be?set?before?calling?into?the?HAL?library

????if?(!mCallbacksObj)

????????mCallbacksObj?=?env->NewGlobalRef(obj);

????if?(!sGpsInterface)?{

????????sGpsInterface?=?get_gps_interface();

????????if?(!sGpsInterface?||?sGpsInterface->init(&sGpsCallbacks)?!=?0)?{

????????????sGpsInterface?=?NULL;

????????????return?NULL;

????????}

????}

????return?sGpsInterface;

}

Gps_qemu.c的代碼路徑為:\sdk\emulator\gps

這邊qemu_gps_init函數(shù)即是sGpsInterface->init函數(shù),其中里面做了gps_state_init初始化,并注冊了callbacks回調(diào)函數(shù),而這個函數(shù)也是在JNI層實現(xiàn)的,而且有JNI層傳下來的函數(shù)。

部分代碼為;

qemu_gps_init(GpsCallbacks*?callbacks)

{

????GpsState*??s?=?_gps_state;

????if?(!s->init)

????????gps_state_init(s);

????if?(s->fd?<?0)

????????return?-1;

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

????return?0;

}

在這個主方法中首先打開串口,然后進立socket通信,然后建立線程監(jiān)聽底層數(shù)據(jù)上報

static?void

gps_state_init(?GpsState*??state?)

{

????state->init???????=?1;

????state->control[0]?=?-1;

????state->control[1]?=?-1;

????state->fd?????????=?-1;

????state->fd?=?qemud_channel_open(QEMU_CHANNEL_NAME);

????if?(state->fd?<?0)?{

????????D("no?gps?emulation?detected");

????????return;

????}

????D("gps?emulation?will?read?from?'%s'?qemud?channel",?QEMU_CHANNEL_NAME?);

????if?(?socketpair(?AF_LOCAL,?SOCK_STREAM,?0,?state->control?)?<?0?)?{

????????LOGE("could?not?create?thread?control?socket?pair:?%s",?strerror(errno));

????????goto?Fail;

????}

????if?(?pthread_create(?&state->thread,?NULL,?gps_state_thread,?state?)?!=?0?)?{

????????LOGE("could?not?create?gps?thread:?%s",?strerror(errno));

????????goto?Fail;

????}

????D("gps?state?initialized");

????return;

Fail:

????gps_state_done(?state?);

}

該方法說明在初始化時調(diào)用的相關(guān)擴展接口是沒用的

static?const?void*

qemu_gps_get_extension(const?char*?name)

{

????//?no?extensions?supported

????return?NULL;

}

22的時候handlerEnable還創(chuàng)建了一個監(jiān)聽線程

而在2.3GpsLocationProvider(路徑為:frameworks\base\services\java\com\android\server\location

在構(gòu)造函數(shù)中就創(chuàng)建了這個?監(jiān)聽線程

構(gòu)造器中的部分代碼

?mThread?=?new?GpsLocationProviderThread();

????????mThread.start();

????????while?(true)?{

????????????try?{

????????????????mInitializedLatch.await();

????????????????break;

????????????}?catch?(InterruptedException?e)?{

????????????????Thread.currentThread().interrupt();

????????????}

????????}

//run函數(shù)的部分內(nèi)容

//initialize初始化函數(shù),然后新建一個looper,新建一個providerHandler?用于處理該線程的消息

private?final?class?GpsLocationProviderThread?extends?Thread?{

????????public?GpsLocationProviderThread()?{

????????????super("GpsLocationProvider");

????????}

????????public?void?run()?{

????????????Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

????????????initialize();

????????????Looper.prepare();

????????????mHandler?=?new?ProviderHandler();

????????????//?signal?when?we?are?initialized?and?ready?to?go

????????????mInitializedLatch.countDown();

????????????Looper.loop();

????????}

}

??private?void?initialize()?{

????????//?register?our?receiver?on?our?thread?rather?than?the?main?thread

????????IntentFilter?intentFilter?=?new?IntentFilter();

????????intentFilter.addAction(ALARM_WAKEUP);

????????intentFilter.addAction(ALARM_TIMEOUT);

????????mContext.registerReceiver(mBroadcastReciever,?intentFilter);

????}

初始化主要是將線程的接收者注冊到我們的線程上,而不是注冊到主線程上。

到這邊為止我們完成了?p.enable()函數(shù)的分析。

locationManagerService.java,run?()--->?initialize()--->loadProviders()----->loadProvidersLocked()

------->_loadProvidersLocked()------->updateProvidersLocked()------>updateProviderListenersLocked0

-------->調(diào)用到以下方法

private?void?updateProviderListenersLocked(String?provider,?boolean?enabled)?{

????????int?listeners?=?0;

????????LocationProviderInterface?p?=?mProvidersByName.get(provider);

????????if?(p?==?null)?{

????????????return;

????????}

????????ArrayList<Receiver>?deadReceivers?=?null;

????????

????????ArrayList<UpdateRecord>?records?=?mRecordsByProvider.get(provider);

????????if?(records?!=?null)?{

????????????final?int?N?=?records.size();

????????????for?(int?i=0;?i<N;?i++)?{

????????????????UpdateRecord?record?=?records.get(i);

????????????????//?Sends?a?notification?message?to?the?receiver

????????????????if?(!record.mReceiver.callProviderEnabledLocked(provider,?enabled))?{

????????????????????if?(deadReceivers?==?null)?{

????????????????????????deadReceivers?=?new?ArrayList<Receiver>();

????????????????????}

????????????????????deadReceivers.add(record.mReceiver);

????????????????}

????????????????listeners++;

????????????}

????????}

????????if?(deadReceivers?!=?null)?{

????????????for?(int?i=deadReceivers.size()-1;?i>=0;?i--)?{

????????????????removeUpdatesLocked(deadReceivers.get(i));

????????????}

????????}

????????

????????if?(enabled)?{

????????????p.enable();

????????????if?(listeners?>?0)?{

????????????????p.setMinTime(getMinTimeLocked(provider),?mTmpWorkSource);

????????????????p.enableLocationTracking(true);

????????????}

????????}?else?{

????????????p.enableLocationTracking(false);

????????????p.disable();

????????}

????}

enableLocationTracking在gpsLocationProvider.java

??public?void?enableLocationTracking(boolean?enable)?{

????????//?FIXME?-?should?set?a?flag?here?to?avoid?race?conditions?with?single?shot?request

????????synchronized?(mHandler)?{

????????????sendMessage(ENABLE_TRACKING,?(enable???1?:?0),?null);

????????}

????}

??private?void?sendMessage(int?message,?int?arg,?Object?obj)?{

????????//?hold?a?wake?lock?while?messages?are?pending

????????synchronized?(mWakeLock)?{

????????????mPendingMessageBits?|=?(1?<<?message);

????????????mWakeLock.acquire();

????????????mHandler.removeMessages(message);

????????????Message?m?=?Message.obtain(mHandler,?message);

????????????m.arg1?=?arg;

????????????m.obj?=?obj;

????????????mHandler.sendMessage(m);

????????}

????}

??private?final?class?ProviderHandler?extends?Handler?{

????????@Override

????????public?void?handleMessage(Message?msg)?{

????????????int?message?=?msg.what;

????????????switch?(message)?{

????????????????case?ENABLE:

????????????????????if?(msg.arg1?==?1)?{

????????????????????????handleEnable();

????????????????????}?else?{

????????????????????????handleDisable();

????????????????????}

????????????????????break;

????????????????case?ENABLE_TRACKING:

?????????????????????//

?????????????????????handleEnableLocationTracking(msg.arg1?==?1);

????????????????????break;

}

???????}

???}

handleEnableLocationTracking?函數(shù)

?private?void?handleEnableLocationTracking(boolean?enable)?{

????????if?(enable)?{

????????????mTTFF?=?0;

????????????mLastFixTime?=?0;

????????????startNavigating(false);

????????}?else?{

????????????if?(!hasCapability(GPS_CAPABILITY_SCHEDULING))?{

????????????????mAlarmManager.cancel(mWakeupIntent);

????????????????mAlarmManager.cancel(mTimeoutIntent);

????????????}

????????????stopNavigating();

????????}

????}

startNavigating方法???開始導(dǎo)航

?代碼如下:

private?void?startNavigating(boolean?singleShot)?{

????????if?(!mStarted)?{

????????????if?(DEBUG)?Log.d(TAG,?"startNavigating");

????????????mStarted?=?true;

????????????mSingleShot?=?singleShot;

????????????mPositionMode?=?GPS_POSITION_MODE_STANDALONE;

?????????????if?(Settings.Secure.getInt(mContext.getContentResolver(),

????????????????????Settings.Secure.ASSISTED_GPS_ENABLED,?1)?!=?0)?{

????????????????if?(singleShot?&&?hasCapability(GPS_CAPABILITY_MSA))?{

????????????????????mPositionMode?=?GPS_POSITION_MODE_MS_ASSISTED;

????????????????}?else?if?(hasCapability(GPS_CAPABILITY_MSB))?{

????????????????????mPositionMode?=?GPS_POSITION_MODE_MS_BASED;

????????????????}

????????????}

????????????int?interval?=?(hasCapability(GPS_CAPABILITY_SCHEDULING)???mFixInterval?:?1000);

????????????//本地方法

????????????if?(!native_set_position_mode(mPositionMode,?GPS_POSITION_RECURRENCE_PERIODIC,

????????????????????interval,?0,?0))?{

????????????????mStarted?=?false;

????????????????Log.e(TAG,?"set_position_mode?failed?in?startNavigating()");

????????????????return;

????????????}

????????????//本地方法

????????????if?(!native_start())?{

????????????????mStarted?=?false;

????????????????Log.e(TAG,?"native_start?failed?in?startNavigating()");

????????????????return;

????????????}

????????????//?reset?SV?count?to?zero

????????????updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE,?0);

????????????mFixRequestTime?=?System.currentTimeMillis();

????????????if?(!hasCapability(GPS_CAPABILITY_SCHEDULING))?{

????????????????//?set?timer?to?give?up?if?we?do?not?receive?a?fix?within?NO_FIX_TIMEOUT

????????????????//?and?our?fix?interval?is?not?short

????????????????if?(mFixInterval?>=?NO_FIX_TIMEOUT)?{

????????????????????mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,

????????????????????????????SystemClock.elapsedRealtime()?+?NO_FIX_TIMEOUT,?mTimeoutIntent);

????????????????}

????????????}

????????}

????}

在開啟導(dǎo)航的這個方法中?,調(diào)用的兩個重要的本地方法

?這兩個本地方法可以在?com_android_server_location_GpsLocationProvider.cpp這個文件中找到

1?native_set_position_mode

實現(xiàn)代碼如下:

static?jboolean?android_location_GpsLocationProvider_set_position_mode(JNIEnv*?env,?jobject?obj,

????????jint?mode,?jint?recurrence,?jint?min_interval,?jint?preferred_accuracy,?jint?preferred_time)

{

????const?GpsInterface*?interface?=?GetGpsInterface(env,?obj);

????if?(interface)

????????//這里調(diào)用了接口的set_position_mode方法

????????return?(interface->set_position_mode(mode,?recurrence,?min_interval,?preferred_accuracy,

????????????????preferred_time)?==?0);

????else

????????return?false;

}

?該方法調(diào)用了接口的set_position_mode方法,這個方法的實現(xiàn)在(模擬器)的相關(guān)類中可以看到期實現(xiàn)

部分代碼如下;

static?int?qemu_gps_set_position_mode(GpsPositionMode?mode,?int?fix_frequency)

{

????//?FIXME?-?support?fix_frequency

????return?0;

}

2??native_start?通過向底層發(fā)送命令來啟動GPS,??這個底層就是enable/init函數(shù)中啟動的等待數(shù)據(jù)的線程?

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;

}

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));

}

???數(shù)據(jù)監(jiān)聽線程

static?void*???gps_state_thread(?void*??arg?)

{

????GpsState*???state?=?(GpsState*)?arg;

????NmeaReader??reader[1];

????int?????????epoll_fd???=?epoll_create(2);

????int?????????started????=?0;

????int?????????gps_fd?????=?state->fd;

????int?????????control_fd?=?state->control[1];

????nmea_reader_init(?reader?);

????//?register?control?file?descriptors?for?polling

????epoll_register(?epoll_fd,?control_fd?);

????epoll_register(?epoll_fd,?gps_fd?);

????D("gps?thread?running");

????//?now?loop

????for?(;;)?{

????????struct?epoll_event???events[2];

????????int??????????????????ne,?nevents;

????????nevents?=?epoll_wait(?epoll_fd,?events,?2,?-1?);

????????if?(nevents?<?0)?{

????????????if?(errno?!=?EINTR)

????????????????LOGE("epoll_wait()?unexpected?error:?%s",?strerror(errno));

????????????continue;

????????}

????????D("gps?thread?received?%d?events",?nevents);

????????for?(ne?=?0;?ne?<?nevents;?ne++)?{

????????????if?((events[ne].events?&?(EPOLLERR|EPOLLHUP))?!=?0)?{

????????????????LOGE("EPOLLERR?or?EPOLLHUP?after?epoll_wait()?!?");

????????????????goto?Exit;

????????????}

????????????if?((events[ne].events?&?EPOLLIN)?!=?0)?{

????????????????int??fd?=?events[ne].data.fd;

????????????????if?(fd?==?control_fd)

????????????????{

????????????????????char??cmd?=?255;

????????????????????int???ret;

????????????????????D("gps?control?fd?event");

????????????????????do?{

????????????????????????ret?=?read(?fd,?&cmd,?1?);

????????????????????}?while?(ret?<?0?&&?errno?==?EINTR);

????????????????????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)?{

????????????????????????if?(started)?{

????????????????????????????D("gps?thread?stopping");

????????????????????????????started?=?0;

????????????????????????????nmea_reader_set_callback(?reader,?NULL?);

????????????????????????}

????????????????????}

????????????????}

????????????????else?if?(fd?==?gps_fd)

????????????????{

????????????????????char??buff[32];

????????????????????D("gps?fd?event");

????????????????????for?(;;)?{

????????????????????????int??nn,?ret;

????????????????????????ret?=?read(?fd,?buff,?sizeof(buff)?);

????????????????????????if?(ret?<?0)?{

????????????????????????????if?(errno?==?EINTR)

????????????????????????????????continue;

????????????????????????????if?(errno?!=?EWOULDBLOCK)

????????????????????????????????LOGE("error?while?reading?from?gps?daemon?socket:?%s:",?strerror(errno));

????????????????????????????break;

????????????????????????}

????????????????????????D("received?%d?bytes:?%.*s",?ret,?ret,?buff);

????????????????????????for?(nn?=?0;?nn?<?ret;?nn++)

????????????????????????????nmea_reader_addc(?reader,?buff[nn]?);

????????????????????}

????????????????????D("gps?fd?event?end");

????????????????}

????????????????else

????????????????{

????????????????????LOGE("epoll_wait()?returned?unkown?fd?%d??",?fd);

????????????????}

????????????}

????????}

????}

Exit:

????return?NULL;

}

?這個監(jiān)聽線程最主要的一個就是nmea_reader_set_callback(?)函數(shù)

其實就是注冊了一個回調(diào)函數(shù),location_cb?這個回調(diào)函數(shù)就是對底層location數(shù)據(jù)上報的回調(diào)函數(shù)。

到此?

enableLocationTracking函數(shù)完成了,

也就是LocationManageService.java

updateProviderListenersLocked的完成?

也就是updateProvidersLocked的完成,

也就是loadProviders函數(shù)的完成?

也就是?initialize的完成,

也就是run的完成,

也就是systemReady的完成

所以完了

轉(zhuǎn)載于:https://www.cnblogs.com/retacn-yue/archive/2012/09/03/2761388.html

總結(jié)

以上是生活随笔為你收集整理的android系统学习笔记十一的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。