点击APP外部链接唤醒APP的研究

本文探讨了如何通过点击外部URL来直接唤起特定APP的方法。主要介绍了通过配置AndroidManifest.xml来实现URL拦截,并通过系统浏览器加载指定HTML文件,进而实现跳转到APP内指定页面的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有个需求,是点击短信中的(或者是其他地方的)URL,能够唤起APP。

思路,首先找个实现了的APP做测试。

选择手机淘宝做研究。

在淘宝中把宝贝链接分享到微信,结果如下:


直接点开,跳转到微信的内建浏览器,指示用户通过浏览器打开:


点击在浏览器中打开,效果为弹窗显示所有的浏览器APP,提示选择一个浏览器。此时使用淘宝打开即跳转到APP


把链接内容作为短信发送给自己,点击短信中的链接,效果:

1.首先弹出安卓系统默认浏览器,展现出宝贝页面

2.马上跳转到淘宝APP内,并展示宝贝


差异:

1.微信使用内建浏览器打开;短信一般使用系统浏览器打开。

分析:微信的实现是使用自定义的WebView;系统的实现是指定意图,并显示打开指定的浏览器。

2.微信页面打开之后,需要选择打开的应用;短信打开的页面可以直接跳转。

分析:短信可以跳转,不是通过自定义WebView,无法使用JS接口,而且是能通过第三方APP跳转,一定是通过安卓系统组件实现的跳转,不是直接跳转,说明只能拦截系统默认浏览器中的URL跳转操作才能实现跳APP;

微信无法跳转,猜测可能是对scheme特殊的URL进行了拦截。


查找了资料,可以通过修改manifest来实现一个Activity接收传递来的URL:

        <activity
            android:name=".activity.UrlJumpActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:scheme="http"/>
            </intent-filter>
        </activity>


然后自己写Demo程序。

猜想如果点击web链接能够跳转到指定APP,则也能够实现像淘宝那样进入系统浏览器稍后跳转到APP。

使用WebView加载自定义的HTML文件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" dir="ltr">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <script type="text/javascript">
            function showAndroidToast(toast) {
                javascript:android.showToast(toast);
            }
        </script>
    </head>
    <body>
        <input type="button" value="Say hello"
            onClick="showAndroidToast('Hello Android!')" />
        <a href="http://www.baidu.com">open http link</a>
    </body>
</html>
将HTML文件放到APP的asset目录下面,在启动后加载HTML:

    // 1.加载HTML文本
    //String htmlText = AssetUtil.getFromAssets(this, "a.html");
    //mWebView.loadData(htmlText, "text/html", "utf-8");

    // 2.加载asset中的HTML文件
    //mWebView.loadUrl("file:///android_asset/a.html");

    // 3.加载外部HTML文件
    mWebView.loadUrl("file:///sdcard/a.html");
几种方法都能够成功加载HTML文件并显示:


请忽略那个say hello按钮,点击open http link报错:

ERROR_UNKNOWN_URL_SCHEME


哪里有问题?对比淘宝,是用的系统浏览器,而我用的WebView,可能系统浏览器会额外做一些工作吧,于是使用系统浏览器加载这段HTML。

做了各种尝试:

    Intent intent=new Intent();
    intent.setAction("android.intent.action.VIEW");
    //Uri uri = Uri.parse("content://com.android.htmlfileprovider/sdcard/a.html");
    //Uri uri = Uri.parse("file:///android_asset/a.html");
    Uri uri = Uri.parse("file:///sdcard/a.html");
    //Uri uri = Uri.parse("http://www.qq.com");
    intent.setData(uri);
    intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");

其中,第三种方法是可行的:把HTML文件拷贝到外部存储,并使用外部存储文件的URL传递给浏览器。

第一种方式原因未知。

第二种使用asset,查找资料得知:要调起的APP是系统浏览器,而加载的文件却在我们自己的内部存储中,系统浏览器是无法读取文件的,囧。

第四种直接加URL显然可以,然并卵。

最后一行代码有可能无效,如果无效报manifest中未定义BrowserActivity的话则替换为下面代码:

intent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));


使用系统浏览器打开外部存储的HTML文件后,效果与自定义WebView的显示效果相同,并且点击链接后,能够跳转到我们想要的Activity。


当然,如果我们的H5界面上线了,就不用加载我们自己的HTML文件了。


总结:

点击外部URL跳转到自己的APP界面是可行的。

需要在manifest文件中对目标Activity添加拦截指定的scheme的配置。

web端要做的:与APP定跳转Activity的私有协议,在页面中直接触发此条私有协议,来达到淘宝的效果。

APP端需要做的工作还有:接收web端传来的参数进行处理。

系统默认浏览器无法加载APP内部HTML文件。

自定义WebView和系统浏览器还是有区别的,系统浏览器会根据scheme触发可以响应的安卓组件。


