SIP for android

 

会话发起协议

Android提供了一个支持会话发起协议(SIP)的API,这可以让你添加基于SIP的网络电话功能到你的应用程序。Android包括一个完整的 SIP协议栈和集成的呼叫管理服务,让应用轻松无需管理会话和传输层的沟通就可设置传出和传入的语音通话,或直接音频记录或播放。

以下类型的应用程序可能使用SIP API:

  • 视频会议。
  • 即时消息。

条件和限制

以下是开发一个SIP应用程序的条件:

  • 你必须有一个运行Android2.3或者更高版本的移动设备。
  • SIP是通过无线数据连接来运行的,所以你的设备必须有一个数据连接(通过移动数据服务或者Wi-Fi)。这意味着你不能在模拟器(AVD)上进行测试,只能在一个物理设备上测试。详情请参见应用程序测试(Testing SIP Applications)。
  • 每一个参与者在应用程序的通信会话过程中必须有一个SIP账户。有很多不同的SIP服务提供商提供SIP账户。

SIP API类和接口

以下是Android SIP API中包含的一些类和一个接口(SipRegistrationListener)的概述:

类/接口

描述
SipAudioCall 通过SIP处理网络音频电话
SipAudioCall.Listener 关于SIP电话的事件监听器,比如接受到一个电话(on ringing)或者呼出一个电话(on calling)的时候
SipErrorCode 定义在SIP活动中返回的错误代码
SipManager 为SIP任务提供APIs,比如初始化一个SIP连接。提供相关SIP服务的访问。
SipProfile 定义了SIP的相关属性,包含SIP账户、域名和服务器信息
SipProfile.Builder 创建SipProfile的帮助类
SipSession 代表一个SIP会话,跟SIP对话框或者一个没有对话框的独立事务相关联
SipSession.Listener 关于SIP会话的事件监听器,比如注册一个会话(on registering)或者呼出一个电话(on calling)的时候
SipSession.State 定义SIP会话的声明,比如“注册”、“呼出电话”、“打入电话”
SipRegistrationListener 一个关于SIP注册事件监听器的接口

创建Manifest文件

如果你开发一个用到SIP API的应用程序,记住它需要Android2.3(API9)或者更高版本的平台的支持。所以在你的设备上要运行Android2.3(API9)或者更高的版本,并不是所有的设备都提供SIP的支持。

为了使用SIP,需要添加以下权限到你的manifest文件:

  • android.permission.USE_SIP
  • android.permission.INTERNET

为了确保你的应用程序能够安装到支持SIP的设备上,你需要添加以下内容到你应用程序的manifest文件里:

  • <uses-sdk android:minSdkVersion="9" />. 这个设置表明你的应用程序需要Android2.3或者更高版本的平台。详情请参考API Levels和<uses-sdk>元素相关的文档。

为了控制你的应用程序被那些不支持SIP的设备过滤掉(比如:在Google Play),你需要添加以下内容到你应用程序的manifest文件里:

  • <uses-feature android:name="android.hardware.sip.voip" />. 这个设置声明了你的应用程序用到了SIP API。这个声明还应该包含一个android:required 属性来表明你是否想让你的应用程序被那些不提供SIP支持的设备过滤掉。其他<uses-feature>声明你也可能需要,具体取决于你的 实现,详情请参考<uses- feature> 元素相关的文档。

如果你的应用程序设计用来接受呼叫,那么你还必须在应用程序的manifest文件里定义一个接收器(BroadcastReceiver 的子类):

  • <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>

以下是从SipDemo项目manifest文件中摘录的内容:

[xml] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.android.sip">
  4. ...
  5. <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
  6. ...
  7. <uses-sdk android:minSdkVersion="9" />
  8. <uses-permission android:name="android.permission.USE_SIP" />
  9. <uses-permission android:name="android.permission.INTERNET" />
  10. ...
  11. <uses-feature android:name="android.hardware.sip.voip" android:required="true" />
  12. <uses-feature android:name="android.hardware.wifi" android:required="true" />
  13. <uses-feature android:name="android.hardware.microphone" android:required="true" />
  14. </manifest>

创建一个SipManager对象

要想使用SIP API,你的应用程序需要创建一个SipManager对象,这个SipManager对象在你的应用程序里负责以下内容:

  • 发起SIP会话
  • 发起和接受呼叫
  • 在SIP provider里进行注册和注销
  • 验证会话的连通性

你可以像下面一样实例化一个新的SipManager对象:

