当我们用一个显式 Intent 去启动组件时,Android 会根据 Intent 对象所提供的 component name 直接找到要启动的组件,当我们用一个隐式的 Intent 去启动组件时,Android 系统就无法直接知道要启动的组件名称了。
显式 Intent
代码语言:javascript复制Intent intent = new Intent(this, xxx.class);startActivity(intent);
隐式 Intent
使用隐式 Intent 之前需要在 AndroidManifest.xml 中对标签增加设置。
代码语言:javascript复制<activity android:name="..IntentActivity"> <intent-filter> <action android:name="com.luyai.action.TEST" /> </intent-filter></activity>
使用隐式 Intent 跳转 Activity。
代码语言:javascript复制Intent intent = new Intent("com.luyai.action.TEST");startActivity(intent);
Intent Filter
如果 Intent 中的存在 category 那么所有的 category 都必须和 Activity 过滤规则中的 category 相同。才能和这个 Activity 匹配。Intent 中的 category 数量可能少于 Activity 中配置的 category 数量,但是 Intent 中的这 category 必须和 Activity 中配置的 category 相同才能匹配。
代码语言:javascript复制<activity android:name=".ui.activity.IntentActivity"> <intent-filter> <action android:name="com.luyai.action.TEST" /> <category android:name = "android.intent.category.DEFAULT" /> <category android:name="xxx.xxx.xxx"/> </intent-filter></activity>
运行以下代码可以匹配到 IntentActivity:
代码语言:javascript复制Intent intent = new Intent("com.luyai.action.TEST");intent.addCategory("xxx.xxx.xxx");startActivity(intent);
只通过 category 匹配是无法匹配到 IntentActivity 的,因为 category 属性是一个执行 Action 的附加信息。
URL Scheme
Android 中的 Scheme 是一种页面内跳转协议,是一种非常好的实现机制。通过定义自己的 Scheme 协议,可以非常方便跳转 App 中的各个页面。
使用场景:
- 通过小程序,利用 Scheme 协议打开原生 App。
- H5 页面点击锚点,根据锚点具体跳转路径 App 端跳转具体的页面。
- App 端收到服务器端下发的 Push 通知栏消息,根据消息的点击跳转路径跳转相关页面。
- App 根据URL跳转到另外一个 App 指定页面。
- 通过短信息中的 URL 打开原生 App。 Scheme 路径的规则:
<scheme> :// <host> : <port> [<path>|<pathPrefix>|<pathPattern>]
设置 Scheme
在 AndroidManifest.xml 中对标签增加设置 Scheme。
<activity android:name=".ui.activity.SchemeActivity" android:screenOrientation="portrait"> <!--Android 接收外部跳转过滤器--> <!--要想在别的 App 上能成功调起 App,必须添加 intent 过滤器--> <intent-filter> <!--协议部分配置,注意需要跟 web 配置相同--> <data android:scheme="aa" android:host="bb" android:port="1024" android:path="/from"/> <!--下面这几行也必须得设置--> <category android:name="android.intent.category.DEFAULT" /> <!--表示 Activity 允许通过网络浏览器启动,以显示链接方式引用,如图像或电子邮件--> <category android:name="android.intent.category.BROWSABLE" /> <action android:name="android.intent.action.VIEW" /> </intent-filter></activity>
原生调用:
代码语言:javascript复制Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);startActivity(intent);
网页调用:
代码语言:javascript复制<a href="aa://bb:1024/from?type=jeanboy">打开 App</a>
在 SchemeActivity 中可以处理 Scheme 跳转的参数:
代码语言:javascript复制public class SchemeActivity extends AppCompatActivity {
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Uri uri = getIntent().getData(); if (uri != null) { //获取指定参数值 String type = uri.getQueryParameter("type"); Log.e("SchemeActivity", "type:" type);
if(type.equals("jeanboy")){ ActivityUtils.startActivity(XXXActivity.class); }else if(type.equals("main")){ ActivityUtils.startActivity(MainActivity.class); } } finish(); }}
判断一个 Scheme 是否有效:
代码语言:javascript复制PackageManager packageManager = getPackageManager();Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);boolean isValid = !activities.isEmpty();if (isValid) { startActivity(intent);}