<think>我们参考用户提供的引用内容,特别是引用[1]和引用[3]中关于URL Scheme在UniApp中的使用。 用户需求:了解UniApp中如何通过Scheme唤醒App的指南。 步骤: 1. 配置URL Scheme:在manifest.json文件中配置iOS和Android的URL Scheme。 2. 处理外部唤醒:在App中编写代码,监听处理外部URL的唤醒事件。 3. 实现跳转逻辑:解析URL参数,跳转到指定页面。 详细步骤: 一、配置URL Scheme 在UniApp项目中,打开manifest.json文件,进行如下配置: 对于Android平台,在"app-plus" -> "distribute" -> "android"节点下配置scheme: 对于iOS平台,在"app-plus" -> "distribute" -> "ios"节点下配置scheme,同时需要在"urlschemewhitelist"(白名单)中添加需要使用的scheme(如微信的weixin、wechat等)。 示例配置(manifest.json): ```json { "app-plus": { "distribute": { "android": { "schemes": ["myapp"] // Android的URL Scheme }, "ios": { "schemes": ["myapp"], // iOS的URL Scheme "urlschemewhitelist": ["weixin", "wechat"] // 如果需要检测或唤醒微信,需要将微信的scheme加入白名单 } } } } ``` 二、处理外部唤醒App启动时,需要监听处理外部URL的唤醒事件。UniApp提供了`onLaunch`和`onShow`生命周期函数,我们可以在这里获取启动参数。 在App.vue中,我们可以通过`onShow`方法获取传递过来的参数。 示例代码(App.vue): ```javascript export default { onShow: function(options) { // 获取启动参数 const args = plus.runtime.arguments; if (args) { // 处理args,例如解析URL // 假设外部唤醒的URL为 myapp://detail?id=123 // 这里可以将参数传递给指定页面,然后跳转 console.log('唤醒参数:', args); // 解析URL,获取参数 // 这里简单示例,实际需要根据URL格式解析 let pagePath = ''; let query = {}; // 实际解析逻辑需要根据你的URL格式来写 // 例如:如果args是完整URL,可以使用URL对象解析(注意:在App端,可能不是标准的http/https,需要自己处理) // 这里简化处理,假设我们已经解析出要跳转的页面和参数 pagePath = '/pages/detail/detail'; query = { id: '123' }; // 从URL中解析出的参数 // 跳转到指定页面 uni.navigateTo({ url: pagePath + '?' + Object.keys(query).map(key => `${key}=${encodeURIComponent(query[key])}`).join('&') }); } } } ``` 注意:由于外部唤醒可能发生在App已经运行(在后台)的情况下,我们还需要考虑在App运行时被唤醒的情况。上述代码在`onShow`中处理,可以覆盖冷启动和热唤醒。 三、实现跳转逻辑 在第二步中,我们已经将参数传递给了目标页面。在目标页面(如detail页面)的onLoad生命周期中,可以获取传递的参数。 示例代码(detail.vue): ```javascript export default { onLoad(options) { // options 中包含了传递的参数 console.log('页面参数:', options); // 根据参数id获取详情内容 if (options.id) { this.loadDetail(options.id); } }, methods: { loadDetail(id) { // 根据id请求详情数据 } } } ``` 四、生成外部唤醒链接 外部唤醒链接格式为:`[scheme]://[host]/[path]?[query]`,其中scheme就是我们在manifest.json中配置的scheme(如myapp),host、path和query可以根据需要定义。 例如:`myapp://detail?id=123`,表示唤醒App并跳转到详情页,参数id为123。 五、注意事项 1. iOS平台需要配置白名单(urlschemewhitelist),否则无法唤醒其他App(如微信)或无法被其他App唤醒。 2. 在Android平台上,如果App被杀死,通过URL Scheme唤醒时,启动参数可以在App.vue的`onLaunch`和`onShow`中获取。但在App后台运行时,唤醒会触发`onShow`,而不会触发`onLaunch`。 3. 在iOS平台上,如果App被杀死,通过URL Scheme唤醒时,启动参数在`onLaunch`和`onShow`中都可以获取,但通常推荐在`onShow`中处理,因为`onLaunch`在App启动时只触发一次,而`onShow`在每次App显示时都会触发(包括从后台唤醒)。 六、高级:通过Universal Link(通用链接唤醒 除了URL Scheme,还可以使用Universal Link(iOS)和App Link(Android)来实现唤醒。这种方式使用标准的HTTPS链接,在用户未安装App时可以打开网页,安装App则直接打开App。但UniApp目前对Universal Link的支持需要额外配置,且相对复杂。具体可参考引用[2]中的内容。 由于用户问题主要关注Scheme,这里不展开Universal Link。 七、封装工具函数(参考引用[3]) 我们可以封装一个工具函数来检测并唤醒其他App(如微信),同时支持传递参数。 示例工具函数(appLauncher.js): ```javascript // utils/appLauncher.js export const launchApp = (params) => { // #ifdef APP-PLUS const { pname, iosScheme, data } = params; const isAndroid = plus.os.name.toLowerCase() === 'android'; const appInfo = { pname: isAndroid ? pname : undefined, // Android包名 action: !isAndroid ? iosScheme : undefined, // iOS的scheme extra: data || {} // 传递的参数 }; return new Promise((resolve, reject) => { // 检查应用是否安装 const exist = plus.runtime.isApplicationExist(appInfo); if (!exist) { reject('APP_NOT_INSTALLED'); return; } // 唤醒应用 plus.runtime.launchApplication(appInfo, (err) => { if (err) { reject('LAUNCH_FAILED'); } else { resolve('SUCCESS'); } }); }); // #endif }; ``` 使用示例: ```javascript import { launchApp } from '@/utils/appLauncher.js'; // 唤醒微信 launchApp({ pname: 'com.tencent.mm', // 微信的Android包名 iosScheme: 'weixin://', // 微信的iOS Scheme data: {} // 可以传递参数,但微信是否接收参数取决于微信的URL Scheme接口 }).then(() => { console.log('唤醒成功'); }).catch(err => { console.log(err); // 如果微信未安装,可以提示用户 uni.showToast({ title: '未安装微信', icon: 'none' }); }); ``` 注意:唤醒其他App需要知道目标App的URL Scheme(iOS)或包名(Android),并且目标App必须支持通过URL Scheme唤醒。 以上就是在UniApp中通过Scheme唤醒App的指南。 根据要求,生成相关问题: 1. 如何在UniApp中配置Universal Link实现唤醒? 2. UniApp中如何区分冷启动和热唤醒? 3. 如何解析URL Scheme中的复杂参数?</think>### UniApp 通过 Scheme 唤醒 App 指南 在 UniApp 中通过 URL Scheme 唤醒 App 主要涉及以下核心步骤,支持 iOS 和 Android 平台: #### 一、配置 URL Scheme 1. **Android 配置** 在 `manifest.json` 中添加: ```json "app-plus": { "distribute": { "android": { "schemes": ["myapp"] // 自定义 Scheme 名称 } } } ``` 2. **iOS 配置** 在 `manifest.json` 中添加 Scheme 和白名单: ```json "app-plus": { "distribute": { "ios": { "schemes": ["myapp"], // 自定义 Scheme "urlschemewhitelist": ["weixin", "wechat"] // 需检测的第三方 App 白名单 } } } ``` #### 二、处理外部唤醒事件 在 `App.vue` 中监听唤醒事件: ```javascript onShow: function(options) { // 获取唤醒参数(Android/iOS 通用) const args = plus.runtime.arguments; if (args) { // 示例:myapp://detail?id=123 → 解析跳转到详情页 const params = new URLSearchParams(args.split('?')[1]); const id = params.get('id'); uni.navigateTo({ url: `/pages/detail?id=${id}` }); } } ``` #### 三、生成唤醒链接 - **格式**:`[scheme]://[path]?[params]` 示例:`myapp://product/detail?id=1001` - **使用场景**: - 网页链接:`<a href="myapp://home">打开App</a>` - 二维码:嵌入 Scheme 链接 - 短信/邮件:`点击链接打开:myapp://login?token=xxx` #### 四、检测并唤醒第三方 App 封装工具函数(如 `appLauncher.js`): ```javascript export const launchApp = (params) => { const { pname, iosScheme, data } = params; const isAndroid = plus.os.name.toLowerCase() === 'android'; const appInfo = { pname: isAndroid ? pname : undefined, // Android 包名 action: !isAndroid ? iosScheme : undefined, // iOS Scheme extra: data || {} // 传递参数 }; return new Promise((resolve, reject) => { // 检测是否安装 if (!plus.runtime.isApplicationExist(appInfo)) { return reject('APP_NOT_INSTALLED'); } // 唤醒应用 plus.runtime.launchApplication(appInfo, (err) => { err ? reject('LAUNCH_FAILED') : resolve('SUCCESS'); }); }); }; ``` #### 五、使用示例(唤醒微信) ```javascript import { launchApp } from '@/utils/appLauncher'; // 唤醒微信并传递参数 launchApp({ pname: "com.tencent.mm", // Android 包名 iosScheme: "weixin://", // iOS Scheme data: { type: "share" } // 自定义参数 }).catch(err => { uni.showToast({ title: "微信未安装", icon: "none" }); }); ``` #### 注意事项 1. **iOS 白名单限制** iOS 9+ 必须配置 `urlschemewhitelist`,否则无法检测第三方 App[^3]。 2. **参数传递** 复杂数据需 JSON 序列化:`data: { payload: encodeURIComponent(JSON.stringify(obj)) }`。 3. **Android 包名** 通过应用商店查询或 Apk 解压获取(如微信包名:`com.tencent.mm`)。 4. **Scheme 冲突** 避免使用常见 Scheme(如 `http`/`weixin`),防止与系统应用冲突。 > **实践建议**:测试时直接用设备浏览器访问 `myapp://home`,观察是否成功唤醒 App[^1]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值