Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲一区视频,亚洲精品成人av在线,韩国美女一级片

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          HarmonyOS獲取設(shè)備地理位置實(shí)戰(zhàn)

          設(shè)備的地理位置指的是設(shè)備所在的地理坐標(biāo)位置,通常以經(jīng)度,緯度和海拔高度的形式表示。地理位置信息能在許多業(yè)務(wù)場景中被應(yīng)用,如導(dǎo)航、地圖服務(wù)、位置服務(wù)、社交媒體等。通過獲取設(shè)備的地理位置,開發(fā)者可以為用戶提供個性化的服務(wù)和信息,同時有助于進(jìn)行地理位置相關(guān)的功能開發(fā)和數(shù)據(jù)分析。

          本期筆者將以一個Demo為例,幫助有需要的開發(fā)者實(shí)現(xiàn)獲取設(shè)備地理位置的功能。

          創(chuàng)建工程

          打開DevEco Studio(開發(fā)工具的版本必須支持API9),創(chuàng)建一個新的project,相關(guān)勾選如下

          獲取目錄服務(wù)器信息失敗_目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器失敗

          目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗

          UI設(shè)計(jì)

          ▍導(dǎo)入圖片資源

          在工程文件目錄中打開目錄:src/main//rawfile, 添加兩張任意的圖片(可以在IDE中將待添加的圖片資源直接粘貼至rawfile目錄下,也可以在文件資源管理器中通過文件路徑打開rawfile目錄并添加圖片資源),分別命名為image1和image2。當(dāng)然,圖片的格式?jīng)]有要求,只要在之后的步驟中能被正確引用即可。

          獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器信息失敗

          ▍添加UI描述

          打開Index.ets,刪除build()中原有的所有代碼塊,增加新的UI聲明和自定義彈窗,并定義一些成員變量,相關(guān)代碼如下

          @Entry
          @Component
          struct?Index?{

          ??title:string?=?'地理信息面板'

          ??@State?Geo_Info:string?=?''

          ?//用于存儲用戶是否授權(quán)的狀態(tài)信息
          ??@State?ifAccessible:boolean?=?false
          ??
          ???//new兩個彈窗控制器
          ??private?dialogController_Accessible?:?CustomDialogController?=?new?CustomDialogController({
          ????builder:dialog({
          ??????message:'已獲取權(quán)限'
          ????})
          ??})

          ??private?dialogController_Inaccessible?:?CustomDialogController?=?new?CustomDialogController({
          ????builder:dialog({
          ??????message:'獲取權(quán)限失敗?|?缺少相關(guān)權(quán)限'
          ????})
          ??})


          ??build()?{
          ????Column({space:10})?{

          ??//新的Text組件
          ??????Text(this.title)
          ????????.fontSize(26)
          ????????.fontWeight(800)
          ????????.margin({
          ??????????top:20,
          ??????????bottom:20
          ????????})
          ????????.fontColor('#e699cc')

          ??????Row(){

          ???//條件渲染image組件
          ????????if(this.ifAccessible?==?true){
          ??????????Image($rawfile('image2.png'))
          ????????????.objectFit(ImageFit.Contain)
          ????????????.layoutWeight(1)
          ????????}else{
          ??????????Image($rawfile('image1.png'))
          ????????????.objectFit(ImageFit.Contain)
          ????????????.layoutWeight(1)
          ????????}

          ????????Column(){
          ????????
          ?????????//兩個新的Button組件
          ??????????Button('獲取相關(guān)權(quán)限')
          ????????????.width('90%')
          ????????????.fontSize(18)
          ????????????.backgroundColor(Color.Pink)

          ??????????Button('獲取地理位置')
          ????????????.width('90%')
          ????????????.fontSize(18)
          ????????????.backgroundColor(Color.Pink)
          ????????????.margin({
          ??????????????top:14
          ????????????})

          ????????}
          ????????.height('100%')
          ????????.layoutWeight(4)
          ????????.backgroundColor(Color.White)

          ??????}
          ??????.height('11%')
          ??????.width('92%')

          ??//新的TextArea組件
          ??????TextArea({
          ????????text:this.Geo_Info
          ??????})
          ????????.width('94%')
          ????????.height('50%')
          ????????.fontSize(18)
          ????????.backgroundColor('#F0F0F0')
          ????????.margin({
          ??????????top:20
          ????????})

          ????}
          ????.width('100%')

          ??}

          }

          //自定義彈窗
          @CustomDialog
          struct?dialog{

          ??controller:CustomDialogController

          ??@State?message:string?=?''

          ??build(){
          ????Column()?{
          ??????Text(this.message)
          ????????.fontSize(20)
          ????????.height(40)
          ????????.fontColor(Color.White)
          ????}
          ????.width('100%')
          ????.backgroundColor(Color.Gray)
          ??}

          }

          完成Demo的UI設(shè)計(jì)后,可以打開預(yù)覽器查看界面效果

          獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決

          集成功能模塊

          目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器失敗_獲取目錄服務(wù)器信息失敗

          ▍向用戶動態(tài)申請授權(quán)的基礎(chǔ)功能模塊

          獲取設(shè)備地理位置信息的前提是用戶同意提供相關(guān)敏感權(quán)限,這意味著我們需要向用戶動態(tài)申請相關(guān)所需權(quán)限。而此次關(guān)于向用戶動態(tài)申請授權(quán)的模塊,筆者將把它們集成在Service目錄下的兩個TS文件里,分別是.ts與.ts。

          關(guān)于如何集成向用戶動態(tài)申請授權(quán)的模塊,以及需要在module.json5中添加哪些權(quán)限,筆者在上期博客中已詳細(xì)闡述。

          上期博客的鏈接:

          獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決

          之后,我們在Index.ets中對其進(jìn)行調(diào)用

          //導(dǎo)入common
          import?common?from?'@ohos.app.ability.common'
          //導(dǎo)入向用戶發(fā)起權(quán)限申請的模塊
          import?Request_Permission_From_Users?from?'ets/Service/Applicant'

          @Entry
          @Component
          struct?Index?{

          ?......
          ??
          ??//獲取上下文對象,?儲存在成員變量context中
          ??private?context?=?getContext(this)?as?common.UIAbilityContext

          ??//編寫異步方法,調(diào)用之前已寫好的模塊文件Applicant
          ??async?apply(){
          ????let?res?=?await?Request_Permission_From_Users(this.context)
          ????this.ifAccessible?=?res
          ????if(res){
          ??????this.dialogController_Accessible.open()
          ????}else{
          ??????this.dialogController_Inaccessible.open()
          ????}
          ??}

          ??build()?{
          ????Column({space:10})?{

          ?????......

          ????????Column(){
          ??????????Button('獲取相關(guān)權(quán)限')
          ????????????.width('90%')
          ????????????.fontSize(18)
          ????????????.backgroundColor(Color.Pink)
          ????????????//調(diào)用異步方法apply
          ????????????.onClick(()=>{
          ??????????????this.apply()
          ????????????})

          ?????????......

          ????????}
          ????????.height('100%')
          ????????.layoutWeight(4)
          ????????.backgroundColor(Color.White)

          ??????}
          ??????.height('11%')
          ??????.width('92%')

          ?......

          ??}

          }

          ......

          ▍獲取設(shè)備地理信息的功能模塊

          此功能模塊的目的是輸出設(shè)備所在地的經(jīng)度,緯度,海拔高度和城市名,以及設(shè)備的速度(應(yīng)該是瞬時的)。這需要先獲取設(shè)備所在的地理位置坐標(biāo),再將地理位置坐標(biāo)轉(zhuǎn)化為具體的地理描述(即國家,城市等)。

          在Service目錄下新建一個文件(右鍵Service目錄,選擇新建,再選擇),將其命名為Geo

          獲取目錄服務(wù)器信息失敗_目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器失敗

          在編輯器中打開目錄Geo.ts,加入以下代碼以集成獲取設(shè)備地理信息的功能,各代碼塊的具體功能已寫注解

          //導(dǎo)入位置服務(wù)模塊
          import?geoLocationManager?from?'@ohos.geoLocationManager';

          //導(dǎo)入自定義的權(quán)限檢查模塊
          import?Check_Access?from?'ets/Service/Detector'

          //定義結(jié)點(diǎn)的標(biāo)簽
          const?TAG_NODE0?=?'------[Geo-Node0]?'
          const?TAG_NODE1?=?'------[Geo-Node1]?'
          const?TAG_NODE2?=?'------[Geo-Node2]?'

          /*
          ?*結(jié)點(diǎn)函數(shù)1:獲取用戶設(shè)備當(dāng)前所處位置的經(jīng)度和緯度數(shù)據(jù)
          ?*/
          async?function?Node1_Get_Geographical_Position(){

          ??//預(yù)定義返回值
          ??let?output?=?{
          ????'position_x':null,
          ????'position_y':null,
          ????'position_z':null,
          ????'cityName':'?未知',
          ????'speed':null,
          ????//結(jié)點(diǎn)函數(shù)的執(zhí)行狀態(tài),默認(rèn)為失敗
          ????'isFinished':false,
          ????'error':'無'
          ??}

          ??//檢查定位功能是否可用
          ??if(!geoLocationManager.isLocationEnabled()){
          ????console.info(TAG_NODE1+'Location?module?loads?fail')
          ????output.error?=?'定位功能不可用,?請檢查設(shè)備或服務(wù)器'
          ????return
          ??}

          ??//定義需要輸入的請求參數(shù)
          ??let?requestInfo?=?{'priority':?0x203,?'scenario':?0x300,'maxAccuracy':?0}

          ??//等待模塊完成獲取地理位置的異步操作
          ??await?geoLocationManager.getCurrentLocation(requestInfo).then((result)?=>?{
          ????console.info(TAG_NODE1+'Succeed!?Current?location?=>?latitude:?'?+?result.latitude+';?longitude:?'+result.longitude+';');

          ????//記錄獲取的地理信息
          ????output.position_x?=?result.latitude
          ????output.position_y?=?result.longitude
          ????output.position_z?=?result.altitude
          ????output.speed?=?result.speed

          ????//結(jié)點(diǎn)函數(shù)的執(zhí)行狀態(tài)修改為成功
          ????output.isFinished?=?true

          ??}).catch((error)?=>?{
          ????console.error(TAG_NODE1+'Get?current?location?failed,?error:?'?+?JSON.stringify(error));
          ????output.error?=?'地理位置獲取失敗'
          ??});

          ??return?output

          }

          /*
          ?*結(jié)點(diǎn)函數(shù)2:獲取用戶設(shè)備當(dāng)前所處的城市名稱(中文)
          ?*/
          async?function?Node2_Get_City_Name(input){

          ??//預(yù)定義返回值
          ??let?output?=?{
          ????'cityName':?'?未知',
          ????'position_x':input.position_x,
          ????'position_y':input.position_y,
          ????'position_z':input.position_z,
          ????'speed':input.speed,
          ????//結(jié)點(diǎn)函數(shù)的執(zhí)行狀態(tài),默認(rèn)為失敗
          ????'isFinished':?false,
          ????'error':'無'
          ??}


          ??//判斷逆地理編碼轉(zhuǎn)換服務(wù)是否可用
          ??if(!geoLocationManager.isGeocoderAvailable()){
          ????console.error(TAG_NODE2+'Geocoder?module?loads?fail')
          ????output.error?=?'地理編碼轉(zhuǎn)化功能不可用,?請檢查設(shè)備或服務(wù)器'
          ????return?output
          ??}

          ??//定義需要輸入的請求參數(shù),其中l(wèi)ocale鍵對應(yīng)的值’zh‘表示服務(wù)器將返回中文形式的信息
          ??let?reverseGeocodeRequest?=?{'locale':'zh',"latitude":?input.position_x,?"longitude":?input.position_y,?"maxItems":?1};

          ??//等待模塊完成逆地理編碼轉(zhuǎn)換的異步操作
          ??await?geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest).then((result)?=>?{
          ????console.info(TAG_NODE2+'City?name?:?'?+?result[0].locality);

          ????//記錄獲取的城市名
          ????let?cityName?=?result[0].locality
          ????if(cityName.charAt(cityName.length-1)?==?'市')?cityName.replace('市','')
          ????output.cityName?=?cityName

          ????//結(jié)點(diǎn)函數(shù)的執(zhí)行狀態(tài)修改為成功
          ????output.isFinished?=?true

          ??}).catch((error)?=>?{
          ????console.error(TAG_NODE2+'Get?addresses?from?location:?error:?'?+?JSON.stringify(error));
          ????output.error?=?'逆地理編碼轉(zhuǎn)換失敗'
          ??});

          ??return?output

          }

          //導(dǎo)出可供調(diào)用的接口
          export?async?function?Get_Geo_Data(){

          ??//模塊結(jié)點(diǎn)0
          ??if(!Check_Access()){
          ????console.error(TAG_NODE0+'Insufficient?required?permissions')
          ????return?{
          ??????'position_x':null,
          ??????'position_y':null,
          ??????'position_z':null,
          ??????'cityName':'?未知',
          ??????'speed':null,
          ??????'isFinished':false,
          ??????'error':'設(shè)備未獲取相關(guān)權(quán)限'
          ????}
          ??}

          ??//模塊結(jié)點(diǎn)1
          ??let?output?=?await?Node1_Get_Geographical_Position()
          ??if?(!output.isFinished)?return?output


          ??//模塊結(jié)點(diǎn)2
          ??return?await?Node2_Get_City_Name(output)

          }

          通常,集成這類模塊需要優(yōu)先考慮的問題是回調(diào)地獄。回調(diào)地獄是指,在使用回調(diào)函數(shù)處理異步操作時,由于多個異步操作的嵌套和依賴關(guān)系,導(dǎo)致代碼結(jié)構(gòu)變得混亂和難以維護(hù)的情況。在Java中,我們可以通過創(chuàng)建線程和設(shè)置各線程優(yōu)先級的方式,將原本的異步過程調(diào)整為線性的同步過程。而在中,除了傳統(tǒng)的設(shè)置線程的方法之外,我們還可以通過Promise或async/await來避免回調(diào)地獄,使代碼更加清晰和易于理解。

          在上述代碼中,筆者聲明了兩個異步函數(shù),分別是與,不妨稱它們?yōu)榻Y(jié)點(diǎn)函數(shù)。其中,第一個結(jié)點(diǎn)函數(shù)用于獲取地理位置信息(包含坐標(biāo)信息),第二個結(jié)點(diǎn)函數(shù)用于將所獲取的地理坐標(biāo)信息轉(zhuǎn)換為地理描述,并且,它們在時間維度上有一個執(zhí)行次序,即先執(zhí)行第一個結(jié)點(diǎn)函數(shù),當(dāng)其執(zhí)行完成并返回相關(guān)結(jié)果后,再執(zhí)行第二個結(jié)點(diǎn)函數(shù)。顯然,第二個結(jié)點(diǎn)函數(shù)的輸入即為第一個結(jié)點(diǎn)函數(shù)的輸出,而這也是先執(zhí)行第一個結(jié)點(diǎn)函數(shù)的原因。

          要讓兩個異步的結(jié)點(diǎn)函數(shù)按次序線性執(zhí)行,我們可以定義一個新的異步函數(shù),在其函數(shù)體內(nèi)添加合適的操作語句以調(diào)用這兩個結(jié)點(diǎn)函數(shù)。在上述代碼中,首先需判定相關(guān)的位置權(quán)限是否已被提供,接著調(diào)用第一個結(jié)點(diǎn)函數(shù),并在調(diào)用時增加了關(guān)鍵字await。這意味著,在返回結(jié)果之前,函數(shù)體中剩下的未執(zhí)行的操作語句是不會被執(zhí)行的。當(dāng)?shù)谝粋€結(jié)點(diǎn)函數(shù)執(zhí)行結(jié)束后,再調(diào)用第二個結(jié)點(diǎn)函數(shù),同樣地,要添加關(guān)鍵字await,否則在第二個結(jié)點(diǎn)函數(shù)成功響應(yīng)前,就已經(jīng)跑完了,這樣什么都不會被輸出。

          獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器信息失敗

          獲取目錄服務(wù)器信息失敗_目錄器獲取失敗服務(wù)怎么解決_獲取目錄服務(wù)器失敗

          接下來,筆者將討論兩個結(jié)點(diǎn)函數(shù)各自的代碼邏輯。

          對于第一個結(jié)點(diǎn)函數(shù),首先它預(yù)定義了需要輸出的變量output(對應(yīng)一個Object型數(shù)據(jù)),其包含7個不同的鍵值對。接著,檢查定位功能是否可用,若可用,則通過導(dǎo)入的系統(tǒng)模塊的方法異步獲取設(shè)備的地理位置信息,并在then()中提取地理位置信息中所攜帶的經(jīng)度,緯度,海拔高度,和實(shí)時速度。最后,輸出變量output。

          至于第二個結(jié)點(diǎn)函數(shù),首先它預(yù)定義了需要輸出的變量output,并且將傳入的參數(shù)input(即的輸出)的一些鍵對應(yīng)的值拷貝到output中。之后, 判斷逆地理編碼轉(zhuǎn)換功能是否可用,若可用,則通過的tion方法異步獲取設(shè)備所在位置的地理描述信息(即國家,城市等),并在then()中提取地理描述信息中的城市名。最后,輸出變量output。

          完成功能集成工作后,我們在Index.ets中調(diào)用此模塊

          ......
          //導(dǎo)入獲取設(shè)備地理信息的模塊
          import?{?Get_Geo_Data?}?from?'ets/Service/Geo'

          @Entry
          @Component
          struct?Index?{

          ?......

          ??//編寫異步方法,調(diào)用之前已寫好的模塊文件Geo
          ??async?update_geo_data(){

          ????//判斷是否獲取所需權(quán)限
          ????if(!this.ifAccessible){
          ??????this.dialogController_Inaccessible.open()
          ??????return
          ????}

          ????let?info?=?await?Get_Geo_Data()

          ????this.Geo_Info?=?'???????---地理信息---\n'?+?'\n當(dāng)前所在城市:'?+?info.cityName?+?'\n緯度:?'?+?info.position_x?+?'\n經(jīng)度:?'?+?info.position_y?+?'\n海拔:?'?+?info.position_z?+?'\n速度:?'?+?info.speed?+?'?m/s\n'
          ????if(!info.isFinished)?this.Geo_Info?+=?'\n錯誤信息:?'?+?info.error

          ??}

          ??build()?{
          ????Column({space:10})?{
          ????.....
          ????
          ????????Column(){
          ????????
          ?????????......

          ??????????Button('獲取地理位置')
          ????????????.width('90%')
          ????????????.fontSize(18)
          ????????????.backgroundColor(Color.Pink)
          ????????????.margin({
          ??????????????top:14
          ????????????})
          ????????????//調(diào)用異步方法update_geo_data
          ????????????.onClick(()=>{
          ??????????????this.update_geo_data()
          ????????????})

          ????????}
          ????????.height('100%')
          ????????.layoutWeight(4)
          ????????.backgroundColor(Color.White)

          ??????}
          ??????.height('11%')
          ??????.width('92%')

          ???......

          ??}

          }

          ......

          真機(jī)&模擬機(jī)調(diào)試

          Demo完成之后,我們需要用模擬機(jī)或真機(jī)來運(yùn)行以查看效果。

          獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決

          可惜的是,模擬機(jī)里的逆地理編碼轉(zhuǎn)換服務(wù)是不可用的,所以其無法得到設(shè)備所在地的地理描述,因而無法輸出城市名。

          相關(guān)日志如下,可見,逆地理編碼轉(zhuǎn)換服務(wù)被檢查為不可用。

          獲取目錄服務(wù)器失敗_獲取目錄服務(wù)器信息失敗_目錄器獲取失敗服務(wù)怎么解決

          如果在真機(jī)上運(yùn)行,逆地理編碼轉(zhuǎn)換服務(wù)是沒什么問題的。下圖是筆者借用了的真機(jī)后得到的程序運(yùn)行截圖

          獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決

          結(jié)語

          文章所述僅代表個人理解,如有不足懇請讀者不吝賜教。

          獲取目錄服務(wù)器信息失敗_獲取目錄服務(wù)器失敗_目錄器獲取失敗服務(wù)怎么解決


          主站蜘蛛池模板: 国产一区二区三区免费视频| 亚洲AV无码一区二区三区牲色| 亚洲AV成人一区二区三区观看 | 中文字幕一区二区区免| 无码人妻久久一区二区三区蜜桃 | 精品无码人妻一区二区三区18| 久久国产精品一区二区| 国产精品 一区 在线| 免费一区二区三区| 亚洲一区二区三区久久久久| 无码精品不卡一区二区三区| 亚洲一区二区精品视频| 亚洲AV色香蕉一区二区| 亚洲精品日韩一区二区小说| 精品一区二区三区在线视频观看| 狠狠色成人一区二区三区| ...91久久精品一区二区三区| 无码视频免费一区二三区| 精品成人一区二区三区四区 | 国产大秀视频在线一区二区| 国产在线一区二区视频| 久久精品一区二区三区资源网 | 精品理论片一区二区三区| 日韩电影一区二区三区| 无码一区二区三区爆白浆| 久久国产午夜精品一区二区三区| 蜜臀AV一区二区| 波多野结衣一区二区三区aV高清| 日韩国产免费一区二区三区 | 亚洲一区二区影视| 无码日韩精品一区二区人妻| 美女毛片一区二区三区四区| 日亚毛片免费乱码不卡一区| 亚洲av无码片区一区二区三区| 日韩少妇无码一区二区三区| 人妻无码第一区二区三区| 国产成人高清精品一区二区三区| 日本一区二区三区不卡视频| 国产suv精品一区二区33| 美女视频一区二区| 无码少妇丰满熟妇一区二区|