uni-app创建桌面Shortcuts支持Android && iOS

426 阅读7分钟

uni-app、uni-app-x创建shortcuts支持Android以及iOS并且支持国际化。如果你不会原生开发,通过搜索引擎找来找去,都没有找到完整的创建Shortcuts的流程,那么你来对了,迄今为止这是最全面并且免费的教程。

翻译为纯前端人员能看的懂的数据格式就是下面这样

{
    "type": "about",
    "title": "关 于",  
    "subtitle": "www.dcloud.io", 
    "icontype": "",
    "iconfile": "sa.png",  
    "userinfo": {  
        "key3":"value3"  
    } 
}
  • type: (必选)菜单项类型,字符串类型,用于标识菜单项
  • title: (必选)菜单项上显示的标题,字符串类型
  • subtitle: (可选)菜单项上显示的子标题,字符串类型,如果你手机上有Soul 可以长按看一下,颜色比较淡一点的那一行就是subtitle在这里郑重声明,本人从来不玩Soul
  • icontype: (可选)菜单项上显示的图标类型,字符串类型,取值参考iOS官方文档UIApplicationShortcutIconType
  • iconfile: (可选)菜单项上显示的图标文件,字符串类型, 如果有值则icontype失效,一般都会使用自己的图片。注意:图片是纯白色并且背景透明的png
  • userinfo: (可选)菜单项上的自定义数据,JSON格式 额外的参数 我觉得有个type就可以判断了

说了这么多开始赶紧进入正题(我是真的不想打字)

manifest.json切换到源码试图,在app-plus节点下面添加locales节点。

这里面配置了Android以及iOS平台下面的Shortcuts展示文本对应的中英文配置

"locales": {
    "zh": {
        "android": {
            "strings": {
                "AddTitle": "扫啊扫",
                "DailyTitle": "签到",
                "ExchangeTitle": "你想干什就干什"
            }
        },
        "ios": {
            "infoPlist": {
                "AddTitle": "扫啊扫",
                "DailyTitle": "签到",
                "ExchangeTitle": "你想干什就干什"
            }
        }
    },
    "en": {
        "android": {
            "strings": {
                "AddTitle": "Scan for adding devices",
                "DailyTitle": "Daily check-in",
                "ExchangeTitle": "Point exchange"
            }
        },
        "ios": {
            "infoPlist": {
                "AddTitle": "Scan for adding devices",
                "DailyTitle": "Daily check-in",
                "ExchangeTitle": "Point exchange"
            }
        }
    }
}

如果需要支持其它语言,请自行添加,如果你想要测试英文请将系统语言设置为英文,然后在进行体验。 不能想要即要还要,知足者常乐

iOS平台

在你的项目根目录下面创建Info.plist文件,不要犟,它只能是Info.plist,不能是love.list或者是hello.list,如果你不犟那我给你说说Info.plist是什么?它是什么呢? 对!没错。他就是相当于你的vite.config.js或者vue.config.js。只是Info.plist要比它们功能强大

在项目更目录下面新建nativeResources文件夹,在nativeResources新建ios文件夹,在此基础上新建Resources文件夹。把你的图片放在此文件里面

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<!-- 添加shortcuts -->
		<key>UIApplicationShortcutItems</key>
		<array>
			<!-- 扫一扫 -->
			<dict>
				<!-- type -->
				<key>UIApplicationShortcutItemType</key>
				<string>add</string>
				<!-- title -->
				<key>UIApplicationShortcutItemTitle</key>
                                <!-- AddTitle是在manifest.json下面locales下面的infoPlist的key  -->
				<string>AddTitle</string>
				<!-- icontype内置图标 -->
				<!-- <key>UIApplicationShortcutItemIconType</key>
				<string>UIApplicationShortcutIconTypeAdd</string> -->
				<!-- subtitle -->
				<key>UIApplicationShortcutItemSubtitle</key>
				<string>我是副标题</string>
				<!-- iconfile -->
				<key>UIApplicationShortcutItemIconFile</key>
                                <!--菜单项上显示的图标文件名称 记得不要后缀.png 图片文件在nativeResources下面的ios下面的Resources文件夹下面 -->
				<string>scode</string>
			</dict>
			<!-- 签到 -->
			<dict>
				<key>UIApplicationShortcutItemType</key>
				<string>daily</string>
				<key>UIApplicationShortcutItemTitle</key>
				<string>DailyTitle</string>
				<key>UIApplicationShortcutItemIconFile</key>
				<string>daily</string>
			</dict>
			<!-- 积分兑换 -->
			<dict>
				<key>UIApplicationShortcutItemType</key>
				<string>exchange</string>
				<key>UIApplicationShortcutItemTitle</key>
				<string>ExchangeTitle</string>
				<key>UIApplicationShortcutItemIconFile</key>
				<string>point</string>
			</dict>
		</array>
	</dict>
