HarmonyOS鸿蒙Next中如何在开发中由应用APP跳转到另外一个APP上面
HarmonyOS鸿蒙Next中如何在开发中由应用APP跳转到另外一个APP上面 鸿蒙开发中怎么样可以由应用APP跳转到另外的一个APP上面,应用组件之间的跳转方式。
import { BusinessError } from '@kit.BasicServicesKit';
import { bundleManager, common, Want } from '@kit.AbilityKit';
class SchemeModel {
appName: string = '';
scheme: string = '';
domain?: string = '';
path?: string = '';
bundleName?: string = '';
abilityName?: string = '';
isWebUrl: boolean = false;
constructor(
appName: string,
scheme: string,
domain: string = 'home',
path: string = '',
bundleName?: string,
abilityName?: string,
isWebUrl: boolean = false
) {
this.appName = appName;
this.scheme = scheme;
this.domain = domain;
this.path = path;
this.bundleName = bundleName;
this.abilityName = abilityName;
this.isWebUrl = isWebUrl;
}
getDeepLinking(): string {
if (this.isWebUrl) {
return this.scheme;
}
return this.path ? `${this.scheme}://${this.domain}/${this.path}` : `${this.scheme}://${this.domain}`;
}
}
interface AppStatus {
name: string;
status: '可用' | '不可用' | '检查失败';
}
// 跳转应用市场详情页
function startAppGalleryDetailAbility(context: common.UIAbilityContext, bundleName: string): void {
const want: Want = {
action: 'ohos.want.action.appdetail',
uri: `store://appgallery.huawei.com/app/detail?id=${bundleName}`,
};
context.startAbility(want)
.then(() => console.info('AppLauncher', `成功跳转应用市场详情页:${bundleName}`))
.catch((error: BusinessError) =>
console.error('AppLauncher', `跳转应用市场详情页失败:code=${error.code}, message=${error.message}`)
);
}
@Entry
@Component
struct AppLauncherPage {
@State currentAppIndex: number = 0;
@State appStatusList: AppStatus[] = [];
@State showStatus: boolean = false;
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
private promptAction = this.getUIContext().getPromptAction();
private schemeModels: SchemeModel[] = [
new SchemeModel('抖音', 'snssdk1128'),
new SchemeModel('微博', 'sinaweibo'),
new SchemeModel('小红书', 'xhsdiscover'),
new SchemeModel('哔哩哔哩', 'bilibili'),
new SchemeModel('快手', 'kwai'),
new SchemeModel('微信', 'weixin'),
new SchemeModel('QQ', 'mqqapi'),
new SchemeModel('支付宝', 'alipays'),
new SchemeModel('云闪付', 'upwallet'),
new SchemeModel('京东', 'openapp.jdmobile'),
new SchemeModel('美团', 'imeituan', 'www.meituan.com'),
new SchemeModel('拼多多', 'pinduoduo'),
new SchemeModel('淘宝', 'tbopen', 'm.taobao.com', 'tbopen/index.html'),
new SchemeModel('高德地图', 'amapuri'),
new SchemeModel('腾讯会议', 'wemeet'),
new SchemeModel('知乎', 'zhihu'),
new SchemeModel('百度地图', 'baidumap', 'map', 'direction'),
new SchemeModel('腾讯地图', 'qqmap', 'map', 'routeplan'),
new SchemeModel('华为地图(花瓣地图)', 'maps', 'locationInfo'),
// 修正:运动健康补充正确的abilityName
new SchemeModel('运动健康', 'huaweischeme', 'healthapp', 'home/main', 'com.huawei.hmos.health',
'com.huawei.health.MainAbility'),
new SchemeModel('浏览器(百度)', 'https://www.baidu.com', '', '', undefined, undefined, true),
// 修正:优酷补充abilityName
new SchemeModel('优酷', 'youku', 'https://www.youku.com', 'h5/home', 'com.youku.next',
'com.youku.next.MainAbility'),
// 修正:去哪儿旅行补充abilityName
new SchemeModel('去哪儿旅行', 'qunar', 'https://m.qunar.com', 'hotel', 'com.qunar.hos',
'com.qunar.hos.MainAbility'),
// 修正:天眼查补充abilityName
new SchemeModel('天眼查', 'tianyancha', 'https://tianyancha.com', 'home', 'com.tianyancha.skyeye.hm',
'com.tianyancha.skyeye.hm.MainAbility'),
// 修正:58同城补充abilityName
new SchemeModel('58同城', 'wubalife', 'https://bj.58.com', 'home', 'com.wuba.life', 'com.wuba.life.MainAbility'),
// 修正:唯品会补充abilityName
new SchemeModel('唯品会', 'vipshop', 'https://m.vip.com', 'index', 'com.vip.hosapp', 'com.vip.hosapp.MainAbility')
];
build() {
// UI代码完全不变,此处省略(和之前一致)
Column() {
Text('选择要跳转的应用:')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 });
Scroll() {
Column({ space: 15 }) {
ForEach(this.schemeModels, (model: SchemeModel, index: number) => {
Row({ space: 10 }) {
Radio({ value: model.appName, group: 'appGroup' })
.checked(index === this.currentAppIndex)
.onChange((checked: boolean) => {
if (checked) {
this.currentAppIndex = index;
}
})
Text(model.appName)
.fontSize(16)
}
.width('100%')
.justifyContent(FlexAlign.Start)
.padding(10)
.backgroundColor('#F5F5F5')
.borderRadius(8)
}, (model: SchemeModel) => model.appName)
}
.width('100%')
.padding(20)
}
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
.layoutWeight(1);
Text(this.getAppStatusText())
.fontSize(14)
.fontColor(this.getStatusColor())
.margin({ top: 10, bottom: 10 })
.textAlign(TextAlign.Center);
if (this.showStatus) {
Text(this.appStatusList.map(item => `${item.name}: ${item.status}`).join('\n'))
.fontSize(14)
.width('100%')
.textAlign(TextAlign.Start)
.padding(10)
.backgroundColor('#F0F0F0')
.borderRadius(8)
.margin({ top: 10 });
}
Row({ space: 20 }) {
Button(this.getButtonText())
.width(150)
.height(45)
.enabled(this.getButtonEnabled())
.backgroundColor(this.getButtonEnabled() ? '#007DFF' : '#CCCCCC')
.fontColor(this.getButtonEnabled() ? Color.White : '#999999')
.onClick(() => {
this.launchApp();
});
Button('检查应用状态')
.width(150)
.height(45)
.backgroundColor('#666666')
.onClick(async () => {
this.showStatus = !this.showStatus;
if (this.showStatus) {
await this.checkAppStatus();
}
});
}
.margin({ top: 20 })
.justifyContent(FlexAlign.Center);
}
.width('100%')
.height('100%')
.padding(10);
}
/**
* 优化:带AbilityName的BundleName启动(解决16000019错误)
*/
private async openAppByBundleName(model: SchemeModel): Promise<boolean> {
if (!model.bundleName) {
return false;
}
// 构建Want参数:优先带abilityName
const want: Want = { bundleName: model.bundleName };
if (model.abilityName) {
want.abilityName = model.abilityName;
}
try {
await this.context.startAbility(want);
console.warn('AppLauncher', `通过BundleName+AbilityName成功打开: ${model.appName}`);
return true;
} catch (error) {
const businessError = error as BusinessError;
console.error('AppLauncher',
`通过BundleName打开${model.appName}失败: code=${businessError.code}, message=${businessError.message}`);
// 错误码区分:
// 16000019:组件匹配失败 → 降级到Scheme跳转
// 16000001:应用未安装 → 返回false(弹商店)
// 其他错误 → 降级到Scheme跳转
if (businessError.code === 16000001) {
return false;
} else {
return this.jumpToApp(model.getDeepLinking(), model.appName, model);
}
}
}
/**
* 通用Scheme跳转方法(保留)
*/
private async jumpToApp(uri: string, appName: string, model: SchemeModel): Promise<boolean> {
const want: Want = { uri: uri };
try {
await this.context.startAbility(want);
console.warn('AppLauncher', `通过Scheme成功跳转到: ${appName}`);
return true;
} catch (err) {
const businessError = err as BusinessError;
console.error('AppLauncher',
`Scheme跳转${appName}失败: code=${businessError.code}, message=${businessError.message}`);
// Scheme跳转失败且是未安装错误,返回false
if (businessError.code === 16000001) {
return false;
} else {
this.promptAction.showToast({ message: `${appName} 跳转失败,请手动打开` });
return false;
}
}
}
/**
* 最终版启动逻辑(多级降级)
*/
private async launchApp() {
const currentModel = this.schemeModels[this.currentAppIndex];
const deepLink = currentModel.getDeepLinking();
console.warn('AppLauncher', `尝试跳转到: ${currentModel.appName}, deepLink: ${deepLink}`);
// 1. 网页链接:直接Scheme跳转
if (currentModel.isWebUrl) {
await this.jumpToApp(deepLink, currentModel.appName, currentModel);
return;
}
// 2. 非网页链接:多级降级跳转
let isOpened = false;
// 2.1 优先:BundleName+AbilityName
if (currentModel.bundleName) {
isOpened = await this.openAppByBundleName(currentModel);
}
// 2.2 降级:Scheme跳转(如果BundleName失败且不是未安装)
if (!isOpened && bundleManager.canOpenLink(deepLink)) {
isOpened = await this.jumpToApp(deepLink, currentModel.appName, currentModel);
}
// 2.3 最终:未安装 → 弹应用商店
if (!isOpened && currentModel.bundleName) {
this.getUIContext().showAlertDialog({
title: '应用未安装',
message: `您的设备上未安装“${currentModel.appName}”,是否前往应用商店下载?`,
primaryButton: {
value: '前往应用商店',
action: () => {
startAppGalleryDetailAbility(this.context, currentModel.bundleName!);
}
},
secondaryButton: {
value: '取消', action: () => {
}
},
autoCancel: true,
backgroundBlurStyle: BlurStyle.Thin,
backgroundBlurStyleOptions: {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.AVERAGE,
scale: 1,
blurOptions: { grayscale: [20, 20] },
},
});
}
}
// 以下原有方法仅微调,无核心改动
private canOpenApp(): boolean {
const currentModel = this.schemeModels[this.currentAppIndex];
if (currentModel.isWebUrl) {
return true;
}
try {
return bundleManager.canOpenLink(currentModel.getDeepLinking());
} catch (error) {
console.error('AppLauncher', `检查应用状态失败: ${JSON.stringify(error)}`);
return false;
}
}
private getAppStatusText(): string {
const currentModel = this.schemeModels[this.currentAppIndex];
if (currentModel.isWebUrl) {
return `${currentModel.appName} (通过浏览器打开)`;
}
if (currentModel.bundleName || this.canOpenApp()) {
return `${currentModel.appName} (可正常打开)`;
} else {
return `${currentModel.appName} 暂不支持跳转`;
}
}
private getButtonEnabled(): boolean {
const currentModel = this.schemeModels[this.currentAppIndex];
if (currentModel.isWebUrl) {
return true;
}
return !!currentModel.bundleName || this.canOpenApp();
}
private async checkAppStatus() {
console.warn('AppLauncher', '开始检查所有应用状态...');
this.appStatusList = [];
for (const model of this.schemeModels) {
try {
let canOpen = false;
if (model.bundleName || model.isWebUrl) {
canOpen = true;
} else {
canOpen = await bundleManager.canOpenLink(model.getDeepLinking());
}
this.appStatusList.push({ name: model.appName, status: canOpen ? '可用' : '不可用' });
console.warn('AppLauncher', `应用 ${model.appName}: ${canOpen ? '可用' : '不可用'}`);
} catch (error) {
this.appStatusList.push({ name: model.appName, status: '检查失败' });
console.error('AppLauncher', `检查 ${model.appName} 状态失败: ${JSON.stringify(error)}`);
}
}
}
private getStatusColor(): string {
const currentModel = this.schemeModels[this.currentAppIndex];
if (currentModel.isWebUrl) {
return '#4F9DFF';
}
if (currentModel.bundleName || this.canOpenApp()) {
return '#007DFF';
}
return '#FF0000';
}
private getButtonText(): string {
const currentModel = this.schemeModels[this.currentAppIndex];
if (currentModel.isWebUrl) {
return '打开浏览器';
}
if (currentModel.bundleName || this.canOpenApp()) {
return '打开应用';
}
return '暂不支持';
}
}
在moudle.json5中加上
"querySchemes": [
"vipshop",
//唯品会
"wubalife",
//58同城
"tianyancha",
//天眼查
"qunar",
//去哪儿旅行
"youku",
//优酷
"huaweischeme",
//运动健康
"baidumap",
//百度地图
"qqmap",
//腾讯地图
'snssdk1128',
// 抖音
'sinaweibo',
// 微博
'xhsdiscover',
// 小红书
'bilibili',
// 哔哩哔哩
'kwai',
// 快手
'weixin',
// 微信
'mqqapi',
// QQ
'alipays',
// 支付宝
'upwallet',
// 云闪付
'openapp.jdmobile',
// 京东
'imeituan',
// 美团
'pinduoduo',
// 拼多多
'tbopen',
// 淘宝
'amapuri',
// 高德地图
'wemeet',
// 腾讯会议
'maps',
// 华为地图(花瓣地图)
'zhihu'
// 知乎
],
更多关于HarmonyOS鸿蒙Next中如何在开发中由应用APP跳转到另外一个APP上面的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用startAbility()进行跳转
Want是一种对象,用于在应用组件之间传递信息。
其中,一种常见的使用场景是作为startAbility()方法的参数。例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。代码如下所示
import { Want } from '@kit.AbilityKit';
const want: Want = {
// 需要跳转的bundleName(应用包名)
bundleName: 'com.huawei.hmos.settings',
// 需要跳转的Ability
abilityName: 'EntryAbility'
}
const uiContext = getContext(this) as common.UIAbilityContext
uiContext.startAbility(want)
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17
官方推荐Applink,Applink没安装对应应用时会引导下载,配置稍微复杂点,使用deeplink也可以,deepLink简单点
拉起指定应用概述-拉起指定应用-应用间跳转-Stage模型开发指导-Ability Kit(程序框架服务)-应用框架 - 华为HarmonyOS开发者
可以使用Applink,和deeplink
方式其实挺多 有一种是根据对方app的包 另外一种就是如果对方有app linking链接 你可以用context直接打开 实现跳转,
weixin://
可以看看官方文档的说明是否满足需求。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/link-between-apps-overview#应用跳转的两种类型
在HarmonyOS Next中,应用间跳转使用UIAbility的启动方式。通过调用startAbility()方法,并配置目标应用的want参数,指定bundleName和abilityName。需在目标应用的module.json5配置文件中导出UIAbility,设置"exported": true。同时,调用方需在module.json5中声明所需权限。
在HarmonyOS Next中,应用间跳转主要通过隐式Want实现。这是一种声明式的方式,不依赖具体目标应用包名,而是通过匹配action、entities、uri等参数来启动能处理该意图的应用。
核心步骤如下:
- 发起方应用:使用
startAbility()方法,传入一个隐式Want对象。 - 目标方应用:在
module.json5配置文件的abilities标签下,为对应的UIAbility声明相应的skills(过滤器),以表明自己能响应该Want。
示例代码:
- 发起跳转的应用:
import { common, Want } from '@kit.AbilityKit';
let wantInfo: Want = {
// 使用隐式Want,不指定bundleName和abilityName
action: 'ohos.want.action.viewData', // 自定义的action
entities: ['entity.system.browsable'],
uri: 'https://www.example.com/data' // 可携带数据
};
let context = getContext(this) as common.UIAbilityContext;
context.startAbility(wantInfo).then(() => {
// 跳转成功处理
}).catch((err) => {
// 跳转失败处理
});
- 被跳转的应用:在其
module.json5中配置skill。
{
"module": {
"abilities": [
{
"name": "TargetAbility",
// ... 其他配置
"skills": [
{
"entities": ["entity.system.browsable"],
"actions": ["ohos.want.action.viewData"] // 与发起方action匹配
}
]
}
]
}
}
关键点:
- 匹配规则:系统会根据发起方Want的
action、entities、uri(可选)等,与所有已安装应用的skills声明进行匹配。若匹配到多个应用,系统会弹出选择器供用户选择。 - 数据传递:可通过Want的
parameters属性携带复杂数据。 - 明确跳转:若确知目标应用包名与Ability名,也可使用显式Want,但会降低灵活性,且需确保目标应用已安装。
这种方式实现了应用间的解耦,是HarmonyOS应用交互的基础机制。

