官網(wǎng):http://www.linphone.org
源碼:https://github.com/BelledonneCommunications/linphone-android
API:http://www.linphone.org/docs/liblinphone-javadoc
如果官網(wǎng)提供的SDK無法滿足需求铣缠,可以下載完整版進(jìn)行編譯门粪,使用git命令(提示:因編碼方式不同钓觉,下載的源碼復(fù)制到不同的系統(tǒng)下將無法編譯)
git clone git://git.linphone.org/linphone-android.git --recursive
一离赫、下載SDK并引用
1.從官網(wǎng)下載sdk壓縮包并解壓,獲得三個文件呈础,其中l(wèi)inphone-android-liblinphone-tester-javadoc.jar為API,linphone-android-liblinphone-tester-sources.jar為java源碼橱健,liblinphone-sdk.aar為帶資源的SDK文件而钞。
2.AndroidStudio引用aar文件
方法一:將liblinphone-sdk.aar放到Module的libs目錄下,并在bulid.gradle里添加
repositories { flatDir { dirs 'libs' } }
并在dependencies中添加
compile(name:'liblinphone-sdk',ext:'aar')
之后Reduild project重新構(gòu)建就能使用拘荡。
方法二:new Module選擇import JAR/.AAR Package選項臼节,選擇liblinphone-sdk.aar文件后會直接生成一個lib庫,其他Module直接引用就能使用珊皿。
二网缝、初始化
1.自定義Service實現(xiàn)LinphoneCoreListener接口,創(chuàng)建LinphoneCore并進(jìn)行注冊登錄蟋定。
@Override
public void onCreate() {
????try{
? ? ? ? //創(chuàng)建LinphoneCore
????????LinphoneCore?lc = LinphoneCoreFactory.instance().createLinphoneCore(this, this);
????????TimerTask lTask = new TimerTask() {
????????????@Override
????????????public void run() {
????????????????lc.iterate();
????????????}
????????};
????????mTimer = new Timer("LinphoneMini scheduler");
????????mTimer.schedule(lTask, 0, 20);
? ??????String sipAddress = "sip:賬號@服務(wù)器地址"; //你的sip地址
????????String password = ""; //你的密碼
????????LinphoneAddress address = LinphoneCoreFactory.instance().createLinphoneAddress(sipAddress);
????????String username = address.getUserName();
????????String domain = address.getDomain();
????????LinphoneAuthInfo authInfo = LinphoneCoreFactory.instance().createAuthInfo(username, password, null, domain);????????LinphoneProxyConfig proxyConfig = getLc().createProxyConfig(sipAddress, domain, null, true);
????????lc.addProxyConfig(proxyConfig);
????????lc.addAuthInfo(authInfo);
????????lc.setDefaultProxyConfig(proxyConfig);
????}catch(LinphoneCoreException e){
????????e.printStackTrace();
????}
}
2.利用registrationState()回調(diào)監(jiān)聽注冊狀態(tài)
@Override
public void registrationState(LinphoneCore linphoneCore, LinphoneProxyConfig linphoneProxyConfig, LinphoneCore.RegistrationState registrationState, String s) {
Log.i("registrationState","registration: " + registrationState + " ---" + linphoneProxyConfig.getAddress() + " - " + s);
}
三粉臊、LinphoneChatMessage文本消息
1.使用LinphoneChatRoom和LinphoneChatMessage進(jìn)行文本消息的發(fā)送
public void sendMessage() {
????try {
????????//對方的sip地址
????????String to = "sip:對方賬號@服務(wù)器地址";
????????LinphoneAddress toAddress = lc.interpretUrl(to);
????????//建立對話
????????LinphoneChatRoom cr = lc.getChatRoom(toAddress);
????????//創(chuàng)建消息
????????LinphoneChatMessage msg = cr.createLinphoneChatMessage("你好");
????????//發(fā)送消息
????????cr.sendChatMessage(msg);
????} catch (LinphoneCoreException e) {
????????e.printStackTrace();
????}
}
2.利用messageReceived()回調(diào)接收消息
@Override
public void messageReceived(LinphoneCore lpc, LinphoneChatRoom cr, LinphoneChatMessage msg) {
Toast.makeText(getApplicationContext(), "接收到來自" + msg.getFrom().getUserName() + "的消息: " + msg.getText(), Toast.LENGTH_SHORT).show();
}
四、LinphoneCall語音視頻通話(單通話)
1.撥打電話
public synchronized void callOut(){
? ? try {
? ? ? ? //對方的sip地址
? ? ? ? String to = "sip:對方賬號@服務(wù)器地址";
????????LinphoneProxyConfig lpc = lc.getDefaultProxyConfig();
????????if (lpc != null){
? ? ? ? ? ? to = lpc.normalizePhoneNumber(to);
????????}
? ? ? ? LinphoneAddress toAddress = lc.interpretUrl(to);
????????if (lpc != null && toAddress.asStringUriOnly().equals(lpc.getIdentity())){
? ? ? ? ? ? //判斷下?lián)艽虻奶柎a是否是自己注冊登錄的號碼
? ? ? ? ? ? return;
????????}
? ? ? ? if (lc.isNetworkReachable()){
? ? ? ? ? ? //創(chuàng)建通話參數(shù)
? ? ? ? ? ? LinphoneCallParams params = lc.createCallParams(null);
????????????//是否啟用視頻
? ? ? ? ? ? params.setVideoEnabled(false);
????????????//設(shè)置音頻帶寬
? ? ? ? ? ? params.setAudioBandwidth(40);
????????????//建立通話
? ? ? ? ? ? lc.inviteAddressWithParams(toAddress,params);
????????} else {
? ? ? ? ? ? Log.e("Error: no network");
????????}
? ? } catch (LinphoneCoreException e){
? ? ? ? e.printStackTrace();
????}
}
2.接聽電話
public synchronized void callAnswer(){
? ? LinphoneCall mCall = null;
????ArrayList calls = new ArrayList<>(Arrays.asList(lc.getCalls()));
????for (LinphoneCall call : calls){
? ? ? ? LinphoneCall.State cstate = call.getState();
????????if (LinphoneCall.State.IncomingReceived == cstate){
? ? ? ? ? ? mCall = call;
????????????break;
????????}
????}
? ? if (mCall == null){
? ? ? ? return;
????}
? ? LinphoneCallParams params = lc.createCallParams(mCall);
????if (params != null){
? ? ? ? try {
? ? ? ? ? ? lc.acceptCallWithParams(mCall,params);
????????} catch (LinphoneCoreException e){
? ? ? ? ? ? lc.enableSpeaker(false);
????????????Log.i(e,"Accept call failed");
????????}
? ? } else {
? ? ? ? Toast.makeText(this,"An error occurred while accepting the call",Toast.LENGTH_LONG).show();
????}
}
3.掛斷電話
lc.terminateAllCalls();
4.利用callState()回調(diào)監(jiān)聽電話狀態(tài)
@Override
public void callState(LinphoneCore linphoneCore,LinphoneCall call,LinphoneCall.State state,String s){
? ? Log.i("callState","與你通話的是: " + call.getRemoteAddress()+ " - " + state + " - " + s);
????if (state == LinphoneCall.State.IncomingReceived){
? ? ? ? //來電
? ? }
? ? if (state == LinphoneCall.State.OutgoingRinging){
? ? ? ? //去電
? ? }
? ? if (state == LinphoneCall.State.Connected){
? ? ? ? //來去電接通
? ? }
? ? if (state == LinphoneCall.State.CallEnd || state == LinphoneCall.State.CallReleased || state == LinphoneCall.State.Error){
? ? ? ? //結(jié)束釋放驶兜、錯誤通話
? ? }
}