</plist>

此图为证 image.png

好了到此在app-ios上面已经可以了,在桌面上长按你的应用 就可以看到效果了。哦!对了 需要云打包后才能生效,模拟器里面也可以看到。并且只能添加四个

wecom-temp-169017-9a4fa013fc5e256b9f583b3136afb659.jpg

Android平台

在项目根目录下新建AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"  
    package="com.hello.meet">
    <!-- 上面的package="com.hello.meet"  com.hello.meet是你的自定义包名-->
    <application>
        <!-- io.dcloud.PandoraEntry是固定的不要修改 不要犟 -->
        <activity android:name="io.dcloud.PandoraEntry">
			<intent-filter>
		        <action android:name="android.intent.action.MAIN" />
		        <category android:name="android.intent.category.LAUNCHER" />
		    </intent-filter>
            <!-- 添加快捷方式的配置 -->
            <meta-data
                android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts" />
            <!-- shortcuts是nativeResources-android-res-xml-shortcuts.xml文件名 -->
        </activity>    
    </application>

</manifest>

在项目根目录下nativeResources新建android文件夹,在android文件夹下面新建res,继续在res文件夹下面新建三个文件夹,分别是:xmlvaluesdrawable

  • xml 下面存放shortcuts配置文件
  • drawable 下面存放图片资源文件
  • values 下面存放描述文件

我已经说过了 把你要在shortcuts展示的图标图片上在drawable里面 记得是png格式哦 大小96*96可以试试, 如果图片比较模糊 那就在大一些,直到到它不模糊。温馨提示 云打包是有次数限制的,如果你充了会员就当没看见

好了,图片资源已经放到drawable里面了,下面就是xml以及values这两个文件了。

values/strings.xml

<resources>
    <string name="AddTitle">Scan for adding devices</string>
    <string name="DailyTitle">Daily check-in</string>
    <string name="ExchangeTitle">Point exchange</string>
</resources>

稍微解释一下: 还记得最上面的manifest.json里面的 locales节点里面的东西? 不记得自己往上☝️翻 。这里的nameAddTitle就是 android.strings对应的key。至于我为什么在string里面也写了,不是因为我喜欢打字,而是当你国际化语言不支持的时候 会使用这个里面的文字内容。比如你只配置了中英文,如果系统语言是俄语,那此时显示的就是你里面的内容。

xml/shortcuts.xml

<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 扫啊扫 第一个item -->
    <shortcut
        android:shortcutId="add"
        android:enabled="true"
        android:icon="@drawable/scode"
        android:shortcutShortLabel="@string/AddTitle">
        <!-- @string/AddTitle 是values文件下面的strings.xml里面的name值 -->
        <intent
            android:action="android.intent.action.VIEW"
            android:targetPackage="com.hello.meet"
            android:targetClass="io.dcloud.PandoraEntryActivity">
                        <!-- extras是参数 可以有多个 -->
			<extra android:name="type" android:value="add" />
                        <extra android:name="hello" android:value="yes" />
		</intent>
		<categories android:name="android.shortcut.conversation" />
		<capability-binding android:key="actions.intent.CREATE_MESSAGE" />
    </shortcut>
    <!-- 签到 第二个item  -->
    <shortcut
        android:shortcutId="daily"
        android:enabled="true"
        android:icon="@drawable/daily"
        android:shortcutShortLabel="@string/DailyTitle">
       <intent
           android:action="android.intent.action.VIEW"
           android:targetPackage="com.hello.meet"
           android:targetClass="io.dcloud.PandoraEntryActivity">
		   <extra android:name="type" android:value="daily" />
		</intent>
		<categories android:name="android.shortcut.conversation" />
		<capability-binding android:key="actions.intent.CREATE_MESSAGE" />
    </shortcut>
	<!-- 积分 第三个item -->
	<shortcut
	    android:shortcutId="exchange"
	    android:enabled="true"
	    android:icon="@drawable/point"
	    android:shortcutShortLabel="@string/ExchangeTitle">
	   <intent
	       android:action="android.intent.action.VIEW"
	       android:targetPackage="com.hello.meet"
	       android:targetClass="io.dcloud.PandoraEntryActivity" >
			<extra android:name="type" android:value="exchange" />
		</intent>
		<categories android:name="android.shortcut.conversation" />
		<capability-binding android:key="actions.intent.CREATE_MESSAGE" />
	</shortcut>
