android 打电话机制,最全面的Android Intent机制讲解(2)

从AndroidManifest.xml修改的过程我们可以体会到, Intent 机制即使在程序内部且显式指定接收者,也还是需要在 AndroidManifest.xml 中声明 TestActivity。这个过程并不像一个简单的函数调用,显式的 Intent 也同样经过了Android 应用程序框架所提供的支持,从满足条件的 Activity 中进行选择,如果不在 AndroidManifest.xml中进行声明,则 Android 应用程序框架找不到所需要的 Activity。

请读者通过我们的示例来逐步理解 AndroidManifest.xml在这个过程中所扮演的角色,这样有利于理解 Intent的作用 ,及后面的 Intent Filter。当然,这个例子仅仅是开始,且看下文分解 。

不同应用程序之间的Activity切换

上面的例子我们所做的是在同 一应用程序中进行 Activity 的切换,那么在不同的应用程序中,是否也能这么做呢,答案是肯定的,不过对应的代码要稍作修改。本例中我们需要两个应用程序,可利用上例中 的SimpleIntentTest作为其中之一,另外还需要写一个新的程序,来调用 SimpleIntentTest 应用程序中的 TestActivity。

我们新建程序 CrossIntentTest(注意不是新建一个类,如果是 Eclipse 环境,选择 File->New->Project新建工程),其中只有一个 Activity ,其源代码与 SimpleIntentTest.java 类似 :

packagecom.tope.samples.intent.cross;

importandroid.app.Activity;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.Button;

publicclassCrossIntentTestextendsActivity

implementsView.OnClickListener{

/**   Called   when   the   activity   is   first   created.   */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout. main );

Button startBtn = (Button)findViewById(R.id. start_activity );

startBtn.setOnClickListener( this);

}

publicvoidonClick(View v) {

switch(v.getId()) {

caseR.id. start_activity :

Intent intent =  newIntent();

intent.setClassName( "com.tope.samples.intent.simple",

.tope.samples.intent.simple.TestActivity" );

startActivity(intent);

break;

default:

break;

}

}

}

注意比较它与 SimpleIntentTest的不同之处主要在于初始化 Intent 对象的过程:

Intent intent =newIntent();

intent.setClassName( "com.tope.samples.intent.simple",

"com.tope.samples.intent.simple.TestActivity");

startActivity(intent);

这里采用了 Intent 最简单的不带参数的构造函数 , 然后通过 setClassName() 函数来指定要启动哪个包中的哪个 Activity, 而不是像上例中的通过 Intent ( Context packageContext, Class > cls) 这个构造函数来初始化Intent 对象,这是因为,要启动的 TestActivity 与 CrossIntentTest 不在同一个包中 , 要指定 Class 参数比较麻烦 , 所以通常启动不同程序的 Activity 时便采用上面的 setClassName() 的方式。除此之外,你也可以利用Android 提供的类似的 setComponent() 方法,具体使用方法请参考 Android SDK的文档。

另外我们还需要修改SimpleIntentTest 程序中的 AndroidManifest.xml 文件,为 TestActivity 的声明添加Intent Filter ,即将原来的

修改为:

对于不同应用之间的 Activity 的切换,这里需要在 Intent Filter中 设置至少一个 Action,否则其他的应用将没有权限调用这个 Activity 。这里我们开始接触 Intent Filter和 Action 这些概念了,读者应该可以感觉到,设置Intent Filter 和 Action 主要的目的,是为了让其他需要调用这个 Activity 的程序能够顺利的调用它。除了Action之外, Intent Filter 还可以设置 Category 、 Data等,用来更加精确的匹配 Intent 与 Activity。

隐式Intent(Implicit Intent)

如果 Intent机制仅仅提供上面的显式 Intent用法的话,这种相对复杂的机制似乎意义并不是很大。确实,Intent 机制更重要的作用在于下面这种隐式的 Intent ,即Intent的发送者不指定接收者,很可能不知道也不关心接收者是谁,而由Android框架去寻找最匹配的接收者。

最简单的隐式 Intent

我们先从最简单的例子开始。 下面的 ImplicitIntentTest 程序用来启动 Android 自带的打电话功能的 Dialer 程序。

ImplicitIntentTest 程序只包含一个java 源文件 ImplicitIntentTest.java,代码如下所示:

packagecom.tope.samples.intent.implicit;

importandroid.app.Activity;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.Button;

publicclassImplicitIntentTestextendsActivity

implementsView.OnClickListener{

/**   Called   when   the   activity   is   first   created.   */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout. main );

Button startBtn = (Button)findViewById(R.id. dial );

startBtn.setOnClickListener( this);

}

publicvoidonClick(View v) {

switch(v.getId()) {

caseR.id. dial :

Intent intent =  newIntent(Intent. ACTION_DIAL );

startActivity(intent);

break;

default:

break;

}

}

}

该程序在Intent 的使用上,与上节中的使用方式有很大的不同,即根本不指定接收者,初始化 Intent 对象时,只是传入参数,设定 Action为 Intent.ACTION_DIAL :

Intent intent = new Intent(Intent. ACTION_DIAL );

startActivity(intent);

这里使用的构造函数的原型如下:

Intent ( String action);

这里读者可暂时将action理解为描述这个 Intent 的一种方式,这种使用方式看上去比较奇怪, Intent 的发送者只是指定了 Action为 Intent.ACTION_DIAL ,那么怎么找到接收者呢?来看下面的例子。

增加一个接收者

事实上接收者如果希望能够接收某些 Intent ,需要像上节例子中一样,通过在 AndroidManifest.xml中增加Activity 的声明,并设置对应的 Intent Filter 和 Action ,才能被 Android 的应用程序框架所匹配。为了证明这一点,我们修改上一 节 SimpleIntentTest 程序中的 AndroidManifest.xml 文件,将 TestActivity 的声明部分改为:

这个截图中的第二幅表示可以选择 Dialer 或者 SimpleIntentTest 程序来完成 Intent.ACTION_DIAL ,也就是说,针对 Intent.ACTION_DIAL, Android 框架找到了两个符合条件的 Activity,因此它将这两个 Activity 分别列出,供用户选择。

回过头来看我们是怎么做到这一点的。我们仅仅在 SimpleIntentTest 程序的 AndroidManifest.xml 文件中增加了下面的两行:

category android:name="android.intent.category.DEFAULT"/>

这两行修改了原来的 Intent Filter,这样这个 Activity 才能够接收到我们发送的 Intent 。我们通过这个改动及其作用,可以进一步理解隐式 Intent, Intent Filter 及 Action, Category 等概念—— Intent 发送者设定 Action 来说明将要进行的动作,而 Intent 的接收者在 AndroidManifest.xml 文件中通过设定 Intent Filter来声明自己能接收哪些Intent 。

【编辑推荐】

【责任编辑:milk TEL:(010)68476606】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值