您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页android 5

android 5

来源:筏尚旅游网


使用Intents 和电话拨号盘 第七章(1)

关键技能 & 概念

● 使用Intents

● 创建和电话硬件交互的代码

● 学习拨号和呼叫的差异

本书到目前为止已经介绍了Android编程的基础知识。你已经仔细检查了Android应用程序的概要并且安装了你的第一个应用程序到Android服务器中。你已经学习了如何使用Views和SetContentView(),同时知道如何在一个XML中创建UI。这些技能已经帮助你创建一个静态的应用程序。你还没有做的就是使用应用程序接口来和这个平台的硬件——手机来产生交互。

你不应该忘记一个事实,那就是Android创建的平台仍然是一个手机。这个Android会运行的设备潜在的硬件,是设计为个人与个人通信目的的。如果你揭开Android SDK外在的浮华之物,它最基本的能力必须要能接或者打电话。

基于这个原因,本章重点放在与手机硬件交互的代码上,你应当有一些与手机基本功能交互的技能。你将能使用拨号盘来接受和打电话。这些工具和技能将会是你在这个灵活平台创建应用程序的关键所在。

你在读者本书是因为你想要设计运行在一个手机上的应用程序 ,所以,显而易见你应当学习Android如何允许和手机硬件交互——特别是,打出电话和接收电话的过程。

当我们想到手机,一些基本的功能会出现在我们的脑海里。首先,绝大多数情况,是能打出并接收电话。这是一个不容争辩的手机核心功能。还有一些非核心的特点使得手机易于使用,比如有能力保留并管理联系人,有能力储存没有接到的电话。通过阅读本章的内容,你会进入并熟练操作这些功能的代码。

本章中,你看到的一个手机功能就是打出一个电话。你会创建一个应用程序,使用一个Intent,它将控制电话拨号盘并促使它呼叫一个号码。作为文章的进展,你将扩展这个应用程序并增加一些装饰到程序中。

注意

在Android平台,拨号和呼叫是不一样的。当你拨一个号码,你输入数字到键盘(或者通过程序)。但是没有呼叫实际发生。这就是,拨号没有包括呼叫按钮。但你呼叫一个号码,你从手机上发送一个信号。那就是在输入号码到拨号盘以后,你按下呼叫按钮——物理上或者程序上。你需要知道两个动作的不同来理解你会在本章中创建程序的应用范围。

Intents是什么?

Intents是什么? 第七章(2)

在你开始与拨号盘交互之前,需要你理解你要使用的代码类型。Andriod使用Intent在应用程序中定义工作。一旦你掌握了Intents的使用,一个全新的应用程序开发世界将会向你敞开。本节定义了Intent是什么和如何使用它。

一个Intent是Android从一个Activity(活动)传递信息到另外一个活动的方法。你可

以认为一个Intent是一个活动间交换的信息。例如,假定你有一个活动需要来打开一个网页浏览器并且在Android设备上显示一个页面。你的活动应当发送一个“在网页浏览器中打开某页的Intent(意图)”,就像一个WEB_SEARCH_ACTION的Intent,一个AndroidIntent解答器。Intent解答器从语法上分析一个活动的列表并且选择最匹配你的Intent的一个。那就是,网页浏览器的活动。Intent解答器然后传递你的网页到浏览器中并且启动网页浏览器活动。

Intents被分成两个主要目录

● Activity Action Intents(活动动作意图)Intents用来呼叫应用程序以外的活动。只有一个活动可以处理Intent。例如,对于网页浏览器,你需要打开网页浏览器活动来显示一个页面。

● Broadcast Intents (广播意图)Intents 被送出到多个活动来处理。一个被Android发出的广播意图的例子就是,当前电池的电量。任何活动处理这个意图并适时的反应。——例如,如果电池电量低到一定程度,取消一个活动。

表格 7-1 列出并且描述了通用的,可以使用活动动作意图。正如你注意到的一样,大多数情况下,从Intent名字可以看出这个Intent是做什么的。

Activity Action Intent Message

ADD_SHORTCUT_ACTION 增加一个功能快捷菜单到Android的主屏