</shortcuts>

这个shortcuts.xml里面的字段我也稍微狡辩一下:即使代码里面有注释,我还是怕你们不懂。 不!不是你们看不懂,是我表达的有问题。

<shortcut
        android:shortcutId="daily"//这个就相当于你v-for时候的那个key
        android:enabled="true"
        android:icon="@drawable/daily"// 这个就是drawable文件下面的图标文件名称 不要带后缀.png啊
        android:shortcutShortLabel="@string/DailyTitle">//这个是对应的名字 就是那个名字
       <intent
           android:action="android.intent.action.VIEW"//不要修改
           android:targetPackage="com.hello.meet"//这个是你自定义的包名
           android:targetClass="io.dcloud.PandoraEntryActivity">//不要修改
		   <extra android:name="type" android:value="daily" />//这个是参数 key-value
		</intent>
		<categories android:name="android.shortcut.conversation" />//不要修改
		<capability-binding android:key="actions.intent.CREATE_MESSAGE" />//不要修改
    </shortcut>

如果看到这 你还不知道谁在谁下面,此图为证 image.png

如果你已经认认真真看到这,不出意外 你已经成功的可以展示Shortcuts了。请在app-android 长按你的应用,你可以看到了,是不是觉得自己很了不起,很神奇,是的!

应当仔细地观察,为的是理解;应当努力地理解,为的是行动。——罗曼罗兰

如果到这了,你还有疑问?那我很高兴。因为 罗曼罗兰曾说,生活中不是缺少美,而是缺少发现美的眼睛。愿我们都能成为生活的艺术家,用心感受每一处细微的美好。

好了 继续往下看

获取启动参数

App.vue里面处理

<script setup>
import { onLaunch,onShow,onHide } from '@dcloudio/uni-app'

const useShortcut = ()=>{
	const name = plus.runtime.launcher//获取app启动类型
	if(name == 'shortcut'){// 如果是通过shortcut启动
		const {type} = JSON.parse(plus.runtime.arguments)
		if(type == 'add'){// type就是这个<extra android:name="type" android:value="add" /> 不记得自己往上翻
			// 去做你想做的是
		}
	}
}
onLaunch(()=>{
	console.log('App Launch')
	const {osName} =  uni.getSystemInfoSync()
	osName == 'ios' ? useShortcut() : false;//为什么要执行一次 app 首次启动 包括杀掉进程在启动的时候 
	plus.globalEvent.addEventListener('newintent',() => {// app切换到后台 再到前台的时候会触发这个方法
		// 为什么这里要判断 因为android平台上面不会触发这个方法 这不是我的问题 是uni-app的问题
		osName == 'ios' ? useShortcut() : false
	});
})
onShow(()=>{
	console.log('App Show')
	const {osName} =  uni.getSystemInfoSync()
	if(osName == 'android'){// android 需要延时获取参数 要不然获取不到 不要问为什么 应为我试了几个手机都是这样
		setTimeout(()=>{
			useShortcut()
		},50)
	}
})
onHide(()=>{
	console.log('App Hide')
})
</script>

获取到启动参数 你就可以开始你自己的表演了。如果还有疑问可以评论 ,近几年很少逛掘金了,如果非要跟我探讨一下那么你可以发我邮箱wmf@meet-ui.cn。当然如果你好奇我是怎么有自己的 可以自定义域名邮箱的,也可以发邮件。

如果你通过 搜索引擎 的相关关键词进入了 掘金看到这一篇文章,并且对你还有那么一丝丝用处或者启发。那么我觉得 这篇文章已经发挥了它的作用

如果有人错过机会,多半不是机会没有到来,而是因为等待机会者没有看见机会到来,而且机会过来时,没有一伸手就抓住它。——罗曼·罗兰