[java] view plaincopyprint?
  1. public SipManager mSipManager = null;
  2. ...
  3. if(mSipManager == null) {
  4. mSipManager = SipManager.newInstance(this);
  5. }

在SIP服务器上进行注册

一个典型的Android SIP应用中包含一个或多个用户,他们中的每个人都有一个SIP账户。在Android SIP应用中,每一个SIP账户代表一个SipProfile对象。

一个SipProfile对象定义了一个SIP的概要文件,包括SIP账户、域名和服务器信息。跟正在这个设备上运行应用的SIP账户相关联的概要文件被 称之为本地配置文件。与会话相连接的概要文件被称之为对应配置文件。当你的SIP应用通过本地SipProfile登录到SIP服务器的时候,这就有效的 注册当前设备为基站来发送SIP呼叫到你想呼叫的SIP地址。

本节展示了如何创建一个SipProfile,以及如何把刚创建的SipProfile注册到SIP服务器上,并且跟踪注册事件。 你可以像以下一样创建一个SipProfile对象:

[java] view plaincopyprint?
  1. public SipProfile mSipProfile = null;
  2. ...
  3. SipProfile.Builder builder = new SipProfile.Builder(username, domain);
  4. builder.setPassword(password);
  5. mSipProfile = builder.build();

接下来的代码摘录本地配置文件,用于呼出电话和/或接收通用的SIP电话。呼叫器可以通过mSipManager.makeAudioCall来呼出后续 电话。这段摘录同样设置了一个android.SipDemo.INCOMING_CALL行动,这个行动会被一个intent过滤器来使用,当前设备接 收到一个呼叫(见Setting up an intent filter to receive calls)。以下是注册步骤:

[java] view plaincopyprint?
  1. Intent intent = new Intent();
  2. intent.setAction("android.SipDemo.INCOMING_CALL");
  3. PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
  4. mSipManager.open(mSipProfile, pendingIntent, null);

最后这段代码在SipManager上设置了一个SipRegistrationListener 监听器,这个监听器会跟踪SipProfile是否成功的注册到你的SIP服务提供者。

[java] view plaincopyprint?
  1. mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {
  2. public void onRegistering(String localProfileUri) {
  3. updateStatus("Registering with SIP Server...");
  4. }
  5. public void onRegistrationDone(String localProfileUri, long expiryTime) {
  6. updateStatus("Ready");
  7. }
  8. public void onRegistrationFailed(String localProfileUri, int errorCode,
  9. String errorMessage) {
  10. updateStatus("Registration failed.  Please check settings.");
  11. }<span style="padding:0px; margin:0px; color:rgb(102,204,102)"></span>

当你的应用程序使用完一个profile的时候,你应该关闭它来释放相关联的对象到内存中以及从服务器上注销当前设备。例如:

[java] view plaincopyprint?
  1. public void closeLocalProfile() {
  2. if (mSipManager == null) {
  3. return;
  4. }
  5. try {
  6. if (mSipProfile != null) {
  7. mSipManager.close(mSipProfile.getUriString());
  8. }
  9. } catch (Exception ee) {
  10. Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
  11. }
  12. }

拨打一个语音电话

要想拨打一个语音电话,你需要准备如下条件:

  • 一个发起呼叫电话的SipProfile对象(本地配置文件)和一个用来接收呼叫的有效的SIP地址(对应配置文件)
  • 一个SipManager对象

要想拨打一个语音电话,你应该建立一个SipAudioCall.Listener监听器。大部分客户与SIP堆栈的交互都是通过监听器来发生的。在这一小段你将会看到SipAudioCall.Listener监听器是如何在呼叫制定之后建立事务的:

[java] view plaincopyprint?
  1. SipAudioCall.Listener listener = new SipAudioCall.Listener() {
  2. @Override
  3. public void onCallEstablished(SipAudioCall call) {
  4. call.startAudio();
  5. call.setSpeakerMode(true);
  6. call.toggleMute();
  7. ...
  8. }
  9. @Override
  10. public void onCallEnded(SipAudioCall call) {
  11. // Do something.
  12. }
  13. };

一旦你创建了这个SipAudioCall.Listener监听器,你就可以拨打电话了,SipManager对象里的makeAudioCall方法接受以下参数:

  • 一个本地SIP配置文件(呼叫方)
  • 一个相对应的SIP配置文件(被呼叫方)
  • 一个用来监听从SipAudioCall发出的呼叫事件的SipAudioCall.Listener,这个参数可以为null,但是如上所说,一旦呼叫电话制定,这个监听器将被用来创建事务
  • 超时的值,以秒为单位

例如:

[html] view plaincopyprint?
  1. call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30);