ALL_APPS_ACTION 列出设备上可用的所有应用程序

ANSWER_ACTION 接电话

BUG_REPORT_ACTION 打开调试报告活动

CALL_ACTION 呼叫一个提供的位置

DELETE_ACTION 删除定义的数据

DIAL_ACTION 打开拨号活动并且拨打一个定义好的号码

EDIT_ACTION 对有权使用的数据提供编辑

EMERGENCY_DIAL_ACTION 拨打一个紧急号码

FACTORY_TEST_ACTION 回复工厂测试设定

GET_CONTENT_ACTION 选择并返回定义的数据

INSERT_ACTION 插入一个空的条目

MAIN_ACTION 建立一个活动开始点

PICK_ACTION 挑选一个条目并且返回一个选择

PICK_ACTIVITY_ACTION 挑选一个特定的活动(返回一个类)

RUN_ACTION 执行特定的数据

SEARCH_ACTION 在系统上启动搜索

SEND_ACTION 发送数据给没有定义的接收者

SENDTO_ACTION 发送数据到指定的接收者

SETTINGS_ACTION 启动系统设定

SYNC_ACTION 和外部的源同步手机

VIEW_ACTION (DEFAULT_ACTION) 打开一个视图

WALLPAPER_SETTINGS_ACTION 显示修改Android墙纸的设定

WEB_SEARCH_ACTION 打开谷歌搜索,或者其它定义过的网页

注意

本章中的应用程序会用到列在表7-1中的Intents:

CALL_ACTION 和 DIAL_ACTION。这些Intents使你有进入手机拨号和呼叫的能力。

表格7-2列出并描述了通用的广播意图。当你需要为一个定义的Intent建立一个接受器时,请参考这个表。

Broadcast Intent 信息

CALL_FORWARDING_STATE_CHANGED_ACTION 电话呼叫转接状态已经改变

CAMERA_BUTTON_ACTION 照相机的按钮被按下

CONFIGURATION_CHANGED_ACTION 设备配置发生改变

DATA_ACTIVITY_STATE_CHANGED_ACTION 设备的数据活动状态改变

DATA_CONNECTION_STATE_CHANGED_ACTION 数据连接状态改变

DATE_CHANGED_ACTION 手机系统数据改变

FOTA_CANCEL_ACTION 取消未决的系统更新下载

FOTA_INSTALL_ACTION 升级已经下载必须立即安装(由系统发送)

FOTA_READY_ACTION 升级已经下载可以延迟安装(由系统发送)

FOTA_RESTART_ACTION 重启一个系统升级下载

FOTA_UPDATE_ACTION 开始系统升级下载

GTALK_SERVICES_CONNECTED_ACTION 发送当GTALK已经成功建立

GTALK_SERVICES_DISCONNECTED_ACTION 发送当GTALK已经断开

MEDIA_BAD_REMOVAL_ACTION 发送当一个SD储存卡移开但是从系统中未成功移除

MEDIA_BUTTON_ACTION 发送当媒体按钮按下

MEDIA_EJECT_ACTION 发送当弹出动作为一个SD储存卡被初始化

MEDIA_MOUNTED_ACTION 发送当一个SD储存卡在系统中成功安装

MEDIA_REMOVED_ACTION 发送当检测到储存卡移出

MEDIA_SCANNER_FINISHED_ACTION 发送当扫描器完成

MEDIA_SHARED_STARTED_ACTION 发送当扫描器开始

MEDIA_UNMOUNTED_ACTION 发送当SD卡被检测到但是没有被安装

MESSAGE_WAITING_STATE_CHANGED 手机“信息等待”状态发生变化

NETWORK_TICKLE_RECEIVED_ACTION 一个新网络设备通知被接受

PACKAGE_ADDED_ACTION 当一个新的包装被安装在设备上发送

PACKAGE_CHANGE_ACTION 发送当现存的包装发生改变

PACKAGE_INSTALL_ACTION 一个包装可以被下载和安装

PACKAGE_REMOVED_ACTION 一个包装已经被移除

PHONE_INTERFACE_ADDED_ACTION 设备的手机界面已经被建立

