Android系统编程入门系列之硬件交互——通信硬件电信SIM卡
现在的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卡的更多相关文章
- Android系统编程入门系列之加载界面Activity
上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...
- Android系统编程入门系列之硬件交互——多媒体摄像头
多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...
- Android系统编程入门系列之硬件交互——传感器
到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...
- Android系统编程入门系列之硬件交互——通信硬件USB
在硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互.从本文开始,将重点介绍该系列相关硬件. 互联通信系列硬件 根据硬件的可通信距离,由近及远分为USB.NFC.蓝牙.W ...
- Android系统编程入门系列之硬件交互——通信硬件Bluetooth
通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...
- Android系统编程入门系列之硬件交互——多媒体展示
前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...
- Android系统编程入门系列之硬件交互——通信硬件NFC
在上篇文章介绍了接入式USB硬件的简单使用,接下来将介绍不依赖物理连接的硬件通信了.本文的重点是近距离通信的硬件NFC. NFC硬件 应用程序中可以通过NFC硬件读取或发送指定协议的技术实现,在And ...
- Android系统编程入门系列之硬件交互——无线通信WLAN
Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...
- Android系统编程入门系列之界面Activity交互响应
在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...
随机推荐
- SqlServer数据库表生成C# Model实体类SQL语句——补充
在sql语句最前边加上 use[数据库名] 原链接:https://www.cnblogs.com/jhli/p/11552105.html --[SQL骚操作]SqlServer数据库表生成C ...
- tomcat启用apr需要的三个组件(缺少可能会报错)
tomcat8开始支持Apr,可以提升IO性能,但若配置了使用Apr,如下图所示,则需要安装apr和aprutil和tomcat-native 如果采用nio的方式,则配置可以改成protocol=& ...
- iOS开发笔记,简单实现视频音频的边下边播
总是在网上看别人的博文,受益匪浅,从没自己写过,今天分享一点小经验,第一次写技术博客,希望对同行的ios猿们有所帮助. 先介绍一下自己的情况:一年ios开发,http协议不太懂,大约知道断点下载h ...
- Redis 学习笔记(五)高可用之主从模式
上一节提到了 Redis 的持久性,也就是在服务器实例宕机或故障时,拥有再恢复的能力.但是在这个服务器实例宕机恢复期间,是无法接受新的数据请求.对于整体服务而言这是无法容忍的,因此我们可以使用多个服务 ...
- shell——eval exec
eval # cat test.sh echo \$$# eval "echo \$$#" # sh test.sh a b c $3 c shell的内建命令exec将并不启动新 ...
- Selenium对应版本
下面是谷歌浏览器与chromedriver的版本对应关系,供参考: ChromeDriver v2.45 (2018-12-10)----------Supports Chrome v70-72Chr ...
- python篇第3天【编码规范】
第二天加班去了! 语法约定: 多行语句 Python语句中一般以新行作为为语句的结束符. 但是我们可以使用斜杠( \)将一行的语句分为多行显示,如下所示: total = item_one + \ i ...
- JMM之synchronized关键字
对于通讯,涉及两个关键字volatile和synchronized: Java支持多个线程同时访问一个对象或者对象的成员变量,由于每个线程可以拥有这个变量的拷贝(虽然对象及其成员变量分配的内存实在共享 ...
- tip7:CentOS8虚拟机安装相关总结
使用工具:Win10家庭版.WM12Pro.CentOS8. 一.安装 之前使用虚拟机安装操作系统使用的都是OpenSuse,也有相关备份.但是在Win10家庭版上用不了,启动电脑蓝屏(可能某些硬件不 ...
- docker安装sentinel-dashbord
查找 sentinel-dashboard docker search sentinel-dashboard pull 镜像 docker pull bladex/sentinel-dashboard ...