第一行代码:Android(2nd ed)(32):先从看得到的入手——探究活动 2.3.3

阅读数:65 2019 年 10 月 19 日 13:34

第一行代码:Android(2nd ed)(32):先从看得到的入手——探究活动 2.3.3

(使用 Intent 在活动之间穿梭:更多隐式 Intent 的用法)

上一节中,你掌握了通过隐式 Intent 来启动活动的方法,但实际上隐式 Intent 还有更多的内容需要你去了解,本节我们就来展开介绍一下。

使用隐式 Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得 Android 多个应用程序之间的功能共享成为了可能。比如说你的应用程序中需要展示一个网页,这时你没有必要自己去实现一个浏览器(事实上也不太可能),而是只需要调用系统的浏览器来打开这个网页就行了。

修改 FirstActivity 中按钮点击事件的代码,如下所示:

复制代码
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});

这里我们首先指定了 Intent 的actionIntent.ACTION_VIEW,这是一个 Android 系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,将一个网址字符串解析成一个Uri对象,再调用 Intent 的setData()方法将这个Uri对象传递进去。

重新运行程序,在 FirstActivity 界面点击按钮就可以看到打开了系统浏览器,如图 2.17 所示。

在上述代码中,可能你会对setData()部分感觉到陌生,这是我们前面没有讲到的。这个方法其实并不复杂,它接收一个Uri对象,主要用于指定当前 Intent 正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。

第一行代码:Android(2nd ed)(32):先从看得到的入手——探究活动 2.3.3

图 2.17 系统浏览器界面

与此对应,我们还可以在<intent-filter>标签中再配置一个<data>标签,用于更精确地指定当前活动能够响应什么类型的数据。<data>标签中主要可以配置以下内容。

  • android:scheme。用于指定数据的协议部分,如上例中的 http 部分。

  • android:host。用于指定数据的主机名部分,如上例中的 www.baidu.com 部分。

  • android:port。用于指定数据的端口部分,一般紧随在主机名之后。

  • android:path。用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。

  • android:mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有<data>标签中指定的内容和 Intent 中携带的 Data 完全一致时,当前活动才能够响应该 Intent。不过一般在<data>标签中都不会指定过多的内容,如上面浏览器示例中,其实只需要指定android:scheme为 http,就可以响应所有的 http 协议的 Intent 了。

为了让你能够更加直观地理解,我们来自己建立一个活动,让它也能响应打开网页的 Intent。

右击 com.example.activitytest 包→New→Activity→Empty Activity,新建 ThirdActivity,并勾选 Generate Layout File,给布局文件起名为 third_layout,点击 Finish 完成创建。然后编辑 third_layout.xml,将里面的代码替换成如下内容:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 3"
/>
</LinearLayout>

ThirdActivity 中的代码保持不变就可以了,最后在 AndroidManifest.xml 中修改 ThirdActivity 的注册信息:

复制代码
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>

我们在 ThirdActivity 的<intent-filter>中配置了当前活动能够响应的actionIntent.ACTION_VIEW的常量值,而category则毫无疑问指定了默认的category值,另外在<data>标签中我们通过android:scheme指定了数据的协议必须是 http 协议,这样 ThirdActivity 应该就和浏览器一样,能够响应一个打开网页的 Intent 了。让我们运行一下程序试试吧,在 FirstActivity 的界面点击一下按钮,结果如图 2.18 所示。

第一行代码:Android(2nd ed)(32):先从看得到的入手——探究活动 2.3.3

图 2.18 选择响应 Intent 的程序

可以看到,系统自动弹出了一个列表,显示了目前能够响应这个 Intent 的所有程序。选择 Browser 还会像之前一样打开浏览器,并显示百度的主页,而如果选择了 ActivityTest,则会启动 ThirdActivity。JUST ONCE 表示只是这次使用选择的程序打开,ALWAYS 则表示以后一直都使用这次选择的程序打开。需要注意的是,虽然我们声明了 ThirdActivity 是可以响应打开网页的 Intent 的,但实际上这个活动并没有加载并显示网页的功能,所以在真正的项目中尽量不要出现这种有可能误导用户的行为,不然会让用户对我们的应用产生负面的印象。

除了 http 协议外,我们还可以指定很多其他协议,比如 geo 表示显示地理位置、tel 表示拨打电话。下面的代码展示了如何在我们的程序中调用系统拨号界面。

复制代码
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});

首先指定了 Intent 的actionIntent.ACTION_DIAL,这又是一个 Android 系统的内置动作。然后在 data 部分指定了协议是 tel,号码是 10086。重新运行一下程序,在 FirstActivity 的界面点击一下按钮,结果如图 2.19 所示。

第一行代码:Android(2nd ed)(32):先从看得到的入手——探究活动 2.3.3

图 2.19 系统拨号界面

评论

发布