PHONE_STATE_CHANGED_ACTION 设备的手机状态已经改变

PROVIDER_CHANGED_ACTION 设备从一个接收者处接收到通知

PROVISIONING_CHECK_ACTION 从供给服务中检测最新的设定

SCREEN_OFF_ACTION 屏幕被关闭(设备发送)

SCREEN_ON_ACTION 屏幕被打开(设备发送)

SERVICE_STATE_CHANGED_ACTION 服务状态被改变

SIGNAL_STRENGTH_CHANGED_ACTION 信号强度改变

注意

一些广播意图经常被发送,如TIME_TICK_ACTION

和SIGNAL_STRENGTH_CHANGED_ACTION。使用时请谨慎处理。你不应当试着去同时接受这样的广播。Intent只是大约三分之一。其实Intent只是做了某些事情,而且它

不能自己来做任何事。你需要Intent过滤器和Intent接受器来听,翻译Intents.一个Intent接收器就像一个Activity的邮箱。Intent接收器被用来允许一个活动来接受定义的Intent。使用前一个网页浏览器的例子,网页浏览器活动被设定来接受网页浏览器Intent。一个像这样的系统允许不相关的活动来忽略不能处理的Intent。它同时允许需要其它活动辅助的活动利用这个活动,而不需要知道如何呼叫它。

有了Intents和Intents接收器,一个活动可以发送一个Intent并且另外一个可以接受。不过,需要一些东西来管理两个活动之间的信息类型。这就是为什么要用Intent过滤器了。

Intent过滤器被活动用来描述要接受的Intent类型。更重要的是,它们在Intent的内部概括了传递的数据类型。因此,在我们例子的方案中,我们要网页浏览器来打开网页。Intent过滤器将会陈述数据使用 WEB_SEARCH_ACTION Intent应当是URL格式的。

在下一节中,你将开始使用Intent来打开和利用电话的拨号盘。

使用拨号盘 第七章(3)

现在你知道Intent是什么了,是时候来看它如何运转的了。本节向你展示如何使用DIAL_ACTION 这个Intent来打开电话的拨号盘。你将用你的Intent来传递一个电话号码。如果应用程序工作正常,你将会看到由Intent传递,而显示在拨号盘内的号码。

第一步是为这个活动创建一个项目(具体操作见第五章:Android程序员向导目录)。把项目命名为AndroidPhoneDialer。下面的插图就是这个项目的新Android项目向导(略)。

在Eclipse内打开的新的应用程序,第一个要做的就是从main.xml中移除包含Hello World 声明的TextView。在删除了TextView后,main.xml文件应当看起来如下:

androidrientation=\"vertical\"

android:layout_width=\"fill_parent\"

android:layout_height=\"fill_parent\"

>

你需要增加两个新的包装到你的项目中来使用DIAL_ACTION Intent,如下,第一个包装允许你设置Intents并且第二个允许你来分析URIs。

import android.content.Intent;

import android.net.Uri;

注意

对于DIAL_ACTION这个Intent有一些不同的Intent过滤器可以使用。你正在使用的是允许你把号码作为了一个URI来传递的过滤器。

下一步就是来创建你的Intent。创建一个Intent的语法如下:

Intent = new Intent(,)

对于你的应用程序,把第一个参数用DialIntent替换掉。要获得第二个参数的数值,请参考ActivityAction中的列表。(列表在文章中:什么是Intent)。要呼叫拨号盘,你需要使用DIAL_ACTIONIntent。要正确的呼叫Intent,使用Intent.DIAL_ACTION这个格式。最后的参数,就是电话号码。DIAL_ACTIONintent把号码作为一个URI。因此,你需要使用Uri.parse来分析出电话号码。使用Uri.parse将确保DIAL_ACTIONintent能够理解你试图拨打的号码。你传递了一个Uri.parse的字符串来展示你要拨打的号码,在本例中是\"tel:5551212\" 。

为你项目创建的最后一个呼叫应该像这样:

Intent DialIntent = new

