专为易燃易爆环境设计的扩音电话
基于SIP协议的网络电话机
基于SIP协议的IP对讲机
实现不同通信网络之间的互联互通。
为应急通信系统提供应急广播设备
专用的应急指挥通中心通信调度设备
提供寻呼、广播、对讲、电话、报警等功能...
集成了语音、视频、即时消息、会议的通信平台...
基于电话通信技术,为企业提供客服呼叫方案...
用于实时调度和指挥工作,快速响应和协调沟通...
为制造业、矿业、石油化工、等场所,构建可靠的通信方案...
为高速公路、地铁、隧道等交通场所提供应通信方案...
处理客户的查询、投诉、技术支持、订单处理...
专门为处理紧急情况而设计的通信系统
专门设计用于危险环境中的通信系统
公司动态简介
行业知识简介
博客
2017-04-04
前几篇从Android的Voip官网支持功能到Android Voip系统实现原理到VOIP的实现,相信大家已经对Voip有了大概的了解了吧?什么,还不了解,没关系,本节给大家看下Android的SDK里自带的SipDemo,这就算实践了吧,接下来会慢慢学习怎么自己做基于SIP协议栈的软电话,希望可以做到像CsipSimple那样。
Android Sip学习(准备知识)SIP 协议完整的呼叫流程
Android Sip学习(一)Android 2.3 APIs SIP-based VoIP
Android Sip学习(二)Android VoIP系统实现原理
Android Sip学习(三)Android Voip实现
Android Sip学习(四)Android自带SipDemo详解
会话发起协议 Android提供了一个支持会话发起协议(SIP)的API,这可以让你添加基于SIP的网络IP电话功能到你的应用程序。Android包括一个完整的SIP协议栈和集成的呼叫管理服务,让应用轻松无需管理会话和传输层的沟通就可设置传出和传入的语音通话,或直接音频记录或播放。
以下类型的应用程序可能使用SIP API: 视频会议。 即时消息。
条件和限制 以下是开发一个SIP应用程序的条件: 你必须有一个运行Android2.3或者更高版本的移动设备。 SIP是通过无线数据连接来运行的,所以你的设备必须有一个数据连接(通过移动数据服务或者Wi-Fi)。这意味着你不能在模拟器(AVD)上进行测试,只能在一个物理设备上测试。每一个参与者在应用程序的通信会话过程中必须有一个SIP账户。有很多不同的SIP服务提供商提供SIP账户。 SIP API类和接口 以下是Android SIP API中包含的一些类和一个接口(SipRegistrationListener)的概述:
创建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/HTML Code复制内容到剪贴板
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
package="com.example.android.sip">
……省略此部分
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
</application>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="true" />
<uses-feature android:name="android.hardware.microphone" android:required="true" />
</manifest>
创建一个SipManager对象 要想使用SIP API,你的应用程序需要创建一个SipManager对象,这个SipManager对象在你的应用程序里负责以下内容: 发起SIP会话 发起和接受呼叫 在SIP provider里进行注册和注销 验证会话的连通性
你可以像下面一样实例化一个新的SipManager对象:
Java Code复制内容到剪贴板
public SipManager mSipManager = null;
...
if(mSipManager == null) {
mSipManager = SipManager.newInstance(this);
}
在SIP服务器上进行注册 一个典型的Android SIP应用中包含一个或多个用户,他们中的每个人都有一个SIP账户。在Android SIP应用中,每一个SIP账户代表一个SipProfile对象。 一个SipProfile对象定义了一个SIP的概要文件,,包括SIP账户、域名和服务器信息。跟正在这个设备上运行应用的SIP账户相关联的概要文件被称之为本地配置文件。与会话相连接的概要文件被称之为对应配置文件。当你的SIP应用通过本地SipProfile登录到SIP服务器的时候,这就有效的注册当前设备为基站来发送SIP呼叫到你想呼叫的SIP地址。 本节展示了如何创建一个SipProfile,以及如何把刚创建的SipProfile注册到SIP服务器上,并且跟踪注册事件。 你可以像以下一样创建一个SipProfile对象:
public SipProfile mSipProfile = null;
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mSipProfile = builder.build();
接下来的代码摘录本地配置文件,用于呼出电话和/或接收通用的SIP电话。呼叫器可以通过mSipManager.makeAudioCall来呼出后续电话。这段摘录同样设置了一个android.SipDemo.INCOMING_CALL行动,这个行动会被一个intent过滤器来使用,当前设备接收到一个呼叫。以下是注册步骤:
Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);
最后这段代码在SipManager上设置了一个SipRegistrationListener 监 听器,这个监 听器会跟踪SipProfile是否成功的注册到你的SIP服务提供者。
mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
当你的应用程序使用完一个profile的时候,你应该关闭它来释放相关联的对象到内存中以及从服务器上注销当前设备。例如:
public void closeLocalProfile() {
if (mSipManager == null) {
return;
try {
if (mSipProfile != null) {
mSipManager.close(mSipProfile.getUriString());
} catch (Exception ee) {
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
拨打一个语音电话 要想拨打一个语音电话,你需要准备如下条件: 一个发起呼叫电话的SipProfile对象(本地配置文件)和一个用来接收呼叫的有效的SIP地址(对应配置文件); 一个SipManager对象。
要想拨打一个语音电话,你应该建立一个SipAudioCall.Listener监 听器。大部分客户与SIP堆栈的交互都是通过监 听器来发生的。在这一小段你将会看到SipAudioCall.Listener监 听器是如何在呼叫制定之后建立事务的:
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
public void onCallEnded(SipAudioCall call) {
// Do something.
};
一旦你创建了这个SipAudioCall.Listener监 听器,你就可以拨打电话了,SipManager对象里的makeAudioCall方法接受以下参数:
一个本地SIP配置文件(呼叫方) 一个相对应的SIP配置文件(被呼叫方) 一个用来监听从SipAudioCall发出的呼叫事件的SipAudioCall.Listener,这个参数可以为null,但是如上所说,一旦呼叫电话制定,这个监 听器将被用来创建事务 (超时的值,以秒为单位)
例如:
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子类的代码。(如果想查看完整的例子,你可以下载官网的SDK,里面自带例子从android-10就开始有这个功能,下面是我的电脑截图)
/*** Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
*/
public class IncomingCallReceiver extends BroadcastReceiver {
/**
* Processes the incoming call, answers it, and hands it over to the
* WalkieTalkieActivity.
* @param context The context under which the receiver is running.
* @param intent The intent being received.
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
public void onRinging(SipAudioCall call, SipProfile caller) {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
wtActivity.call = incomingCall;
wtActivity.updateStatus(incomingCall);
if (incomingCall != null) {
incomingCall.close();
创建一个用来接收呼叫的intent过滤器 当SIP服务接收到一个新的呼叫的时候,他会发送一个intent,这个intent会附带一个由应用程序提供的action。在SipDemo项目中,这个action是android.SipDemo.INCOMING_CALL。 以下从SipDemo中摘录的代码展示了如何通过挂起一个基于android.SipDemo.INCOMING_CALL action的intent来创建SipProfile对象的。PendingIntent对象将执行一个广播当SipProfile接收到一个呼叫的时候:
上面被执行的广播如果被intent过滤器拦截的话,这个intent过滤器将会启动声明过的Receiver(IncomingCallReceiver)。你可以在你的应用程序里的manifest文件中指定一个intent过滤器,或者通过代码来指定一个intent过滤器,就像SipDemo项目中Activity中的onCreate()方法一样:
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public IncomingCallReceiver callReceiver;
public void onCreate(Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
测试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)。
联系我们
028-83110277
IP电话机、视频电话机供应商
手机:
成都世讯电科信息技术有限公司是一家多媒体融合通信解决方案及运营服务提供商,公司专注于为广大用户提供简单高效的通信产品和真正符合行业用户需求的行业应用解决方案,让用户享受到个性化、私密性强又具开放性、兼容性强又易于管理的高科技服务,帮助用户实现办公及运营通信的现代化与网络信息化。
公司拥专注于IP多媒体解决方案的应用与实施,有IP多媒体通信系统(IPBX)、IP多媒体通信平台定制与搭建(运营、对讲广播、门禁、调度、音视频会议及与视频监控交互式应用等)、IP电话机、视频电话机、项目租赁、云通信及系统集成等服务。
电话:028-83110277
Q Q:86313858