美文网首页
android sip协议通话实现

android sip协议通话实现

作者: endian | 来源:发表于2018-01-23 16:11 被阅读0次

android sip协议通话代码实现

  • 简介
    • android里面的VOIP网络通话基于sip(Session initiation protocol)协议;android已经集成了sip协议栈,并提供了相应的API给应用开放使用,开发者不需要了解具体的协议内容

  • 基于sip的网络通话基本过程

    1. 建立SIP服务器,关于如何建立SIP服务器,请参考这篇文章
    2. 需要所有参与通话的客户端注册用户到SIP服务器
    3. 一个客户端发起SIP通话到另一个客户端,这个消息首先发到SIP服务器,sip服务器收到消息后转发到目的客户端
    4. 目的客户端接收电话

  • 关于SIP网络通话的主要类和描述如下表所示:

    <table>
    <tbody><tr>
    <th>类/接口</th>
    <th>描述</th>

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

<tr>
<th> SipSession.State</th>
<th>定义SIP会话的声明,比如“注册”、“呼出电话”、“打入电话”</th>
</tr>
<tr>
<th> SipRegistrationListener</th>
<th> 一个关于SIP注册事件监 听器的接口</th></tr></tbody></table>


  • 在应用的AndroidManifest.xml中需要声明下面权限和特征

      <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-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
      
      <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" />
    

  • 构造一个SipManager实例.

      SipManager manager = SipManager.newInstance(this);
      //必须调用此方法创建,这是因为该方法会判断设备是否支持sip协议PackageManager.FEATURE_SIP
      如果有的android设备不支持,可以添加android.software.sip.voip.xml和android.software.sip.xml到/system/etc/permissions/下
    

  • 下面代码是注册一个账户到SIP服务器
    SipProfile.Builder builder = new SipProfile.Builder(username, domain); 
    //uesrname表示注册用户名,domain表示域,实际就是sip服务器ip
    builder.setPassword(password); //注册用户密码
    SipProfile me = builder.build(); //构造一个SipProfile对象,也就是相当于一个账户信息
    Intent i = new Intent();
    i.setAction("android.SipDemo.INCOMING_CALL");
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA); 
    //构造一个PendingIntent对象,这样当sip Service收到一个通话请求时,
    //例如收到一个来电时,SipService会调用PendingIntent的send方法发送相应广播消息给调用者,也就是当前的SipProfile对象.
    manager.open(me, pi, null); //此处就是用于注册一个账户到sip服务器

//注册一个监听器,用于获取注册账户时的通知状态,当然也可以不注册.

        manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
        public void onRegistering(String localProfileUri) { //正在注册
        }

        public void onRegistrationDone(String localProfileUri, long expiryTime) {//注册成功
        }

        public void onRegistrationFailed(String localProfileUri, int errorCode,
                String errorMessage) {
        }
    });

  • 开始拨号,从一个设备拨打电话到另一个设备,前提是两个设备都已注册,且知道目的设备的sip账户信息.

      try {
          SipAudioCall.Listener listener = new SipAudioCall.Listener() {
              // Much of the client's interaction with the SIP Stack will
              // happen via listeners.  Even making an outgoing call, don't
              // forget to set up a listener to set things up once the call is established.
              @Override
              public void onCallEstablished(SipAudioCall call) { //当网络通话建立了之后,会收到此通知
                  call.startAudio(); //启动音频
                  call.setSpeakerMode(true); //设置为扬声器模式,也就是开启回声抑制
                  call.toggleMute(); //切换静音,注意默认为非静音,调用此方法后变为静音了
              }
      
              @Override
              public void onCallEnded(SipAudioCall call) {
              }
          };
      
          //注意此处的makeAudioCall方法就是打网络电话的,localProfile就是本地设备的SipProfile对象,
          //PeerProfile就是目标设备的SipProfile对象,listener是监听器
              SipAudioCall call = manager.makeAudioCall(localProfile.getUriString(),
               PeerProfile, listener, 30);}catch (Exception e) {    }
    
    • 注意,此处的SipProfile的内容格式,例如,LocalProfile的url格式为"sip:abcde123@10.0.149.240",PeerProfile的url格式为"sip:abcde234@10.0.149.240",url内容也就是sip账户,
      其中:

        (1)  sip: 表示采用sip协议
        (2) abcde123和abcde234是用户名, 也称为帐号.  用字母和数字均可。
        (3) 10.0.149.240是sip账户所属的服务器地址(当然也可以用域名来表示)
        (4)  SIP协议默认端口为5060,  默认采用UDP传输,如果需要指定端口为5678,可以修改为sip:abcde123@10.0.149.240:5678,
      

从localProfile和peerProfile指定的内容可以看出,账户名作为唯一标识,由sip服务器来解析账户名,从而找到对应的目的主机.

  • 目的端接收通话
    • 根据前面的分析,一个设备拨打电话到目的设备时,在目的设备的sip服务(SipService)会发送一个广播消息给当前的目的设备。因此必须提前注册一个广播接收器来接收此消息,这样才知道有来电通知,可以在AndroidManifest.xml静态注册,也可以在应用程序中动态注册,因此下面代码必须放在广播接收器的onReceive()方法中:

    • 案例:

      try {

        SipAudioCall.Listener listener = new SipAudioCall.Listener() {
            @Override
            public void onRinging(SipAudioCall call, SipProfile caller) {
                try {
                    call.answerCall(30);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
      
        //takeAudioCall就表示需要为接听电话创建一个SipAudioCall对象.
        SipAudioCall incomingCall = manager.takeAudioCall(intent, listener);
        incomingCall.answerCall(30); //接听电话
        incomingCall.startAudio(); //启动音频
        incomingCall.setSpeakerMode(true);
      
      • 注意点:

              1.所有参与网络通话的设备和sip服务器的网络必须是连接的,网络类型可以是以太网,wifi,mobile等都可以.
              如果通话过程有问题,可以检测设备网络收发包是否正常.
              2.对应的设备必须支持sip,voip功能才行.

相关文章

网友评论

      本文标题:android sip协议通话实现

      本文链接:https://www.haomeiwen.com/subject/ifwsaxtx.html