讲了这么多废话,上一点干货吧,这篇我们主要讲的是Android Sip中的第三方框架 android-jain-sip-ri-1.2.224.jar,这篇将介绍android-jain-sip-ri-1.2.224.jar的使用
为什么使用这个库?
1.本地SIP堆栈的限制
Google原生的android sip堆栈是建立在JAIN SIP之上的,但是它没有所有的功能,现在不支持即时消息,状态和视频通话。Google分叉了SIP堆栈,并且从未真正地更新默认发货的SIP API,并使用与原始JAIN SIP项目相同的软件包名称。这对于那些希望在全世界增加SIP功能的开发者来说是一个麻烦,因为他们不能使用JAIN SIP。
2.JAIN SIP是基于Java的
这是一个基于java的SIP协议栈,它允许你在没有NDK的麻烦的情况下将SIP协议栈无缝集成到你的android应用程序中。
3.完整的SIP协议栈
JAIN SIP是RFC 3261规范的完整实现,同时也支持多个SIP RFC。
怎么使用?
1.导包:将android-jain-sip-ri-1.2.224.jar和log4导入到项目中,以Android Studio为例:
2.设置权限:参考Android-Sip_开发介绍(1)
Step -1: 初始化
创建一个单例类SipStackAndroid并初始化一个SIP堆栈。 这个类将实现SipListener和相应的方法来处理SIP事件。
public class SipStackAndroid implements SipListener {
private static SipStackAndroid instance = null;
public static SipStack sipStack;
public static SipProvider sipProvider;
public static HeaderFactory headerFactory;
public static AddressFactory addressFactory;
public static MessageFactory messageFactory;
public static SipFactory sipFactory;
public static ListeningPoint udpListeningPoint;
public static String localIp;
public static int localPort = 5080;
public static String localEndpoint = localIp + ":" + localPort;
public static String transport = "udp";
public static String remoteIp = "23.23.228.238";
public static int remotePort = 5080;
public static String remoteEndpoint = remoteIp + ":" + remotePort;
public static String sipUserName;
public String sipPassword;
protected SipStackAndroid() {
initialize();
}
public static SipStackAndroid getInstance() {
if (instance == null) {
instance = new SipStackAndroid();
}
return instance;
}
private static void initialize() {
localIp = getIPAddress(true);
localEndpoint = localIp + ":" + localPort;
remoteEndpoint = remoteIp + ":" + remotePort;
sipStack = null;
sipFactory = SipFactory.getInstance();
sipFactory.setPathName("android.gov.nist");
Properties properties = new Properties();
properties.setProperty("javaxx.sip.OUTBOUND_PROXY", remoteEndpoint + "/"
+ transport);
properties.setProperty("javaxx.sip.STACK_NAME", "androidSip");
try {
// Create SipStack object
sipStack = sipFactory.createSipStack(properties);
System.out.println("createSipStack " + sipStack);
} catch (PeerUnavailableException e) {
e.printStackTrace();
System.err.println(e.getMessage());
System.exit(0);
}
try {
headerFactory = sipFactory.createHeaderFactory();
addressFactory = sipFactory.createAddressFactory();
messageFactory = sipFactory.createMessageFactory();
udpListeningPoint = sipStack.createListeningPoint(localIp,
localPort, transport);
sipProvider = sipStack.createSipProvider(udpListeningPoint);
sipProvider.addSipListener(SipStackAndroid.getInstance());
// this.send_register();
} catch (PeerUnavailableException e) {
e.printStackTrace();
System.err.println(e.getMessage());
System.exit(0);
} catch (Exception e) {
System.out.println("Creating Listener Points");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Step-2:发送注册
以下方法发送一个注册包到服务器。
private void send_register() {
try {
System.out.println();
SipStackAndroid.getInstance();
AddressFactory addressFactory = SipStackAndroid.addressFactory;
SipStackAndroid.getInstance();
SipProvider sipProvider = SipStackAndroid.sipProvider;
SipStackAndroid.getInstance();
MessageFactory messageFactory = SipStackAndroid.messageFactory;
SipStackAndroid.getInstance();
HeaderFactory headerFactory = SipStackAndroid.headerFactory;
// Create addresses and via header for the request
Address fromAddress = addressFactory.createAddress("sip:"
+ SipStackAndroid.sipUserName + "@" + SipStackAndroid.remoteIp);
fromAddress.setDisplayName(SipStackAndroid.sipUserName);
Address toAddress = addressFactory.createAddress("sip:"
+ SipStackAndroid.sipUserName + "@" + SipStackAndroid.remoteIp);
toAddress.setDisplayName(SipStackAndroid.sipUserName);
Address contactAddress = createContactAddress();
ArrayList viaHeaders = createViaHeader();
URI requestURI = addressFactory.createAddress(
"sip:" + SipStackAndroid.remoteEndpoint).getURI();
// Build the request
final Request request = messageFactory.createRequest(requestURI,
Request.REGISTER, sipProvider.getNewCallId(),
headerFactory.createCSeqHeader(1l, Request.REGISTER),
headerFactory.createFromHeader(fromAddress, "c3ff411e"),
headerFactory.createToHeader(toAddress, null), viaHeaders,
headerFactory.createMaxForwardsHeader(70));
// Add the contact header
request.addHeader(headerFactory.createContactHeader(contactAddress));
ExpiresHeader eh = headerFactory.createExpiresHeader(300);
request.addHeader(eh);
// Print the request
System.out.println(request.toString());
// Send the request --- triggers an IOException
// sipProvider.sendRequest(request);
ClientTransaction transaction = sipProvider
.getNewClientTransaction(request);
// Send the request statefully, through the client transaction.
transaction.sendRequest();
} catch (Exception e) {
e.printStackTrace();
}
}
private Address createContactAddress() {
try {
SipStackAndroid.getInstance();
return SipStackAndroid.addressFactory.createAddress("sip:" + SipStackAndroid.sipUserName + "@"
+ SipStackAndroid.localEndpoint + ";transport=udp"
+ ";registering_acc=23_23_228_238");
} catch (ParseException e) {
return null;
}
}
private ArrayList createViaHeader() {
ArrayList viaHeaders = new ArrayList();
ViaHeader myViaHeader;
try {
SipStackAndroid.getInstance();
myViaHeader = SipStackAndroid.headerFactory.createViaHeader(SipStackAndroid.localIp, SipStackAndroid.localPort,
SipStackAndroid.transport, null);
myViaHeader.setRPort();
viaHeaders.add(myViaHeader);
} catch (ParseException e) {
e.printStackTrace();
} catch (InvalidArgumentException e) {
e.printStackTrace();
}
return viaHeaders;
}
Step-3:发送认证信息
为了响应REGISTER包,服务器请求认证信息(407错误)。 哪个会在实现SipListener的类的processResponse()方法中被接收。 下面的代码片段将身份验证发送回服务器。
像AccountManagerImpl这样的助手类可以在JAIN-SIP的例子中找到。
@Override
public void processResponse(ResponseEvent arg0) {
Response response = (Response) arg0.getResponse();
ClientTransaction tid = arg0.getClientTransaction();
System.out.println(response.getStatusCode());
if (response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED
|| response.getStatusCode() == Response.UNAUTHORIZED) {
AuthenticationHelper authenticationHelper = ((SipStackExt) sipStack)
.getAuthenticationHelper(new AccountManagerImpl(),
headerFactory);
try {
ClientTransaction inviteTid = authenticationHelper
.handleChallenge(response, tid, sipProvider, 5);
inviteTid.sendRequest();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (SipException e) {
e.printStackTrace();
}
}
发送SIP消息
看一下发送SIP消息的流程:
private void sendMessage(String to, String message) throws ParseException,
InvalidArgumentException, SipException {
SipStackAndroid.getInstance();
SipURI from = SipStackAndroid.addressFactory.createSipURI(SipStackAndroid.getInstance().sipUserName, SipStackAndroid.getInstance().localEndpoint);
SipStackAndroid.getInstance();
Address fromNameAddress = SipStackAndroid.addressFactory.createAddress(from);
SipStackAndroid.getInstance();
// fromNameAddress.setDisplayName(sipUsername);
FromHeader fromHeader = SipStackAndroid.headerFactory.createFromHeader(fromNameAddress,
"Tzt0ZEP92");
SipStackAndroid.getInstance();
URI toAddress = SipStackAndroid.addressFactory.createURI(to);
SipStackAndroid.getInstance();
Address toNameAddress = SipStackAndroid.addressFactory.createAddress(toAddress);
SipStackAndroid.getInstance();
// toNameAddress.setDisplayName(username);
ToHeader toHeader = SipStackAndroid.headerFactory.createToHeader(toNameAddress, null);
SipStackAndroid.getInstance();
URI requestURI = SipStackAndroid.addressFactory.createURI(to);
// requestURI.setTransportParam("udp");
ArrayList viaHeaders = createViaHeader();
SipStackAndroid.getInstance();
CallIdHeader callIdHeader = SipStackAndroid.sipProvider.getNewCallId();
SipStackAndroid.getInstance();
CSeqHeader cSeqHeader = SipStackAndroid.headerFactory.createCSeqHeader(50l,
Request.MESSAGE);
SipStackAndroid.getInstance();
MaxForwardsHeader maxForwards = SipStackAndroid.headerFactory
.createMaxForwardsHeader(70);
SipStackAndroid.getInstance();
Request request = SipStackAndroid.messageFactory.createRequest(requestURI,
Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwards);
SipStackAndroid.getInstance();
SupportedHeader supportedHeader = SipStackAndroid.headerFactory
.createSupportedHeader("replaces, outbound");
request.addHeader(supportedHeader);
SipStackAndroid.getInstance();
SipURI routeUri = SipStackAndroid.addressFactory.createSipURI(null, SipStackAndroid.getInstance().remoteIp);
routeUri.setTransportParam(SipStackAndroid.transport);
routeUri.setLrParam();
routeUri.setPort(SipStackAndroid.remotePort);
SipStackAndroid.getInstance();
Address routeAddress = SipStackAndroid.addressFactory.createAddress(routeUri);
SipStackAndroid.getInstance();
RouteHeader route =SipStackAndroid.headerFactory.createRouteHeader(routeAddress);
request.addHeader(route);
SipStackAndroid.getInstance();
ContentTypeHeader contentTypeHeader = SipStackAndroid.headerFactory
.createContentTypeHeader("text", "plain");
request.setContent(message, contentTypeHeader);
System.out.println(request);
SipStackAndroid.getInstance();
ClientTransaction transaction = SipStackAndroid.sipProvider
.getNewClientTransaction(request);
// Send the request statefully, through the client transaction.
transaction.sendRequest();
}
这将发送一个消息到服务器,服务器将要求我们已经覆盖的授权。