在android的应用程序可以有多个Activity,每个Activity是同级别的,那么在启动程序时,最先启动哪个Activity呢?有些程序可能需要显示在程序列表里,有些不需要。怎么定义呢?
android.intent.action.MAIN 决定应用程序最先启动的Activity 。
android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。
因为你的程序可能有很多个activity,
只要xml配置文件中有这么一个intent-filter,而且里面有这个launcher,那么这个activity就是点击程序时最先运行的那个activity。
1
2
3
4
5
6
7
8
|
<
intent-filter
>
<
action
android:name
=
"android.intent.action.MAIN"
/>
<
category
android:name
=
"android.intent.category.DEFAULT"
/>
<!--
<category android:name="android.intent.category.LAUNCHER" />
-->
<
category
android:name
=
"android.intent.category.BROWSABLE"
/>
</
intent-filter
>
|
intent一定要有的3个匹配值, action, category, data.
发送了这个intent之后,android会去系统里保存的MainManifest.xml清单(假设这个系统存放全部apk清单的文件为MainManifest.xml)里查找符合这两个属性的activity,然后启动它。
当某个Activity用startActivity(intentOther)方法向系统发送了一个intent(假如为 intentOther),那么android系统会去查找这个MainManifest.xml里注册的<intent-filter >属性,
查找到符合这个 intentOther 的就启动这个Activity,如果有多个这样的Activity符合条件的话,就跳出一个对话框让用户选择究竟要启动哪一个
1
2
3
4
5
6
7
8
9
10
11
12
|
<!-- display missed call -->
<
activity-alias
android:name
=
"@string/missedcallactivity"
android:icon
=
"@drawable/missing_icon"
android:label
=
"@string/missedcallactivity"
android:targetActivity
=
".CustomLinphoneDialer"
>
<
intent-filter
>
<
action
android:name
=
"android.intent.action.MAIN"
/>
<
category
android:name
=
"android.intent.category.LAUNCHER"
/>
</
intent-filter
>
</
activity-alias
>
|
这个代码 能显示两个图标 ,我们的目的是 能显示通话记录, 还得调用target activity, and show call history activity.
为了能支持隐式intent,activity、service和broadcast receiver会包含1到多个intent filter。每个intent filter描述组件的可接收一组intent的能力。在intent filter中,说明了可接受的类型,以及不想要的intent。隐式的intent要想投递到一个组件,只需通过组件的一个filter即可。
组件把filter分成多个,是为了针对具体不同的任务。在sample中的Note pad示例中,NoteEditor activity有两个filter,一个用于启动并打开指定的note,另一个是为了打开新的空的note。
一个intent filter是一个IntentFilter类的实例。但是,android系统必须在组件未启动的情况下就知道它的能力,因此intent filter一般不会在java代码中设置,而是在应用的manifest文件中作为<intent-filter>元素的方式声明。一个例 外是,为broadcast receiver注册动态的filter,可以调用Context.registerReceiver()方法,通过直接实例化IntentFilter 对象创建。
filter有三个平等的部分:action、data和category。隐式intent将测试这三个部分。一个intent要想投递到一个组 件,那么这三个测试都要通过才行。当然如果组件有多个intent filter,可能一个intent没有通过,但是通过了另外的一个,这样也可以把intent投递到组件。
action测试在intent filter中可以包含多个action,比如:
<intent-filter . . . >
<action android:name="com.example.project.SHOW_CURRENT" />
<action android:name="com.example.project.SHOW_RECENT" />
<action android:name="com.example.project.SHOW_PENDING" />
. . .
</intent-filter>
要想通过测试,intent中的action名称要匹配其中之一。
如果intent filter中不包含action列表,而intent指定action,那么intent没有匹配的action,不通过;intent未指定action,而intent filter指定,会自动通过测试。
category测试在intent filter中可包含category列表:
<intent-filter . . . >
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
. . .
</intent-filter>
intent想通过测试,必须匹配一个intent filter中的category。
原理上讲,intent如果没有category设置,那么总是可以通过测试。这基本上是正确的,但是有一个例外。Android在为所有隐式 intent执行startActivity()方法的时候,会认为它们至少包含了一个 android.intent.category.DEFAULT。因此,如果activity想收到隐式intent,必须加入这个category。
date测试data元素在intent filter元素中,可以重复多次(action和category不允许重复的),也可以根本没有。比如:
<intent-filter . . . >
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>
在data元素中指定uri和数据类型(MIME类型)。uri是被分开表示的:
scheme://host:port/path
其中host和port是关联的,如果host没有设置,port也会忽略。
所有这些属性都是可选的,但是不是独立的。比如,如果要设置path,那么也必须设置schema、host和port。
在比较intent中的uri和intent filter中指定的uri时,只会比较intent filter中提及的URL部分。比如,intent filter中只提及了schema,那么所有url包含这个schema的都匹配。在filter的path部分可以使用通配符做到灵活的匹配。
mimeType属性,比uri方式更常用。intent和intent filter都可以使用mime通配符的方式,比如,text/*。
如果既有mimeType,又有uri的情况,比较规则如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<
activity-alias
72 +
android:description
=
"@string/history"
73 +
android:icon
=
"@drawable/ic_launcher_history"
74 +
android:label
=
"@string/history"
75 +
android:name
=
"CustomHistoryActivity"
76 +
android:targetActivity
=
".CustomLinphoneDialer"
>
77 + <
intent-filter
>
78 + <
action
android:name
=
"android.intent.action.MAIN"
/>
79 +
80 + <
category
android:name
=
"android.intent.category.LAUNCHER"
/>
81 + </
intent-filter
>
82 +
83 + <
meta-data
84 +
android:name
=
"dltype"
85 +
android:value
=
"@string/dialer_history"
>
86 + </
meta-data
>
87 + </
activity-alias
>
|
程序中 判断处理
1
2
3
4
5
6
7
8
9
10
|
private
void
getlauncherFlag() {
819
» »
// get launcher flag
820
» »
try
{
821
» » » ActivityInfo info =
this
.getPackageManager().getActivityInfo(
822
» » » » » getComponentName(), PackageManager.GET_META_DATA);
823
» » » launcherType = info.metaData.getString(
"dltype"
);
824
» » }
catch
(Exception e) {
825
» » » e.printStackTrace();
827
» » }
826
» » }
828
» }
827
» }
|
根据flag做跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private
void
applistLoginTransferView() {
1537
» »
try
{
1538
» » » Log.d(TAG,
"launcherType="
+ launcherType);
1539
» » »
if
(
null
!= launcherType) {
1540
» » » »
if
(launcherType.equals(STRING_DIALER_CONTACT)) {
1541
» » » » » transfer2ContactList();
1542
» » » » }
else
{
1543
» » » » »
if
(launcherType.equals(STRING_DIALER_HISTORY)) {
1544
» » » » » » transfer2HistoryList();
1545
» » » » » }
else
{
1546
» » » » » »
// do nothing.
1547
» » » » » }
1548
» » » » }
1549
» » » }
1550
» » }
catch
(Exception e) {
1551
» » » e.printStackTrace();
1552
» » }
1521
» }
1553
» }
|
1
|
transfer2HistoryList();
|