鴻蒙安全控制元件之位置控制元件簡介

龙儿筝發表於2024-11-28

位置控制元件使用直觀且易懂的通用標識,讓使用者明確地知道這是一個獲取位置資訊的按鈕。這滿足了授權場景需要匹配使用者真實意圖的需求。只有當使用者主觀願意,並且明確瞭解使用場景後點選位置控制元件,應用才會獲得臨時的授權,獲取位置資訊並完成相應的服務功能。

一旦應用整合了位置控制元件,使用者點選該控制元件後,無論應用是否已經申請過或被授予精準定位許可權,都會在本次前臺期間獲得精準定位的授權,可以呼叫位置服務獲取精準定位。

對於不是強位置關聯應用(例如導航、運動健康等)的應用,只在部分前臺場景需要使用位置資訊(例如定位城市、打卡、分享位置等)。如果需要長時間使用或是在後臺使用位置資訊,建議申請位置許可權。

位置控制元件效果如圖所示。
img1

約束與限制

  • 當使用者首次點選應用中的位置控制元件,系統將彈窗請求使用者授權。如果使用者點選“取消”,彈窗消失,應用無授權,使用者再次點選位置控制元件時,將會重新彈窗;如果使用者點選“允許”,彈窗消失,應用將被授予臨時位置許可權,此後點選該應用的位置控制元件將不會彈窗。
  • 精準定位的臨時授權會持續到滅屏、應用切後臺、應用退出等任一情況發生,然後恢復到臨時授權之前的授權狀態(授予/未授予/未申請)
  • 應用在授權期間沒有呼叫次數限制。
  • 為了保障使用者的隱私不被惡意應用獲取,應用需確保安全控制元件是可見的且使用者能夠識別的。開發者需要合理的配置控制元件的尺寸、顏色等屬性,避免視覺混淆的情況,如果發生因控制元件的樣式不合法導致授權失敗的情況,請檢查裝置錯誤日誌。

開發步驟

以在聊天介面傳送實時定位資訊為例。在當前場景下,應用僅需要在前臺期間,短暫地訪問當前位置,不需要長時間使用。此時,可以直接使用安全控制元件中的位置控制元件,免去許可權申請和許可權請求等環節,獲得臨時授權,滿足許可權最小化,提升使用者的隱私體驗。

參考以下步驟,實現效果:點選控制元件“當前位置”獲取臨時精準定位授權,獲取授權後,彈窗提示具體位置資訊,效果圖請見上文。

  1. 引入位置服務依賴。
import { geoLocationManager } from '@kit.LocationKit';
  1. 新增位置控制元件和獲取當前位置資訊。
    安全控制元件是由圖示、文字、背景組成的類似Button的按鈕,其中圖示、文字兩者至少有其一,背景是必選的。圖示和文字不支援自定義,僅支援在已有的選項中選擇。應用申明安全控制元件的介面時,分為傳參和不傳參兩種,不傳參預設建立圖示+文字+背景的按鈕,傳參根據傳入的引數建立,不包含沒有配置的元素。

    當前示例使用預設引數,具體請參見LocationButton控制元件。此外,所有安全控制元件都繼承安全控制元件通用屬性,可用於定製樣式。

    在LocationButton的onClick()回撥中透過呼叫geoLocationManager模組提供的方法獲取當前位置資訊。

import { geoLocationManager } from '@kit.LocationKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

// 獲取當前位置資訊
function getCurrentLocationInfo() {
  const requestInfo: geoLocationManager.LocationRequest = {
    'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
    'scenario': geoLocationManager.LocationRequestScenario.UNSET,
    'timeInterval': 1,
    'distanceInterval': 0,
    'maxAccuracy': 0
  };
  try {
    geoLocationManager.getCurrentLocation(requestInfo)
      .then((location: geoLocationManager.Location) => {
        promptAction.showToast({ message: JSON.stringify(location) });
      })
      .catch((err: BusinessError) => {
        console.error(`Failed to get current location. Code is ${err.code}, message is ${err.message}`);
      });
  } catch (err) {
    console.error(`Failed to get current location. Code is ${err.code}, message is ${err.message}`);
  }
}

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column({ space: 10 }) {
        LocationButton({
          icon: LocationIconStyle.LINES,
          text: LocationDescription.CURRENT_LOCATION,
          buttonType: ButtonType.Normal
        })
          .padding({top: 12, bottom: 12, left: 24, right: 24})
          .onClick((event: ClickEvent, result: LocationButtonOnClickResult) => {
            if (result === LocationButtonOnClickResult.SUCCESS) {
              // 免去許可權申請和許可權請求等環節,獲得臨時授權,獲取位置資訊授權
              getCurrentLocationInfo();
            } else {
              promptAction.showToast({ message: '獲取位置資訊失敗!' })
            }
          })
      }
      .width('100%')
    }
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
}

相關文章