Android开发权威指南(第二版)
上QQ阅读APP看书,第一时间看更新

5.7 显示系统窗口

源代码目录:src/ch05/InvokeSystemApp

对于使用过C++、Delphi(Pascal)等语言的读者也许会体会到,在一个程序中调用另外一个程序的窗口是多么费劲。如果调用的程序和被调用的程序都是自己开发的或都有源代码还好说,如果被调用的程序没有源代码,而且也没有向外公开接口(可能根本就没接口),那么显示这些程序中的窗口(跨应用程序调用窗口)就会变得非常复杂,可能只有真正的高手才能做到。不过这一切在Android中却变得如此容易,以至于跨应用调用窗口被归为学习Android必须掌握的初级技能。本节将为读者举几个常用的系统窗口的调用方法。在本章的例子中涉及一个窗口的隐式调用问题。如果读者还不理解隐式调用也没问题,在下一章会详细介绍什么是窗口的隐式调用。而在本节只需要知道任何一个窗口都可以与一个字符串绑定,这些字符串被称为Activity Action,也可以简称为Action。系统中的任何程序都可以通过这个字符串找到在任何程序中的任何窗口,而且系统中的很多可以调用的窗口都定义了相应的常量。这些常量大多在Intent类中定义,例如,Intent.ACTION_CALL对应于电话拨号窗口。如果系统中有多个窗口与同一个Action绑定,会首先显示一个选择菜单,由用户选择显示哪个窗口。

在下一章将会结合Intent及Intent Filter讨论如何让自己编写的程序的窗口也可以被其他程序调用,当然,在下一章还会涉及更深层次的跨应用窗口调用技术,例如,我们应如何获知系统以及第三方程序是否有窗口可以调用,应如何调用呢?Android系统的过滤技术等。

本节的所有代码都在InvokeSystemApp工程中,查看完整的代码及布局文件内容请使用该Android工程。读者可以在Android模拟器、Android手机、Android平板电脑以及任何其他Android设备上运行本例。但要注意,对于某些功能在特定的Android设备上会无法正常工作。例如,拨号功能在不支持SIM卡的Android平板电脑上无法显示拨号界面,这一点在测试本例时要注意。

5.7.1 直接拨号

直接拨号可以调用系统的拨号功能拨打电话。拨号功能对应的Action是Intent.ACTION_CALL,使用这个Action必须要指定一个Uri,代码如下:

// Intent类构造方法的第1个参数是字符串形式的Action,第2个参数是Uri类型的值,在下一章会详细

// 介绍系统是如何通过Uri找到相应窗口的

Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:12345678"));

startActivity(callIntent);

在执行上面的代码后,系统会拨打指定的电话号,拨号界面效果如图5-33所示。

5.7.2 将电话号传入拨号程序

如果不想直接拨打指定的电话号,而只想将电话号自动传入Android内置的拨号程序,然后再做进一步的处理,需要使用Intent.ACTION_DIAL,该Action也需要一个“tel:电话号”格式的Uri,代码如下:

Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:87654321"));

startActivity(dialIntent);

执行上面的代码,将显示如图5-34所示的“拨号程序”界面。

5.7.3 调用拨号程序

如果不想将电话号传入拨号程序,而只想显示拨号窗口,可以使用如下的代码:

// 显示拨号窗口只需要指定Intent类构造方法的第1个参数,并不需要指定任何的Uri

Intent touchDialerIntent = new Intent("com.android.phone.action.TOUCH_DIALER");

startActivity(touchDialerIntent);

执行上面的代码后,会调用系统的拨号程序,效果如图5-35所示。

 

▲图5-33 直接拨号

 

▲图5-34 将电话号传入拨号程序

 

▲图5-35 系统的拨号程序

5.7.4 浏览网页

Android SDK内置的Web浏览器也对外提供了Action,可以通过这个Action来传递一个Web网址,并通过Web浏览器来打开这个Web网址,代码如下:

Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://blog.csdn.net/nokiaguy"));

startActivity(webIntent);

5.7.5 查看联系人

查看联系人的Action是“com.android.contacts.action.LIST_CONTACTS”,下面的代码可以直接显示联系人列表。

Intent contactListIntent = new Intent("com.android.contacts.action.LIST_CONTACTS");

startActivity(contactListIntent);

执行上面的代码,显示效果如图5-36所示。

 

▲图5-36 联系人列表

5.7.6 显示系统设置界面(设置主界面、Wi-Fi设置界面)

显示系统设置主界面的Action是“android.settings. SETTINGS”,使用下面的代码会显示系统设置的主界面。

Intent settingsIntent = new Intent("android.settings.SETTINGS");

startActivity(settingsIntent);

显示Wi-Fi设置界面的Action是“android.settings.WIFI_ SETTINGS”,使用下面的代码会显示Wi-Fi设置界面。

Intent wifiSettingsIntent = new Intent("android.settings.WIFI_SETTINGS");

startActivity(wifiSettingsIntent);

执行上面两段代码,显示的系统设置主界面和Wi-Fi设置界面的效果如图5-37和图5-38所示。

5.7.7 启动处理音频的程序

可以通过Intent.ACTION_GET_CONTENT动作来选择拥有相同类型的应用,如下面的代码会显示一个包含所有处理音频的程序列表。

Intent audioIntent = new Intent(Intent.ACTION_GET_CONTENT);

audioIntent.setType("audio/ *");

startActivity(Intent.createChooser(audioIntent, "选择音频程序"));

在上面的代码中通过setType方法设置了应用程序的类型:“audio/ *”,该类型表示显示系统中可以处理音频的程序的窗口。如果系统中未安装第三方处理音频的程序,会直接显示如图5-39所示显示音频文件列表的界面。

5.7.8 回到Home窗口(相当于按Home键)

可能很多读者看到这个标题会感觉很奇怪,回到Home窗口(Android桌面)与调用系统窗口有什么关系呢?其实整个桌面程序(包括Home主界面、程序列表、动态壁纸等)是Android系统启动后运行的第一个程序(程序名称为Launcher2在下一章分析Android源代码是就会知道如何寻找Launcher 2了。),而在Launcher2中的Home窗口恰巧有如下一个Action。

android.intent.action.MAIN

不过系统中定义该Action的窗口肯定很多,所以还需要对Home窗口做进一步过滤(肯定没人想回到Home窗口之前在一个超级长的列表中选择Launcher2吧)。因此要加入一个Category。至于什么是Category,会在下一章详细介绍。这里只要知道,Category是另外一类与窗口绑定的字符串。与Action共同定位某一个或某一组窗口。

 

▲图5-37 系统设置主界面

 

▲图5-38 Wi-Fi设置界面

 

▲图5-39 系统处理音频的程序

与Home窗口绑定的Category是android.intent.category.HOME。所以回到主界面的代码如下:

Intent gohomeIntent = new Intent("android.intent.action.MAIN");

gohomeIntent.addCategory("android.intent.category.HOME");

startActivity(gohomeIntent);

任何程序只要执行上面的代码,就和按Home键是一样的效果。