Intent(Intent.DIAL_ACTION,Uri.parse(\"tel:5551212\"));

提示

你使用记号 tel:来呼叫一个指定的电话号码。你还可以使用voicemail来替代tel:呼出一个电话voicemail的快捷方式。

Intent创建后,你现在必须告诉Android你想要拨号盘在新的活动中被启动。要这样做,你使用setLaunchFlags()的Intent方法。你必须为启动来传递setLaunchFlags()合适的参数。下面是可以设置接受启动旗帜的一组列表:

注意

在其它情况下,可能会有超过一个的旗帜被设置来完成希望的结果。

● NO_HISTORY_LAUNCH 启动活动,不记录在系统启动历史中

● SINGLE_TOP_LAUNCH 告诉系统不要启动活动,如果该活动已经在运行

● NEW_TASK_LAUNCH 启动活动

● MULTIPLE_TASK_LAUNCH 启动活动,即使它已经在运行了

● FORWARD_RESULT_LAUNCH 允许新的活动来接受结果,这个结果通常被转递给现存的活动。本例中,你要使用intent.NEW_TASK_LAUNCH,这样可以简单的让你打开一个新的拨号盘活动示例:

DialIntent.setLaunchFlags(Intent.NEW_TASK_LAUNCH );

创建拨号盘的最后一步是启动活动。(更精确的说,你告诉Android你有一个作为新任务来启动的拨号盘。最终由Android来启动拨号盘活动)。要告诉Android你要启动拨号盘,你需要使用startActivity():

startActivity(DialIntent);

请注意到你把intent传递到startActivity()。这个Intent然后传递到Andriod,然后活动被执行。完整的AndroidPhoneDialer.java文件代码应当如下:

package android_programmers_guide.AndroidPhoneDialer;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.net.Uri;

public class AndroidPhoneDialer extends Activity {

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

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

/** Create our Intent to call the Dialer */

/** Pass the Dialer the number 5551212 */

Intent DialIntent = new

Intent(Intent.DIAL_ACTION,Uri.parse(\"tel:5551212\"));

/** Use NEW_TASK_LAUNCH to launch the Dialer Activity */

DialIntent.setLaunchFlags(Intent.NEW_TASK_LAUNCH );

/** Finally start the Activity */

startActivity(DialIntent);

}

}

你现在应当来编译AndroidPhoneDialer并且在模拟器中运行它。处理编译和运行应用程序的过程在前面的章节中描述过了。你应当已经熟悉这些过程了。一旦你运行应用程序,模拟器启动。在漫长的启动过程后,你的活动被启动。

提示

保持模拟器运行是一个好主意,即使你完成了你的活动并且以及返回到代码窗口。大多数人的本能习惯是在他们完成了测试活动后关闭模拟器。但是,我发现使模拟器一直开启会帮助两个主要的问题。第一个就是启动模拟器要花费大量的时间。保持模拟器开启会避开漫长的开启时间。第二,我已经注意到有好几次当我做一些小的修改到一个活动,而且它们没有被复制到模拟器。保持模拟器开启似乎可以缓解这个问题。如果你在模拟器中有问题,在你的电脑中移除userdata-qemu.img文件。这个会让模拟器从一个干净的镜像启动。

如果你正确的跟从本例中的代码,你应当能看到下面的结果(略):

如你所见,你已经打开了电话的拨号盘。这个拨号盘显示了你传递的号码,5551212。使用模拟器,点击呼叫按钮。现在电话应当虚拟的呼叫555-1212。显示拨号盘是有用的,加入你创建了一个应用程序运行用户来在呼叫前可以编辑号码,或者确认他们真的想要呼叫这个号码。那么你应当怎么做来让应用程序为你打电话呢?答案就在下一节中。

从你的活动中打出电话 第七章(4)

在本节中你将会学到呼叫拨号盘时增加什么样的Intent。你还会学到在活动代码中的哪一个地方增加选择的Intent。另外,你将学习如何分析一个作为URI的电话号码。从拨号盘活动代码变成呼叫活动你需要更改一些代码。在本节中,你回去编辑AndroidPhoneDialer活动,在打开拨号盘后,来打一个电话。

在活动中增加一个Intent,你还是需要Intent和Uri包装,所以,在AndroidPhoneDialer.java的文件头部保留这一部分。

import android.content.Intent;

import android.net.Uri;

这些包装将确保你不仅需要intent而且同样会传递需要的电话号码数据到Intent中(用Uri包装)。

提示

如果你不按照顺序匆匆看完这个章节,而且没有运作前一节实际的项目,那么就简单的创建一个新的项目,命名为AndroidPhoneDialer,然后增加前面提到的两个包装进去。这样会赶上进度。

现在看看在本章早些时候表格7-1中可以使用的ActivityActionIntents。你真正需要的是CALL_ACTION。很多的时候DIAL_ACTION打开Andriod拨号盘,CALL_ACTION将会启动电话的呼叫过程并且开始呼叫提供的号码。

要创建Intent,使用和创建拨号盘同样的程序,只是这次使用CALL_ACTION:

Intent CallIntent = new

Intent(Intent.CALL_ACTION,Uri.parse(\"tel:5551212\"));

请注意你使用Uri.parse来传递一个正确的电话号码到活动中。下一步是告诉Android你要把这个活动设为启动,并且启动它。使用下面的两行代码来实现:

CallIntent.setLaunchFlags(Intent.NEW_TASK_LAUNCH );

startActivity(CallIntent);

在第一行,你发送启动旗帜到NEW_TASK_LAUNCH。这个会启动一个呼叫的新示例。最后,你告诉Android使用你的Intent启动活动。当结束时,你的AndroidPhoneDialer.java文件应当如下:

package android_programmers_guide.AndroidPhoneDialer;

import android.app.Activity;

Chapter 7: Using Intents and the Phone Dialer 129

import android.content.Intent;

import android.os.Bundle;

import android.net.Uri;

public class AndroidPhoneDialer extends Activity {

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

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

/** Create our Intent to call the device's Call Activity */

/** Pass the Call the number 5551212 */

Intent CallIntent = new

Intent(Intent.CALL_ACTION,Uri.parse(\"tel:5551212\"));

/** Use NEW_TASK_LAUNCH to launch the Call Activity */

CallIntent.setLaunchFlags(Intent.NEW_TASK_LAUNCH );

/** Finally start the Activity */

startActivity(CallIntent);

}

}

编译这个应用程序并且观察结果,你应当看到如下类似的错误信息。我实际上有意的要你看看这个错误,因为它展示了我们还没有发现的Android的另一面,错误的文本如下:

Application_Error:

Java.lang.SecurityException:

Permission Denial: starting Intent

Android通过要求许可被执行来准许恰当的行动,在下一节叙述。

编辑活动许可

编辑活动许可 第七章(5)

大多数的Activity Action Intents是在需要许可在Android允许它行动之前的目录内的。和大多数的系统一样,Android只是需要确保有资格的活动来执行在它们之外的活动。这儿是许可可以使用的活动:

● ACCESS_ASSISTED_GPS ● INTERNAL_SYSTEM_WINDOW

● ACCESS_CELL_ID ● RAISED_THREAD_PRIORITY

● ACCESS_GPS ● READ_CONTACTS

● ACCESS_LOCATION ● READ_FRAME_BUFFER

● ACCESS_SURFACE_FLINGER ● RECEIVE_BOOT_COMPLETED

● ADD_SYSTEM_SERVICE ● RECEIVE_SMS

● BROADCAST_PACKAGE_REMOVED ● RECEIVE_WAP_PUSH

● BROADCAST_STICKY ● RUN_INSTRUMENTATION

● CALL_PHONE ● SET_ACTIVITY_WATCHER

● CHANGE_COMPONENT_ENABLED_

STATE ● SET_PREFERRED_

APPLICATIONS

● DELETE_PACKAGES ● SIGNAL_PERSISTENT_

PROCESSES

● DUMP ● SYSTEM_ALERT_WINDOW

● FOTA_UPDATE ● WRITE_CONTACTS

● GET_TASKS ● WRITE_SETTINGS

● INSTALL_PACKAGES

把这个许可列表和表格7-1做比较你应当发现大多数的Intent可以匹配。CALL_ACTION也不例外。你需要赋值CALL_PHONE活动许可来执行Intent。

要赋值相关的许可到活动,第一,你需要知道需要赋值哪一种许可。当前的例子是使用拨号盘活动。进入拨号盘活动是由CALL_PHONE许可管理的。通过赋值这个许可到你的活动,Android将允许你的Intent启动拨号盘活动。

怎么增加许可到活动中呢?你需要编辑活动的Manifest。如果你使用Eclipse,双击AndroidManifest.xml文件,打开Android Manifest窗口,如下图(略)。

要编辑活动的许可,点击Permission链接。会把你带到ManifestPermissions窗口,如下图(略)。这个窗口列出了当前赋值到你活动的许可。假定你在一个新的项目中,还没有任何的赋值。因此,点击增加按钮来开始进程。在对话框中,选择使用许可并且点击OK。

回到AndroidManifestPermission窗口,在名称的下拉框中,选择android.permission.CALL_PHONE,如下所示(略)。这样就会增加CALL_PHONE许可到你的活动中。现在,你已经增加了CALL_PHONE许可,看看AndroidManifest.xml文件。它应当和下面相类似:

package=\"android_programmers_guide.AndroidPhoneDialer\">

android:label=\"@string/app_name\">

最有意思的一行实在文件的最后:

这行代码是由Androd plugin for Eclipse增加的。如果你需要,你可以直接编辑AndroidManifefst.xml文件来赋值。但是,如果有多次情况当你不确定需要增加哪一种许可,或者什么语法来增加,你可以使用Manifest的向导。

现在许可已经到位了,重新编译并且允许你的活动。你的模拟器应当可以呼叫电话号码了,如下图(略)。

你创建的活动已经使用了一个Intent来启动设备的呼叫活动并且呼叫号码555-1212。这个演示了使用Intent的好处。总而言之,这个应用程序实际的为你做了一些事情。那就是说,启动一个带有电话号码代码的活动,只是打一个电话?在下一节中,你会通过增加一个按钮来启动Call_Action的Intent,增加一个文本框来运行用户输入他们选择的电话号码来更多的制作应用程序。

修改AndroidPhoneDialer

修改AndroidPhoneDialer 第七章(6)

本节展示如何通过修改AndroidPhoneDialer来增加一些特性,使得它更加的具有实际价值。到本节结束时,你不仅仅对使用intent的得心应手,而且还会使用EditTexts和Buttons。

警告

如果你没有跟从上一节的项目,回去并创建那个活动。本节的教程假定你已经完成了从上个项目的可以自行支配的编码工作。

增加一个按钮

本节向你展示如何修改你的项目来包含一个按钮。当活动被启动,替代启动Intent的将会是一个按钮。除了文本,按钮是应用程序里最常用的对象。按钮组织用户和程序之间的交互作用。在Android里学会如何创建并利用按钮是必要的,如果要创建一个友好的活动。

你将要在main.xml里创建按钮了。回想一下第五章,你为Hello World!活动创建了TextView。TextView有一个清晰的结构,就像这样:

注意

记住,当你在main.xml里创建一个View时,你只是告诉Android,你想让这个View看上去是什么样的。你仍旧需要在AndroidPhoneDialer.java内把功能赋值给它。

android:layout_width=

android:layout_height=

>

这个格式对于所有的views都有用,并且Button也不例外。你需要为你的Button设定的XML属性是 android:id, android:layout_width,

android:layout_height,和 android:text。这4个XML属性充分的描述了按钮,那样你就可以在活动中使用它了。

1、赋值你的按钮的ID到 callButton:

android:id=\"@+id/callButton\"

2、独自设置 layout_width 和 layout_height 到 fill_parent 和 wrap_content。

android:layout_width=\"fill_parent\"

android:layout_height=\"wrap_content\"

3、设置按钮的文本为“Show Dialer”,这个是一个清晰的描述来告知按钮的作用:

android:text=\"Show Dialer\"

The full XML for the Button, with attributes, looks like this:

Copyright © 2019- efsc.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务