接收呼叫

为了接收呼叫,SIP应用程序必须包含一个BroadcastReceiver的子类,这个子类得有能力响应一个表明有来电的intent。因此你需要在你的应用程序里做如下事情:

  • 在AndroidManifest.xml文件中声明一 个<receiver>元素。在SipDemo项目中,<receiver>元素是这样的<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
  • 实现BroadcastReceiver的子类,在SipDemo中,这个子类是IncomingCallReceiver
  • 通过挂起一个intent来初始化本地配置文件(SipProfile),当有人呼叫你的时候,这个挂起的intent会调用你的接收器。
  • 创建一个intent过滤器,这个过滤器通过标志着来电的行动来进行过滤。在SipDemo中,这个action是android.SipDemo.INCOMING_CALL。

实现BroadcastReceiver的子类

为了接收呼叫,你的SIP应用必须实现BroadcastReceiver的子类。当Android系统接收到一个呼叫的时候,他会处理这个SIP呼叫, 然后广播一个来电intent(这个intent由系统来定义),以下是SipDemo中实现BroadcastReceiver子类的代码。如果想查看 完整的例子,你可以去SipDemo Sample项目,这个项目在SDK的samples文件夹中。关于下载和安装SDK samples,请参考 Getting the Samples。

[java] view plaincopyprint?
  1. /*** Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
  2. */
  3. public class IncomingCallReceiver extends BroadcastReceiver {
  4. /**
  5. * Processes the incoming call, answers it, and hands it over to the
  6. * WalkieTalkieActivity.
  7. * @param context The context under which the receiver is running.
  8. * @param intent The intent being received.
  9. */
  10. @Override
  11. public void onReceive(Context context, Intent intent) {
  12. SipAudioCall incomingCall = null;
  13. try {
  14. SipAudioCall.Listener listener = new SipAudioCall.Listener() {
  15. @Override
  16. public void onRinging(SipAudioCall call, SipProfile caller) {
  17. try {
  18. call.answerCall(30);
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. };
  24. WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
  25. incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
  26. incomingCall.answerCall(30);
  27. incomingCall.startAudio();
  28. incomingCall.setSpeakerMode(true);
  29. if(incomingCall.isMuted()) {
  30. incomingCall.toggleMute();
  31. }
  32. wtActivity.call = incomingCall;
  33. wtActivity.updateStatus(incomingCall);
  34. } catch (Exception e) {
  35. if (incomingCall != null) {
  36. incomingCall.close();
  37. }
  38. }
  39. }
  40. }<span style="padding:0px; margin:0px; color:rgb(102,204,102)"></span>

创建一个用来接收呼叫的intent过滤器

当SIP服务接收到一个新的呼叫的时候,他会发送一个intent,这个intent会附带一个由应用程序提供的action。在SipDemo项目中,这个action是android.SipDemo.INCOMING_CALL。

以下从SipDemo中摘录的代码展示了如何通过挂起一个基于android.SipDemo.INCOMING_CALL action的intent来创建SipProfile对象的。PendingIntent对象将执行一个广播当SipProfile接收到一个呼叫的时 候:

[java] view plaincopyprint?
  1. public SipManager mSipManager = null;
  2. public SipProfile mSipProfile = null;
  3. ...
  4. Intent intent = new Intent();
  5. intent.setAction("android.SipDemo.INCOMING_CALL");
  6. PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
  7. mSipManager.open(mSipProfile, pendingIntent, null);

上面被执行的广播如果被intent过滤器拦截的话,这个intent过滤器将会启动声明过的 Receiver(IncomingCallReceiver)。你可以在你的应用程序里的manifest文件中指定一个intent过滤器,或者通过 代码来指定一个intent过滤器,就像SipDemo项目中Activity中的onCreate()方法一样:

[java] view plaincopyprint?
  1. public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
  2. ...
  3. public IncomingCallReceiver callReceiver;
  4. ...
  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. IntentFilter filter = new IntentFilter();
  8. filter.addAction("android.SipDemo.INCOMING_CALL");
  9. callReceiver = new IncomingCallReceiver();
  10. this.registerReceiver(callReceiver, filter);
  11. ...
  12. }
  13. ...
  14. }

测试SIP应用程序

