uniapp開發鴻蒙:原生能力調用實戰
引入:跨平台開發的核心能力
在之前的文章中,我們已經掌握了uniapp在鴻蒙平台下的基礎開發技能。今天,我們將深入探討uniapp調用鴻蒙原生能力的完整方案,這是實現複雜業務功能、提升應用體驗的關鍵環節。
uniapp通過uni-app框架提供了豐富的API,同時支持通過原生插件擴展能力。在鴻蒙平台下,我們還可以直接調用鴻蒙的ArkTS原生能力,實現更底層的功能調用。本文將系統講解這三種方式的實現方案。
一、uni-app內置API調用
1.1 設備信息獲取
獲取設備信息:
// 獲取設備信息
uni.getSystemInfo({
success: (res) => {
console.log('設備品牌:', res.brand)
console.log('設備型號:', res.model)
console.log('系統版本:', res.system)
console.log('屏幕尺寸:', res.screenWidth, res.screenHeight)
console.log('DPI:', res.pixelRatio)
}
})
// 獲取設備基礎信息
const systemInfo = uni.getSystemInfoSync()
console.log('設備信息:', systemInfo)
獲取網絡狀態:
// 監聽網絡狀態變化
uni.onNetworkStatusChange((res) => {
console.log('網絡類型:', res.networkType)
console.log('是否聯網:', res.isConnected)
})
// 獲取當前網絡狀態
uni.getNetworkType({
success: (res) => {
console.log('當前網絡:', res.networkType)
}
})
1.2 地理位置服務
獲取當前位置:
// 獲取當前位置
uni.getLocation({
type: 'gcj02', // 座標系類型
success: (res) => {
console.log('經度:', res.longitude)
console.log('緯度:', res.latitude)
console.log('速度:', res.speed)
console.log('精度:', res.accuracy)
},
fail: (err) => {
console.error('獲取位置失敗:', err)
}
})
// 持續定位
const locationId = uni.startLocationUpdate({
type: 'gcj02',
success: () => {
console.log('開始持續定位')
}
})
// 停止定位
uni.stopLocationUpdate({
success: () => {
console.log('停止持續定位')
}
})
1.3 設備傳感器
加速度計:
// 監聽加速度計
uni.onAccelerometerChange((res) => {
console.log('X軸加速度:', res.x)
console.log('Y軸加速度:', res.y)
console.log('Z軸加速度:', res.z)
})
// 開始監聽
uni.startAccelerometer({
interval: 'normal'
})
// 停止監聽
uni.stopAccelerometer()
陀螺儀:
// 監聽陀螺儀
uni.onGyroscopeChange((res) => {
console.log('X軸角速度:', res.x)
console.log('Y軸角速度:', res.y)
console.log('Z軸角速度:', res.z)
})
// 開始監聽
uni.startGyroscope({
interval: 'normal'
})
// 停止監聽
uni.stopGyroscope()
1.4 文件系統操作
文件讀寫:
// 讀取文件
uni.getFileSystemManager().readFile({
filePath: 'file:///path/to/file.txt',
encoding: 'utf8',
success: (res) => {
console.log('文件內容:', res.data)
}
})
// 寫入文件
uni.getFileSystemManager().writeFile({
filePath: 'file:///path/to/file.txt',
data: 'Hello World',
encoding: 'utf8',
success: () => {
console.log('寫入成功')
}
})
// 獲取文件信息
uni.getFileSystemManager().getFileInfo({
filePath: 'file:///path/to/file.txt',
success: (res) => {
console.log('文件大小:', res.size)
}
})
二、鴻蒙原生API調用
2.1 權限申請
權限列表:
// 檢查權限
uni.authorize({
scope: 'scope.userLocation',
success: () => {
console.log('位置權限已授權')
},
fail: () => {
console.log('位置權限未授權')
}
})
// 常用權限scope
const PERMISSIONS = {
LOCATION: 'scope.userLocation', // 位置信息
CAMERA: 'scope.camera', // 相機
RECORD: 'scope.record', // 錄音
USER_INFO: 'scope.userInfo', // 用户信息
ADDRESS: 'scope.address', // 通訊地址
INVOICE: 'scope.invoice', // 發票抬頭
WERUN: 'scope.werun', // 微信運動
WRITE_PHOTOS: 'scope.writePhotosAlbum' // 保存到相冊
}
2.2 系統能力調用
撥打電話:
uni.makePhoneCall({
phoneNumber: '10086',
success: () => {
console.log('撥號成功')
}
})
發送短信:
uni.sendSms({
phoneNumber: '10086',
content: 'Hello',
success: () => {
console.log('發送成功')
}
})
打開系統設置:
uni.openSetting({
success: (res) => {
console.log('設置頁面打開成功')
}
})
獲取剪貼板內容:
uni.getClipboardData({
success: (res) => {
console.log('剪貼板內容:', res.data)
}
})
// 設置剪貼板內容
uni.setClipboardData({
data: 'Hello World',
success: () => {
console.log('複製成功')
}
})
2.3 設備振動
短振動:
uni.vibrateShort({
success: () => {
console.log('振動成功')
}
})
// 長振動
uni.vibrateLong({
success: () => {
console.log('長振動成功')
}
})
2.4 屏幕亮度
獲取屏幕亮度:
uni.getScreenBrightness({
success: (res) => {
console.log('屏幕亮度:', res.value)
}
})
// 設置屏幕亮度
uni.setScreenBrightness({
value: 0.8,
success: () => {
console.log('設置亮度成功')
}
})
// 保持屏幕常亮
uni.setKeepScreenOn({
keepScreenOn: true,
success: () => {
console.log('屏幕常亮開啓')
}
})
三、原生插件開發
3.1 插件項目結構
創建插件項目:
# 創建原生插件項目
npx @dcloudio/uni-plugin create my-plugin
項目結構:
my-plugin/
├── android/ # Android原生代碼
├── ios/ # iOS原生代碼
├── harmony/ # 鴻蒙原生代碼
├── package.json
├── plugin.json # 插件配置文件
└── src/
└── index.js # JS接口文件
3.2 鴻蒙原生代碼實現
harmony/ets/MyPlugin.ets:
import plugin from '@ohos.hap.plugin'
@Entry
@Component
struct MyPlugin {
@State message: string = 'Hello World'
build() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
}
}
// 原生方法實現
export class MyPluginImpl {
static getDeviceInfo(): string {
const deviceInfo = deviceInfo.getDeviceInfoSync()
return JSON.stringify({
brand: deviceInfo.brand,
model: deviceInfo.model,
system: deviceInfo.system
})
}
static showToast(message: string): void {
prompt.showToast({
message: message,
duration: 2000
})
}
}
// 註冊插件
plugin.registerPlugin('my-plugin', MyPluginImpl)
3.3 JS接口封裝
src/index.js:
// JS接口文件
export default {
// 獲取設備信息
getDeviceInfo() {
return new Promise((resolve, reject) => {
// 調用鴻蒙原生方法
const result = uni.requireNativePlugin('my-plugin').getDeviceInfo()
if (result) {
resolve(JSON.parse(result))
} else {
reject(new Error('獲取設備信息失敗'))
}
})
},
// 顯示原生Toast
showToast(message) {
uni.requireNativePlugin('my-plugin').showToast(message)
}
}
3.4 插件配置
plugin.json:
{
"name": "my-plugin",
"id": "my-plugin",
"version": "1.0.0",
"description": "自定義原生插件",
"main": "src/index.js",
"platforms": ["android", "ios", "harmony"],
"dependencies": {}
}
3.5 在uniapp中使用插件
安裝插件:
# 在uniapp項目中安裝插件
npm install ./my-plugin
在頁面中使用:
import myPlugin from 'my-plugin'
// 獲取設備信息
myPlugin.getDeviceInfo().then(info => {
console.log('設備信息:', info)
})
// 顯示Toast
myPlugin.showToast('Hello from native plugin')
四、ArkTS原生能力調用
4.1 條件編譯調用原生API
在uniapp中調用ArkTS:
// #ifdef HARMONYOS
// 鴻蒙平台下調用ArkTS原生API
const { getSystemInfo } = require('@system.app')
getSystemInfo({
success: (res) => {
console.log('系統信息:', res)
}
})
// #endif
// #ifndef HARMONYOS
// 其他平台使用uni-app API
uni.getSystemInfo({
success: (res) => {
console.log('系統信息:', res)
}
})
// #endif
4.2 常用ArkTS API
應用信息:
// #ifdef HARMONYOS
const app = require('@system.app')
// 獲取應用信息
app.getInfo({
success: (res) => {
console.log('應用名稱:', res.name)
console.log('版本號:', res.versionName)
}
})
// 退出應用
app.terminate()
// #endif
路由跳轉:
// #ifdef HARMONYOS
const router = require('@system.router')
// 跳轉到頁面
router.push({
uri: 'pages/index/index'
})
// 返回上一頁
router.back()
// 替換當前頁
router.replace({
uri: 'pages/detail/detail'
})
// #endif
存儲系統:
// #ifdef HARMONYOS
const storage = require('@system.storage')
// 存儲數據
storage.set({
key: 'token',
value: 'your_token',
success: () => {
console.log('存儲成功')
}
})
// 讀取數據
storage.get({
key: 'token',
success: (res) => {
console.log('讀取成功:', res.value)
}
})
// 刪除數據
storage.delete({
key: 'token',
success: () => {
console.log('刪除成功')
}
})
// #endif
五、跨平台適配方案
5.1 平台判斷
判斷當前平台:
// 判斷平台
const platform = uni.getSystemInfoSync().platform
// 條件編譯
// #ifdef HARMONYOS
console.log('當前平台: 鴻蒙')
// #endif
// #ifdef APP-PLUS
console.log('當前平台: App')
// #endif
// #ifdef H5
console.log('當前平台: H5')
// #endif
// #ifdef MP-WEIXIN
console.log('當前平台: 微信小程序')
// #endif
5.2 統一API封裝
封裝跨平台API:
// utils/native.js
export const native = {
// 獲取設備信息
getDeviceInfo() {
// #ifdef HARMONYOS
return new Promise((resolve) => {
const { getSystemInfo } = require('@system.app')
getSystemInfo({
success: resolve
})
})
// #endif
// #ifndef HARMONYOS
return new Promise((resolve) => {
uni.getSystemInfo({
success: resolve
})
})
// #endif
},
// 顯示Toast
showToast(message) {
// #ifdef HARMONYOS
const { showToast } = require('@system.prompt')
showToast({
message: message,
duration: 2000
})
// #endif
// #ifndef HARMONYOS
uni.showToast({
title: message,
icon: 'none'
})
// #endif
},
// 撥打電話
makePhoneCall(phoneNumber) {
// #ifdef HARMONYOS
const { makeCall } = require('@system.telephone')
makeCall({
number: phoneNumber
})
// #endif
// #ifndef HARMONYOS
uni.makePhoneCall({
phoneNumber: phoneNumber
})
// #endif
}
}
5.3 在頁面中使用
import { native } from '@/utils/native'
// 獲取設備信息
native.getDeviceInfo().then(info => {
console.log('設備信息:', info)
})
// 顯示Toast
native.showToast('Hello')
// 撥打電話
native.makePhoneCall('10086')
六、實戰案例:拍照上傳功能
6.1 拍照功能實現
import { native } from '@/utils/native'
export const takePhoto = () => {
return new Promise((resolve, reject) => {
// #ifdef HARMONYOS
const { takePhoto } = require('@system.camera')
takePhoto({
success: (res) => {
resolve(res.uri)
},
fail: reject
})
// #endif
// #ifndef HARMONYOS
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
resolve(res.tempFilePaths[0])
},
fail: reject
})
// #endif
})
}
6.2 圖片上傳功能
import { uploadFile } from '@/utils/upload'
export const uploadPhoto = async () => {
try {
// 拍照
const imagePath = await takePhoto()
// 上傳到服務器
const result = await uploadFile(imagePath)
// 顯示上傳成功
native.showToast('上傳成功')
return result
} catch (error) {
console.error('拍照上傳失敗:', error)
native.showToast('上傳失敗')
throw error
}
}
6.3 在頁面中使用
<template>
<view>
<button @click="handleTakePhoto">拍照上傳</button>
<image v-if="imageUrl" :src="imageUrl" mode="aspectFill" />
</view>
</template>
<script setup>
import { ref } from 'vue'
import { uploadPhoto } from '@/utils/photo'
const imageUrl = ref('')
const handleTakePhoto = async () => {
try {
const result = await uploadPhoto()
imageUrl.value = result.url
} catch (error) {
console.error('拍照上傳失敗:', error)
}
}
</script>
七、鴻蒙平台特有配置
7.1 權限配置
manifest.json:
{
"app-plus": {
"harmony": {
"requestPermissions": [
{
"name": "ohos.permission.CAMERA"
},
{
"name": "ohos.permission.READ_MEDIA"
},
{
"name": "ohos.permission.WRITE_MEDIA"
},
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.LOCATION"
}
]
}
}
}
7.2 應用配置
{
"app-plus": {
"harmony": {
"appId": "com.example.myapp",
"appName": "我的應用",
"versionName": "1.0.0",
"versionCode": 100,
"minPlatformVersion": 9,
"compileSdkVersion": 9,
"targetSdkVersion": 9
}
}
}
八、常見問題與解決方案
8.1 權限申請失敗
問題:在鴻蒙平台下,部分權限需要動態申請。
解決方案:
// 動態申請權限
uni.authorize({
scope: 'scope.camera',
success: () => {
console.log('相機權限已授權')
},
fail: () => {
uni.showModal({
title: '提示',
content: '需要相機權限才能使用拍照功能',
success: (res) => {
if (res.confirm) {
uni.openSetting()
}
}
})
}
})
8.2 原生插件調用失敗
問題:原生插件未正確註冊或配置。
解決方案:
- 檢查
plugin.json配置是否正確 - 確認原生代碼已正確編譯
- 檢查權限配置是否完整
8.3 跨平台兼容性問題
問題:不同平台API行為不一致。
解決方案:
- 使用條件編譯區分不同平台
- 封裝統一的API接口
- 在開發階段充分測試各平台
總結
通過本篇文章的學習,我們掌握了uniapp在鴻蒙平台下調用原生能力的完整方案:
- uni-app內置API:設備信息、地理位置、傳感器等基礎能力
- 鴻蒙原生API:權限申請、系統能力、設備振動等系統級功能
- 原生插件開發:自定義插件的開發、配置和使用
- ArkTS原生調用:條件編譯調用鴻蒙原生API
- 跨平台適配:統一API封裝和平台判斷
- 實戰案例:拍照上傳功能的完整實現
關鍵要點:
- 優先使用uni-app內置API,保證跨平台兼容性
- 原生插件適用於複雜業務場景和性能優化
- 條件編譯是實現跨平台適配的有效手段
- 權限申請是鴻蒙平台下的必要步驟
下一篇文章,我們將深入講解性能優化與調試,包括啓動速度優化、渲染性能優化、內存管理等核心內容,幫助您構建更高效的應用。