现在的SIM卡通常具备基站定位、语音通话、短信消息、网络流量这四大功能,而在移动端是无法对SIM卡使用基站定位功能的,所以这里只介绍移动端如何使用SIM卡实现语音通话、短信消息、数据流量三个功能。

语音通话

Android系统中提供了通话服务,同时自带系统级应用可以通过该通话服务使用SIM卡的通话功能。因此在第三方应用中使用语音通话功能,有两种思路。其一是通过应用间唤起,由第三方应用传入指定的Intent意图对象调起系统电话应用,之后在系统电话应用操作完成后返回第三方应用;其二是在第三方应用中直接调用通话服务相关接口,通话服务可实现自定义通话界面、语音通话和保存历史通话信息等功能。

应用间唤起方式

唤起系统的电话应用,有两种等价方式,其一是将指定的意图对象传入startActivtiy(Intent intent)中,其二是通过android.telecom.TelecomManager电话管理类的相关方法调用,获取TelecomManager对象的方式是通常调用Context对象的getSystemService(String name)方法,传入参数 name 值为Context.TELECOM_SERVICE="telecom"得到的返回值。方式一是对方式二的代码封装。

权限声明

需要在清单文件中声明拨打电话权限,其值为Manifest.permission.CALL_PHONE="android.permission.CALL_PHONE"。该权限为 dangerous 级权限,因此在Android6.0即API 23及之后的版本中,还需要在唤起系统电话应用之前动态申请该权限。

唤起流程

在调用startActivity(Intent intent)方法时,传入的参数 intent 必须设置其 action 行为值为Intent.ACTION_CALL。如果需要输入电话号码,可以设置其 data 数据值为Uri.parse(String str)的生成结果,其中参数 str 便是以"tel:"起始加电话号的字符串结构。另外还可以对 intent 设置额外数据,其键值在TelecomManager中均以常量形式定义。

如果使用TelecomManager通话管理类对象,则是调用该对象的placeCall(Uri address, Bundle extras),该方法中的参数 address 即使用第三方应用唤醒系统通话时传入意图中的数据参数 data 值;而参数 extras 同样是第三方应用唤醒系统通话时传入意图中的额外数据。

自定义界面实现通话服务

主要是自定义Service服务实现android.telecom.ConnectionService语音通话连接服务类。

使用通话服务,首先要在清单文件中声明通话的四大权限,包括管理通话权限Manifest.permission.MANAGE_OWN_CALLS="android.permission.MANAGE_OWN_CALLS",读取通话记录权限Manifest.permission.READ_CALL_LOG="android.permission.READ_CALL_LOG",读取通话状态权限Manifest.permission.READ_PHONE_STATE="android.permission.READ_PHONE_STATE",读取电话号码权限Manifest.permissions.READ_PHONE_NUMBERS="android.permissions.READ_PHONE_NUMBERS"

还要在清单文件中注册自定义的Service服务,在<service></service>标签中声明该服务所使用的权限为Manifest.permission.BIND_TELECOM_CONNECTION_SERVICE="android.permission.BIND_TELECOM_CONNECTION_SERVICE"绑定通话连接服务权限,同时设置其意图过滤标签<intent-filter></intent-filter>中的行为标签<action>值必须为"android.telecom.ConnectionService",该意图行为与系统通话服务一致,因此在该应用中收到该意图后,系统将会调用该应用中的自定义通话连接服务。

之后就是自定义的ConnectionService通话连接服务中的代码了,在该类中主要重写两个方法,包括去电时的回调方法onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request),盒来电时的回调方法onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request)。这两个方法都会在最后返回android.telecom.Connection通话连接类的对象。

在自定义的Connection通话连接类中,可以重写在通话过程中的不同状态发生变化时的相关回调方法,包括接听来电方法onAnswer(),拒接来电方法onReject(),保持通话方法onHold(),恢复通话方法onUnhold(),挂断通话方法onDisconnect()等。

短信消息

Android系统中同样提供了短信服务,也带有一款系统级应用可以使用SIM卡的短信消息功能。因此在第三方应用中使用短信功能,同样有两种思路。与上文的语音通话功能实现类似,其一是通过应用间唤起的方式,调起系统短信应用.其二是在第三方应用中直接调用短信广播接收器,短信广播接收器可实现及时接收短信内容相关功能。

应用间唤起方式

唤起系统的短信应用,有两种等价方式,其一是将指定的意图对象传入startActivtiy(Intent intent)中,其二是通过android.telephony.SmsManager短信管理类,直接调用相关短信接口。获取SmsManager对象的方式,在Android12即API 31级别以前是通过调用单例模式的静态方法SmsManager.getDefault()直接获取,而从Android12开始改用Context对象的getSystemService(Class<T> serviceClass)传入参数 serviceClass 值为SmsManager.class返回得到的对象。这里的方式一同样也是对方式二的代码封装。

权限声明

需要在清单文件中声明发送短信权限,其值为Manifest.permission.SEND_SMS="android.permission.SEND_SMS"。该权限为 dangerous 级权限,因此在Android6.0即API 23及之后的版本中,还需要在唤起系统短信应用之前动态申请该权限。

唤起流程

在调用startActivity(Intent intent)方法时,传入的参数 intent 必须设置其 action 行为值为Intent.ACTION_SENDTO。如果需要输入接收方的电话号码,可以设置其 data 数据值为Uri.parse(String str)的生成结果,其中参数 str 便是以"smsto:"起始加电话号的字符串结构。另外还可以对 intent 设置额外数据,其键值在SmsManager中均以常量形式定义。

