SIP(Session Initiation Protocol)服务在Android 2.3中正式引入,能够支持VOIP,当然在早期版本中,也有不少第三方成功的将SIP服务移植到Android中。比较著名的客户端包括sipdroid等。在Android中,SIP客户端的实现位于android.net.sip包中,主要的类包括SipAudioCall、SipManager、SipProfile、SipSession等。
使用SIP,要求"android.permission.INTERNET"和"android.permission.USE_SIP"权限。考虑到即使软件平台采用了Android 2.3,在硬件配置上也可能不能完全支持SIP,所以在AndroidManifest.xml还应声明"android.hardware.sip.voip"、"android.hardware.wifi"、"android.hardware.microphone"等。
1.SipManager
SipManager用于初始化SIP链接和接入SIP服务等。能够创建SIP会话。比较常用的方法包括:
createSipSession() //创建SIP会话 getCallId() //获得呼叫ID makeAudioCall() //发起语音呼叫 newInstance() //创建一个SipManager实例 register() //注册帐号 takeAudioCall() //接听电话 open() //打开SIP会话
另外支持SIP并不意味着一定支持VOIP,是否支持SIP协议栈和是否支持VOIP功能与硬件设备有关,在基于SIP发起语音呼叫前,还需判断支持SIP和语音呼叫,方法为isVoipSupported()和isApiSupported()。
2.SipAudioCall
SipAudioCall用来处理基于SIP的网络语音呼叫,通过SipManager的makeAudioCall()方法和 takeAudioCall()方法可以获得SipAudioCall的实例。
但需要注意的是,SipAudioCall要求"android.permission.INTERNET"和 "android.permission.USE_SIP"权限。
另外其startAudio()方法还要求"android.permission.ACCESS_WIFI_STATE"、"android.permission.WAKE_LOCK"、 "android.permission.RECORD_AUDIO"权限。其setSpeakerMode()方法还要求"android.permission.MODIFY_PHONE_STATE"权限。
SipAudioCall的常用方法包括: startAudio() //在一个已建立的SIP链接中发起通话 setSpeakerMode() //设置通话模式 toggleMute() //进行静音模式 getPeerProfile() //获取对方的信息 endCall() //结束一个语音呼叫SIP链接 answerCall() //应答一个语音呼叫SIP链接 makeCall() //发起一个语音呼叫SIP链接 sendDtmf() //发送DTMF音
另外通过设置SipAudioCall.Listener()监听器可以监听到SIP链接建立和结束的信息。在SIP语音呼叫链接建立后,就可以传输RTP(Real-time Transport Protocol)流了。在RFC 3551中对SDP(Session Description Protocol)采用的RTP流进行了明确的定义。其语音流为AMR格式。
3.SipProfile
SipProfile包含了一个SIP账户的帐户名、密码、端口、SIP域和SIP服务器地址等信息。
通过SipProfile.Builder可以构建一个SipProfile实例,另外也可以从SipSession中获取本地和对方的SipProfile实例。
SipProfile的常用方法包括: getPassword() //获得密码 getUriString() //获得URI getSipDomain() //获得SIP域 getDisplayName() //获得显示名 getUserName() //获得账户名
4.SipSession
SipSession意味着一个SIP会话。通过SipManager的createSipSession()方法可以获得发起呼叫时的SIP会话,通过SipManager的getSessionFor()方法可以获得收到呼叫时的SIP会话。
通过SipSession.Listener监听器可以监听到会话的信息如呼叫忙、呼叫结束、呼叫建立、注册请求、铃声等。
同SipSession.State监听器可以监听到会话的状态,SIP会话的状态目前有DEREGISTERING、INCOMING_CALL、INCOMING_CALL_ANSWERING、IN_CALL、NOT_DEFINED、OUTGOING_CALL、OUTGOING_CALL_CANCELING、OUTGOING_CALL_RING_BACK、PINGING、READY_TO_CALL、REGISTERING等。
SipSession的常用方法包括: getPeerProfile() //获取对方的信息 setListener() //设置SipSession.Listener监听器 register() //注册到SIP服务器
下面是发起SIP呼叫的一般过程:
public void initiateCall() { try { SipAudioCall.Listener listener = new SipAudioCall.Listener() { public void onCallEstablished(SipAudioCall call) { call.startAudio(); call.setSpeakerMode(true); call.toggleMute(); } @Override public void onCallEnded(SipAudioCall call) { …… } }; call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30); } catch (Exception e) { if (me SipProfile!= null) { try { meSipManager.close(me.getUriString()); } catch (Exception ee) { ee.printStackTrace(); } } if (call != null) { call.close(); } } }
下面是收到SIP呼叫的一般处理过程:
public class IncomingCallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { SipAudioCall incomingCall = null; try { SipAudioCall.Listener listener = new SipAudioCall.Listener() { @Override public void onRinging(SipAudioCall call, SipProfile caller) { try { call.answerCall(30); } catch (Exception e) { e.printStackTrace(); } } }; incomingCall = meSipManager.takeAudioCall(intent, listener); incomingCall.answerCall(30); incomingCall.startAudio(); incomingCall.setSpeakerMode(true); if(incomingCall.isMuted()) { incomingCall.toggleMute(); } } catch (Exception e) { if (incomingCall != null) { incomingCall.close(); } } } }
在框架层,SIP协议栈的具体实现位于frameworks\base\voip中,和其他服务一样,在框架上采用的同样是C/S架构,其框架层服务为SipService。