要测试SIP应用程序的话,你需要以下条件:

  • 一个运行Android2.3或者更高版本的移动设备。SIP通过无线来运行,所以你必须在一个真正的设备上测试,在AVD上是测试是行不通的
  • 一个SIP账户,有很多不同的提供SIP账户的SIP服务提供商。
  • 如果你要打电话,这个电话必须是有效的SIP账户。

测试一个SIP应用程序的步骤:

  • 让你的设备连接到无线(设置>无线&网络>Wi-Fi>Wi-Fi设置)
  • 设置你的移动设备进行测试,就像在Developing on a Device里描述的一样
  • 在你的移动设备上运行程序,就像在Developing on a Device里描述的一样
  • 如果你正在使用Eclipse,你可以在Eclipse中查看应用程序的日志输出(Window > Show View > Other > Android > LogCat)。

SIP for android相关推荐

  1. android sip服务器,android sip协议通话实现

    android sip协议通话代码实现 简介 android里面的VOIP网络通话基于sip(Session initiation protocol)协议:android已经集成了sip协议栈,并提供 ...

  2. android sip教程,Android SIP开发教程

    Android 系统提供了支持 SIP(Session Initiation Protocol)的 API,允许开发者添加基于 SIP 的因特网电话特性到自己的应用程序中. Android 包含一个完 ...

  3. Android 中的SIP协议

    概述: Android提供了支持SIP(SessionInitiation Protocol)协议的API. 这让我们可以向APP中添加基于SIP的网络电话功能. Android包括了完整的SIP协议 ...

  4. Android 开发 voip/sip 程序

    首先说明一下相关概念,voip 和Sip ,voip的意思是网络电话,会话发起协议(SIP)是建立VOIP连接的IETF标准.SIP是一种应用层协议,用于和一个或多个参与者创建.修改和终止会话.SIP ...

  5. Android应用权限管理总结

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...

  6. Android常用权限

    读写存储卡 装载和卸载文件系统 android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE a ...

  7. Android 常用权限

    添加WiFi以及访问网络的权限:<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ...

  8. android屏幕适配流程,Android屏幕适配姿势

    GitHub地址 为什么要屏幕适配? device_framentation.png 统计 碎片化 品牌机型碎片化 屏幕尺寸碎片化 操作系统碎片化 为了保证用户获得一致的用户体验效果,使得某一元素在A ...

  9. android权限--android开发中的权限及含义(下)

    android权限--android开发中的权限及含义(下) android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权 ...

最新文章

  1. 华为4D成像雷达、智能驾驶平台MDC 810
  2. 大数据销售管理服务提供商InsideSales获得1亿美元融资
  3. BZOJ 1020——[SHOI2008]安全的航线flight
  4. spy导入数据到oracle,运用SchemaSpy逆向工程制作数据库文档
  5. python实用库_python常用库
  6. 通过build.xml在Eclipse中导入工程
  7. matplotlib官方文档pdf_Matplotlib知识
  8. display可以控制标签的显示模式
  9. 幸运红包娱乐微信小程序源码下载-多玩法安装简单
  10. echarts-地图使用/配合散点图展示空气质量
  11. EMV(二)交易流程
  12. python/appium实现华为应用商城app界面上下滑动打开关闭通知栏等功能
  13. 什么是 SAP Support Package Stack
  14. 51单片机数码管滚动显示学号_单片机数码管显示0到9程序代码
  15. Python爬虫之实现百度翻译
  16. 前端websockt可重连功能的插件
  17. python爬取豆瓣250排行榜数据
  18. CentOS7 开机进入紧急模式EmergencyMode的解决办法
  19. 金三银四的背后--软件测试工程师的求职之路
  20. 阿里巴巴云原生技术公开课文案:课时 1:第一堂“云原生”课(转载只为自学)

热门文章

  1. React setStats数组不更新,百思不得其解。
  2. react-navigation 跨 tabs 返回首页
  3. thread线程栈size及局部变量最大可分配size【转】
  4. PaperWeekly 第28期 | 图像语义分割之特征整合和结构预测
  5. cxGrid 在 GridMode = True 模式下实现标题点击排序以及标题列过滤筛选!!!
  6. linux mysql5.6 安装
  7. 搞IT的技术人员为什么会如此苦逼
  8. luogu 1484\1792 种树 奇怪的贪心可反悔
  9. Error opening terminal: xterm-256color
  10. 部署也是工程的一部分,也要编程(自动化)