现在的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. chmod以数字形式改变文件权限

    Linux文件的三种身份和四种权限,三种身份分别为: u:文件的拥有者 g:文件所属的群组 o:其他用户 对于每个身份,又有四种权限,分别为: r:读取文件的权限(read) w:写入文件的权限(wr ...

  2. Python—字符串常用函数

    Python-字符串常用字符串 字符串是一种表示文本的数据类型,使用单引号和双引号及三引号表示 访问字符串中的值字符串的每个字符都对应一个下标,下标编号是从0开始 转义字符字符串的格式化输出切片常用函 ...

  3. Vue项目中实现文件下载到本地的功能

    公司业务需求,我需要实现一个合同模板,自定义输入内容后生成合同随后导出下载合同.(自定义部分用到的是) 为了实现这个文件下载到本地的功能,真的是废了九牛二虎之力,以至于差点放弃(主要还是自己菜).刚开 ...

  4. 【发点感慨】我的cnblogs的文章被爬到了别的网站,阅读量比在cnblogs上还要高

    近期我写了挺多VictoriaMetrics的文章,在搜索相关文章的时候发现,我的文章被别的网站爬去了: 写写技术文章就是无偿分享给别人看的,越多人看到越多人受益,这一点没毛病. 但是: 爬了别人的文 ...

  5. 2021江西省赛赛后总结(Crypto)

    美国大选 程序: from Crypto.Util.number import * from secret import p,q def gcd(a, b): while b: a, b = b, a ...

  6. Express中使用session

    1.安装express-session npm install express-session --save-dev //注意-g无效 2.app.jsvar session = require('e ...

  7. 基于ASP.NET Core 5.0使用RabbitMQ消息队列实现事件总线(EventBus)

    文章阅读请前先参考看一下 https://www.cnblogs.com/hudean/p/13858285.html 安装RabbitMQ消息队列软件与了解C#中如何使用RabbitMQ 和 htt ...

  8. 在Linux中设置php变量的方法

    默认情况下已经安装好了PHP环境,并且知道安装好后的PHP文件路径,然后可以通过以下的方式设置PHP变量,快速执行PHP命令运行PHP文件. 环境:centos 第一步:vi ~/.bash_prof ...

  9. Solution -「Gym 102759G」LCS 8

    \(\mathcal{Description}\)   Link.   给定 \(m\),和长度为 \(n\),字符集为大写字母的字符串 \(s\),求字符集相同且等长的字符串 \(t\) 的数量,使 ...

  10. Solution -「多校联训」行列式

    \(\mathcal{Description}\)   Link.   给定 \(x,\{d_i\}_{i=1}^n,\{p_i\}_{i=2}^n,\{b_i\}_{i=2}^n,\{c_i\}_{ ...