Sipdroid的封装

简介

之前分析了Sip,过了这么久,再到官方看一下sipdroid项目,已经3.4版本了,心中产生一个念头,重新封装Sipdroid项目成.jar(项目名称为SipCore.jar),其它项目使用只要引入jar即可,我花了一个星期的业余时间重新封装了Sipdroid项目(经测试可实现互通,o(∩_∩)o 哈哈 )。

项目

先看效果图:




主要应用代码如下:

sip初始化
		SipManager.getInstance().initConfig(mContext.getApplicationContext()); //实例一个sip管理
		SessionManager.getInstance().initConfig(
				mContext.getApplicationContext()); //实例化一个sip会话管理

		SipManager.getInstance().setmIXSessionChange(
				SessionManager.getInstance()); //会话监听

		SipManager.getInstance().setUserName("1002"); //用户名
		SipManager.getInstance().setPassword("1002"); //密码
		SipManager.getInstance().setServer("baidu.com"); //域名
		// SipManager.getInstance().setUseWifi(true);// wifi默认使用
		SipManager.getInstance().setUse3G(true); //使用3G
		SipManager.getInstance().setUseEdge(true); //使用E网
//		SipManager.getInstance().setUseVpn(useVpn)
//		SipManager.getInstance().setUseStun(useSTUN)
//		SipManager.getInstance().setUseMMtel(useMMtel)
//		……
设置警报声,该资源来自Assets目录。
		try {
			SipManager.getInstance().setAlertingStream(
					this.getAssets().open("alerting")); // 警报声
		} catch (Exception e) {
		}

监听接口如下:
		if (mSipBroadcastReceiver != null)
			return;
		mSipBroadcastReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				int event = intent.getIntExtra(SipManager.ACTION_EVENT, 0);

				if (event == 0)
					return;

				if (event == SipEvent.SipStatusChange) { // sip状态变化
					onSipChange();
				} else if (event == SipEvent.SipSessionChange) {// sip会话状态变化

				}
			}
		};

		final IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(SipManager.ACTION_TAG); // 注册事件
		mContext.registerReceiver(mSipBroadcastReceiver, intentFilter);

拨打电话如下:
	private void callPhone() {
		mPhoneNumber = null;
		mPhoneNumber = new EditText(mContext);
		mPhoneNumber.setText("15079**2011");
		new AlertDialog.Builder(this).setTitle("请输入")
				.setIcon(android.R.drawable.ic_dialog_info)
				.setView(mPhoneNumber)
				.setPositiveButton("确定", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface arg0, int arg1) {
						try {
							SessionManager.getInstance().makeSipSession(
									mPhoneNumber.getText().toString(),
									CallType.OutgoCall);
							// if (SipManager.getInstance().makeAudioCall(
							// mPhoneNumber.getText().toString())) {
							// Log.i("", "");
							// }
						} catch (Exception e) {
						}

					}
				}).setNegativeButton("取消", null).show();
	}

//会话管理(针对Sip电话管理类)
//一个会话包括(连接sip、连接对方、连接成功、连接结束)
//类实现(会话状态改变监听、拨打电话、监听来电等操作)
public class SessionManager implements IXTaskListener, IXSessionChangeListener {
	private static String TAG = SessionManager.class.getCanonicalName();

	public static SessionManager getInstance() {
		if (mThis == null) {
			mThis = new SessionManager();
		}
		return mThis;
	}

	private SipSession mSession;
	private static SessionManager mThis;

	private Context mContext;
	private GSTask mSipSessionTask;

	private SystemCallLogOperate mSystemCallLogOperate;

	public SipSession getSession() {
		return mSession;
	}

	public SystemCallLogOperate getSystemCallLogOperate() {
		if (mSystemCallLogOperate == null) {
			mSystemCallLogOperate = new SystemCallLogOperate();
			mSystemCallLogOperate.initConfig(mContext);
		}

		return mSystemCallLogOperate;
	}

	public void initConfig(Context context) {
		mContext = context;
	}

	public SipSession makeSipSession(String number, CallType callType)
			throws Exception {// 开启会话
		Log.i(TAG, "makeSipSession");
		if (TextUtils.isEmpty(number))
			throw new Exception("无效号码…");
		if (callType == null)
			throw new Exception("拨打出错");

		if (mSession != null) {
			if (mSession.getCallType() == CallType.IncomeCall
					&& mSession.getCallStatus() == CallStatus.ConnectSuccess)
				return null;
			if (mSession.getCallType() == CallType.OutgoCall
					&& mSession.getCallStatus() != CallStatus.ConnectOver)
				return null;
			mSession = null;
		}

		mSession = new SipSession(number, callType);
		mSession.setCallStatus(CallStatus.ConnectSip);

		if (callType == CallType.IncomeCall) { // 来电(需要建立成功后再去通话界面)
		} else { // 去电(直接去通话界面)
			ActivityHelp.jumpToNewActivity(mContext, SipCallStatus.class);
		}

		startSipSessionTask();
		return mSession;
	}