如果使用SmsManager短信管理类对象,则是调用该对象的sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)及其他相关方法发送消息,在该方法中,参数 destinationAddress 即接收方的地址,参数 scAddress 是使用的服务器中心地址,通常为值为null表示使用默认的电信中心服务器,参数 text 为发送的消息体内容,通常一条短信长度为70字节,参数 sentIntent 非空时,将会在短信发送之后回调注册该意图的组件,参数 deliveryIntent 非空时,将会在短信发送给接收方之后回调注册该意图的组件。

自定义界面实现短信服务

主要是自定义BroadcastReceiver广播接收器,实现短信接收实时监听功能。

首先要在清单文件中声明短信接收权限Manifest.permission.RECEIVE_SMS="android.permission.RECEIVE_SMS"

还要在清单文件中注册自定义的BroadcastReceiver广播接收器,在<receiver></receiver>标签内部,设置其意图过滤标签<intent-filter></intent-filter>中的行为标签<action>值必须为"android.provider.Telephony.SMS_RECEIVED",该意图行为与系统短信一致,因此在该应用中收到该意图后,系统发送的广播将会由该应用中的广播接收器接收到。

最后在自定义的BroadcastReceiver中,实现onReceiver(Context context, Intent intent)方法,在该方法中处理接收到广播之后的操作。接收到的短信数据以Protocol Description Unit数据额外数据形式保存在参数 intent 中,可以调用android.provider.Telephony.Sms.Intents.getMessagesFromIntent(Intent intent)静态方法,得到android.telephony.SmsMessage短消息类型。在SmsMessage中便可查看收到的消息内容等信息。

数据流量

数据流量作为联网方式之一,与WLAN联网一起,都可以在android.net.ConnectivityManager连接管理类中操作管理。而由于ConnectivityManager只能管理监听系统的网络状态信息,因此只在连接管理类中判断联网方式时有所涉及,故数据流量的相关功能操作不再单独过多介绍。

Android系统编程入门系列之硬件交互——通信硬件电信SIM卡的更多相关文章

  1. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  2. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  3. Android系统编程入门系列之硬件交互——传感器

    到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...

  4. Android系统编程入门系列之硬件交互——通信硬件USB

    在硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互.从本文开始,将重点介绍该系列相关硬件. 互联通信系列硬件 根据硬件的可通信距离,由近及远分为USB.NFC.蓝牙.W ...

  5. Android系统编程入门系列之硬件交互——通信硬件Bluetooth

    通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...

  6. Android系统编程入门系列之硬件交互——多媒体展示

    前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...

  7. Android系统编程入门系列之硬件交互——通信硬件NFC

    在上篇文章介绍了接入式USB硬件的简单使用,接下来将介绍不依赖物理连接的硬件通信了.本文的重点是近距离通信的硬件NFC. NFC硬件 应用程序中可以通过NFC硬件读取或发送指定协议的技术实现,在And ...

  8. Android系统编程入门系列之硬件交互——无线通信WLAN

    Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...

  9. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

随机推荐

  1. element ui图片上传方法

    <!--商品图片--> <template v-slot:product_cover> <el-upload list-type="picture-card&q ...

  2. go基础——输入输出

    package main import ( "bufio" "fmt" "os" ) func main() { /* 输入和输出 fmt包 ...

  3. Msi.h causes compilation error in vs2010

    创建一个Win32 Console工程ReadFromMSM,什么都不需要做. 在ReadFromMSM.cpp文件中引入头文件: #include <msi.h> 编译,会发现有成堆的错 ...

  4. HTML笔记整理--下节

    欢迎来到HTML基础笔记下节部分! 内联样式 当特殊的样式需要应用到个别元素时,就可以使用内联样式. 使用内联样式的方法是在相关的标签中使用样式属性.样式属性可以包含任何 CSS 属性.以下实例显示出 ...

  5. 使用SetTrustedCredmanAccessPrivilege获取已保存的凭据

      windows系统中有一个名为SeTrustedCredmanAccessPrivilege的权限,使拥有该特权的进程可作为受信任的调用者访问凭据管理器.   凭据管理器可以从控制面板 -> ...

  6. Linux海王 之 pdsh (并行管理工具)

    文章目录 安装 使用 示例 -w 指定主机 -l 指定用户 -g指定用户组 主机列表 交互式界面 pdsh是一个多线程远程shell客户机,它在多个远程主机上并行执行命令 pdsh可以使用几种不同的远 ...

  7. linux历史命令审计

    一.添加历史命令记录 1.首先在/etc/profile中添加 export HISTORY_FILE=/var/log/Command/Command.log export PROMPT_COMMA ...

  8. c++动态内存管理与智能指针

    目录 一.介绍 二.shared_ptr类 make_shared函数 shared_ptr的拷贝和引用 shared_ptr自动销毁所管理的对象- -shared_ptr还会自动释放相关联对象的内存 ...

  9. Renix软件如何添加VLAN头部——网络测试仪实操

    一.添加VLAN头部 打开Renix软件,连接机箱, 预约端口 添加VLAN头部,选中"IPv4 Header"右键选择"Insert Before",会弹出& ...

  10. 能无缝嵌入Excel的报表工具,报表轻松做!

    现在很多人做数据分析会被推荐选择去用编程R和Python.PowerBI.Tableau.Qlik.Smartbi... 从目前数据分析的行业来说,Excel是世界上使用人数最多的报表分析工具,没有之 ...