Amadeus复刻计划(App篇 四)
项目中的理解难点——Intent:(示例代码大部分为Amadeus项目源码)
功能概述
可以实现应用间的不同组件交互(如应用内跳转)或是不同应用之间的交互(有的软件可以调用系统浏览器,就是用的这个)
使用方法(以实用为主,故不过多赘述参数,详情查文档)
显式调用:
Intent intent = new Intent(LaunchActivity.this, MainActivity.class);
startActivity(intent);上文代码意为从launchActivity跳转至MainActivity(软件中用于从启动界面跳转至语音交互界面)
显示调用基本就是这样,很简单故不作赘述
隐式调用
显式调用中明确指出了跳转至哪个页面(MainActivity),但有的时候我们并不需要这么做,比如调用浏览器访问网页,无论是哪个浏览器都能满足需求,故只需要指定“浏览器”这个宽泛的概念即可,而不是必须使用“谷歌浏览器”(例)
Intent intent = new Intent();
intent.setAction("com.example.a3_30intent.action.MY_ACTION");
上面代码即为隐式调用,其中setAction中的参数是一个字符串,该字符串内容与安卓项目中的Manifest.xml相对应(那个注册activity的文件),需要被隐式调用的activity需要在其中加入<intent-fliter>标签,并在该标签内设置action android:name属性。实际上隐式调用所指定的setAction参数就是匹配的该name,当然并不限于同应用,如果知道其他应用的name值,也可以调用该应用的相应组件
在本项目中隐式调用使用了一种变形,作者使用preference构造了设置界面(用于选择界面语言、设定闹钟等功能),其中点击set up会跳转至单独的activity用于设定闹钟。其实现方式为在preference的框架下新建类似这样的标签结构
<Preference android:title="@string/pref_alarm_setup">
<intent
android:action="android.intent.action.VIEW.ALARM"
/>
</Preference>其中intent标签就是实现隐式调用的方法,action的值为目标activity,笔者第一次遇见的时候还颇为疑惑。
PendingIntent
PendingIntent可以视作是Intent的一种封装,上面提到的调用intent的方法都是类似于“点击即用”的方式,但如果你想要定时启动某服务,或者满足某种触发条件再启动就不是很方便。于是PendingIntent就出现了,笔者的个人理解是PendingIntent是提前设定好满足触发条件后的行为(但此时并没有调用),当满足一定条件后才开始调用。
值得注意的是,定义PendingIntent时需要指定Flag参数,而该参数会因安卓api版本不同而不同,更要命的是如果设置错误应用会直接闪退,难以排查,折腾了笔者许久,希望后来者注意。(api>31时为PendingIntent.FLAG_IMMUTABLE)
intent模块笔者所使用到的大概就是上述这些,下文再略作讨论下项目的消息通知机制(就是一般应用的横幅弹窗)
项目中的消息通知函数写的基本没有问题,唯一需要注意的是安卓高版本需要指定NotificationChannel来自定义通知重要级,当然这也很合理,开发者指定消息重要级,然后交由用户判断是否接收该通知,可以有效治理流氓软件的行为
ps:原项目中设定的闹钟响时发送消息与进入启动页面发送消息,这两处的代码有所不同,笔者修改为了与后者保持一致,应该没太大问题。
pps:用两台电脑开发数据迁移实在太麻烦,明天折腾下git同步,希望AS里面的设置不要太复杂……就这样吧