	@Override
	public boolean onSessionState(int state, String number) {
		if (state == UserAgent.UA_STATE_INCOMING_CALL) {// 来电
			if (mSession != null
					&& mSession.getCallType() == CallType.OutgoCall
					&& mSession.getCallStatus() != CallStatus.ConnectOver)
				return true;
			else if (mSession != null
					&& mSession.getCallType() == CallType.IncomeCall
					&& mSession.getCallStatus() == CallStatus.ConnectSuccess) {
				return true;
			}

			if (mSession == null || !mSession.getNumber().equals(number)) {
				mSession = null;
			}

			if (mSession == null) {
				mSession = new SipSession(number, CallType.IncomeCall);
				mSession.setCallStatus(CallStatus.ConnectSuccess);
				startSipSessionTask();
			}

			mSession.setRingTime(System.currentTimeMillis());
			mSession.setCallStatus(CallStatus.ConnectOther);

			ActivityHelp.jumpToNewActivity(mContext, SipCallStatus.class);
		} else if (state == UserAgent.UA_STATE_OUTGOING_CALL) {// 去电

		} else if (state == UserAgent.UA_STATE_IDLE) {// 挂断等操作
			if (mSession != null) {
				mSession.setCallStatus(CallStatus.ConnectOver);// 结束

				// 1 来电 2去电 3丢失
				int callType = mSession.getCallType() == CallType.IncomeCall ? 1
						: 2;
				long duration = System.currentTimeMillis()
						- mSession.getInCallTime();
				if (mSession.getInCallTime() == 0) {
					callType = 3;
					duration = 0;
				}

				try {
					getSystemCallLogOperate().insertEotuCallLog(callType,
							mSession.getNumber(), "",
							mSession.getEstablishTime(), duration);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} else if (state == UserAgent.UA_STATE_INCALL) {// 通话中
			if (mSession != null) {
				mSession.setInCallTime(System.currentTimeMillis());
				mSession.setCallStatus(CallStatus.ConnectSuccess);//
			}
		} else if (state == UserAgent.UA_STATE_HOLD) {// 暂停
			if (mSession != null) {
				// mSession.rejectcall();// 对方暂停就停止通话
			}
		} else if (state == UserAgent.UA_STATE_RINGRING) {// 响铃
			if (mSession != null) {
				mSession.setRingTime(System.currentTimeMillis());
				mSession.setCallStatus(CallStatus.ConnectSuccess);// 响铃
			}
		} else if (state == UserAgent.UA_STATE_IDLE_NOTFOUND) {// 对方未注册(未找到)

		}

		return false; // false 内部处理(播放声音、电源。。。)
	}

	@Override
	public void onTask(Task task, TaskEvent event, Object... arg2) {
		if (mSipSessionTask != null && mSipSessionTask.equalTask(task)) {
			if (event == TaskEvent.Work) {
				try {
					if (!SipManager.getInstance().isRegistered()) {
						SipManager.getInstance().startSip();
					}

					while (true) {
						if (task.isCancel())
							return;
						Thread.sleep(1000);// 休息一秒
						SipManager.getInstance().sentEvent(
								SipEvent.SipSessionChange);

						if (mSession == null) {
							return;
						}

						SipSession.connectSipIncrementing();

						if (!GSNetwork.isConnect(mContext)) { // 无网络异常
							mSession.setCallStatus(CallStatus.ConnectOver);
							mSession = null;
							continue;
						}

						if (mSession.getCallStatus() == CallStatus.ConnectSip) {// 连接Sip
							if (SipSession.getConnectSipCount() > 30) { // 超时
								mSession.setCallStatus(CallStatus.ConnectOver);
								continue;
							}
							if (!SipManager.getInstance().isRegistered()) {
								continue;
							}

							mSession.setCallStatus(CallStatus.ConnectOther);// 进入第二阶段(连接对方)
						} else if (mSession.getCallStatus() == CallStatus.ConnectOther) {// 连接对方
							mSession.connectOtherIncrementing();

							if (mSession.getConnectOtherCount() >= 20) { // 超过3次视为超时
								mSession.setCallStatus(CallStatus.ConnectOver);
								continue;
							}

							if (mSession.getCallType() == CallType.OutgoCall
									&& mSession.getConnectOtherCount() % 6 == 1) {// 5秒一次呼叫对方(对话响应直接跳入第三阶段)
								Thread.sleep(3000); // 等3秒 让对方登陆
								SipManager.getInstance().makeAudioCall(
										mSession.getNumber());
							}

							continue;
							// 对方响铃自动 进入第三阶段(与对方通话)
						} else if (mSession.getCallStatus() == CallStatus.ConnectSuccess) {// 与对方通话
							continue;
						} else if (mSession.getCallStatus() == CallStatus.ConnectOver) {// 结束
							continue;
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
					if (mSession != null)
						mSession.setCallStatus(CallStatus.ConnectOver);
				}
			} else if (event == TaskEvent.Before) {
				SipSession.resetConnectSipCount();
			} else if (event == TaskEvent.Cancel) {
				SipManager.getInstance().stopSip();
				SipManager.getInstance().sentPostEvent(
						SipEvent.SipSessionChange, 2);
			}
		}
	}

	public void releaseConfig() {

		if (mSipSessionTask != null)
			mSipSessionTask.stopTask();
		mSipSessionTask = null;
	}

	private void startSipSessionTask() {
		if (mSipSessionTask == null) {
			mSipSessionTask = new GSTask();
			mSipSessionTask.setIXTaskListener(this);
		}

		if (!mSipSessionTask.isTasking())
			mSipSessionTask.startTask();
	}
}

结论
sipdroid3.4重新封装,对其它项目直接使用提供了便捷。


源码下载


稳定版源码下载



问题:把Sip放入到后台服务中经常出现“No SipListener found matching that message: message DISCARDED“信息

什么原因?原因如下:

02-26 03:30:55.415: W/System.err(292): java.lang.NullPointerException
02-26 03:30:55.415: W/System.err(292): 	at com.sipdroid.core.SipReceiver.playRingtone(SipReceiver.java:204)
02-26 03:30:55.435: W/System.err(292): 	at com.sipdroid.core.SipReceiver.onSessionState(SipReceiver.java:76)
02-26 03:30:55.435: W/System.err(292): 	at org.sipdroid.sipua.UserAgent.changeStatus(UserAgent.java:102)
02-26 03:30:55.465: W/System.err(292): 	at org.sipdroid.sipua.UserAgent.onCallIncoming(UserAgent.java:582)
02-26 03:30:55.475: W/System.err(292): 	at org.zoolu.sip.call.Call.onDlgInvite(Call.java:261)
02-26 03:30:55.486: W/System.err(292): 	at org.zoolu.sip.dialog.InviteDialog.onTransRequest(InviteDialog.java:852)
02-26 03:30:55.495: W/System.err(292): 	at org.zoolu.sip.transaction.InviteTransactionServer.onReceivedMessage(InviteTransactionServer.java:211)
02-26 03:30:55.515: W/System.err(292): 	at org.zoolu.sip.provider.SipProvider.processReceivedMessage(SipProvider.java:1089)
02-26 03:30:55.515: W/System.err(292): 	at org.zoolu.sip.provider.SipProvider.onReceivedMessage(SipProvider.java:1201)
02-26 03:30:55.565: W/System.err(292): 	at org.zoolu.sip.provider.UdpTransport.onReceivedPacket(UdpTransport.java:117)
02-26 03:30:55.565: W/System.err(292): 	at org.zoolu.net.UdpProvider.run(UdpProvider.java:189)

在执行的时候发生一个错误导致listener = null了。代码如下:

	/** The main thread */
	public void run() {
		byte[] buf = new byte[BUFFER_SIZE];
		UdpPacket packet = new UdpPacket(buf, buf.length);

		Exception error = null;
		long expire = 0;
		if (alive_time > 0)
			expire = System.currentTimeMillis() + alive_time;
		try {
//			socket.setSoTimeout(socket_timeout); modified
			// loop
			while (!stop) {
				try {
					socket.receive(packet);
				} catch (InterruptedIOException ie) {
					if (alive_time > 0 && System.currentTimeMillis() > expire)
						halt();
					continue;
				}
				if (packet.getLength() >= minimum_length) {
					if (listener != null)
						listener.onReceivedPacket(this, packet);
					if (alive_time > 0)
						expire = System.currentTimeMillis() + alive_time;
				}
				packet = new UdpPacket(buf, buf.length);
			}
		} catch (Exception e) {
			error = e;
			stop = true;
		}
		is_running = false;
		if (listener != null)
			listener.onServiceTerminated(this, error);
		listener = null;
	}


  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 51
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值