pro android学习笔记,Pro Android学习笔记(一二五):Telephony API(7):SIP Phone(下)...

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying以及作者@恺风Wei。

发起呼叫

发起呼叫,要确保客户端正常发送RTP包,需要增加两个新的权限:

发起呼叫的代码片段如下:

public SipAudioCall myCall = null;public void onOutgoingCall(View v){

if(myCall != null){

myCall.close();

}

try{  //设置状态监听器

SipAudioCall.Listener listener = new SipAudioCall.Listener(){

@Override //通话建立(对方接通),即收到SIP INVITE的200OK消息,并回复ACK时触发

public void onCallEstablished(SipAudioCall call) {

call.startAudio();  //在sip信令接通后,进行语音的处理

call.setSpeakerMode(true);

debug("onCallEstablished");

}

@Override //通话结束,指捕获通话建立后对方挂机,如果本方主动挂机,是不会触发此状态。如果对方拒听,可以在onError(SipAudaioCall call, int errorCode, String errorMessage)中获取,通过errorCode:-7和errorMessage:Temporarily Unavailable (480)。            public void onCallEnded(SipAudioCall call) {

debug("onCallEnded");

}

};

String called = "78000009@192.168.1.10:54712"; //我们用Xlite作为SIP的另一个UA,无需通过软交换,直接填入该终端的地址。        myCall = sipManager.makeAudioCall(mySipProfile.getUriString(), called, listener, 30);

}catch(Exception e){

debug("onOutgoingCall ERROR: "+ e.toString());

e.printStackTrace();

}

}

android.net.sip还提供了myCall.toggleMute()实现静音和非静音的切换,通过isMute()来检查当前是否是静音。静音时无RTP发送。SipDemo就是通过toogleMute()实现对讲的功能。

主动挂机的代码片段如下,包括通话后挂机(发送BYTE),以及建立呼叫的过程中终止(发送CANCEL)。

public void endCall(){

if(myCall == null)

return;

try{

myCall.endCall(); //停止通话}catch(Exception e){

debug("onEndCall ERROR: "+ e.toString());

e.printStackTrace();

}

myCall.close(); //关闭object,不能再用,释放object

myCall = null;

}

a44b0e6c7b100124f260d57b5c2b59f5.png

我要补充的是,SDP协商为PCMU,抓包看到双方都有RTP了,但是有问题,不能听到对方说啥,XLite听到的是噪音,因此应有什么东西欠缺,具体如何处理Audio还是很有问题,这可能也与测试机型有关,所以这个sip包,我觉得不实用。

作为被叫

我们仍用XLite来模拟,将domain设置为我们的小例子的sip地址(要带端口号),不采用register方式,这样在没有软交换的情况下,XLite的拨出电话都会打到我们的小例子。

在上一次笔记中,自动register的方式如下,我们查看了sipManager的说明,没有发现其他方法可以携带PendingIntent,因此作为被叫,必须采用自动register的方式,在收到呼叫时,触发一个广播intent。

Intent i = new Intent();

i.setAction("cn.wei.flowingflying.mysipphone.INCOMING_CALL");

PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);

sipManager.open(mySipProfile, pi, null);

我们需要在AndroidManifest.xml中声明接收器,也可以在代码中进行注册。根据小例子的特点,在代码中进行注册更为合适。

IncomingCallReceiver receiver = new IncomingCallReceiver(this);

…… 进行注册,例如在onCreate()中……IntentFilter filter = new IntentFilter();

filter.addAction("cn.wei.flowingflying.mysipphone.INCOMING_CALL");

this.registerReceiver(receiver, filter);

……进行注销,例如在onDestroy()中….

this.unregisterReceiver(receiver);

接收器代码如下:

public class IncomingCallReceiver extends BroadcastReceiver{

private MainActivity activity = null;  //主Activity的对象

private static boolean isEnd = false;

public IncomingCallReceiver(MainActivity activity){

this.activity = activity;

}

@Override

public void onReceive(Context context, Intent intent) {

activity.debug("--------receiver--------");

try{

//设置监听器,准备进行状态检测,和呼出一样,能触发的对方的状态,而非本方            SipAudioCall.Listener listener = new SipAudioCall.Listener(){

@Override //实际不会触发到onRinging,这是对方Ringing(180)而非本方                public void onRinging(SipAudioCall call, SipProfile caller) {

activity.debug("onRing..............");

}

@Override //呼叫建立可触发,是在answerCall()(发送200OK)后收到ACK时触发

public void onCallEstablished(SipAudioCall call) {

activity.debug("onCallEstablished..............");

}

@Override//对方挂机时触发,包括接通和未接通的挂机                public void onCallEnded(SipAudioCall call) {

activity.debug("onCallEnded..............");

isEnd = true;

call.close();

}

@Override

public void onError(SipAudioCall call, int errorCode,  String errorMessage) {

activity.debug("onError : " + errorMessage);

}

};

// 通过takeAudioCall()获得呼叫的session,并设置监测器

SipAudioCall incomingCall = activity.sipManager.takeAudioCall(intent, listener);

Thread.sleep(2000);//模拟2秒后接通            if(isEnd){ //对方可能已经在未接通前主动挂架,故要进行检查

incomingCall.answerCall(30);  //接通,发送200OK,并有30秒时间等待ACK的应当

incomingCall.startAudio();

incomingCall.setSpeakerMode(true);

activity.myCall = incomingCall;  //使得activity的UI的挂机可以操作

}

}catch(Exception e){

activity.debug("INCOMING CALL ERROR : " + e.toString());

e.printStackTrace();

}

}

}

059129c300f3277e42e8d77a9c1753f1.png

对于被叫,andriod.net.sip不支持INVITE不带sdp方式,会报“seesion description missing in incoming call intent”的错误。

总的来讲android.net.sip高度封装,完成要给sip phone很容易,但是很多无法调整,在实际应用中会受到限制,基本上还是自己处理的为好。

相关链接:我的Android开发相关文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值