linphone-sip通话使用说明
aar版本:liblinphone-sdk-v4.aar
官方Demo:Files · master · BC / public / linphone-android · GitLab:
注:记得把资源文件一起拷贝进去
运行效果
添加依赖
repositories {
flatDir {
dirs 'libs' // aar用到
}
}
dependencies {
api fileTree(dir: 'libs', include: '*.jar')
implementation(name: 'liblinphone-sdk-v4', ext: 'aar')
}
添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.linphone">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<!--悬浮窗权限-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!--唤醒权限-->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!--免提权限-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Linphone">
<activity android:name=".SipMainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".VideoActivity"/>
<service android:name=".LinphoneMiniManager"/>
</application>
</manifest>
使用示例
SipMainActivity
package com.example.linphone;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.linphone.tools.ActivityInterface;
import org.linphone.core.Call;
import org.linphone.core.TransportType;
/**
* author : 吴明辉
* e-mail : 1412378121@qq.com
* date : 2022/3/2611:23
* git : https://gitee.com/yunianvh
* desc : AccountBuilder接电话时用到
*/
public class SipMainActivity extends AppCompatActivity {
private static final String TAG = SipMainActivity.class.getSimpleName();
private TextView id_text_status, id_text_code, id_call_stateinfo, id_text_version;
private EditText id_etext_regtext, id_etext_dail, id_etext_regpwd, id_etext_ipport, id_etext_type;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sipmain);
id_etext_regtext = (EditText) this.findViewById(R.id.id_etext_regtext);
id_etext_dail = (EditText) this.findViewById(R.id.id_etext_dail);
id_etext_regpwd = (EditText) this.findViewById(R.id.id_etext_regpwd);
id_text_status = (TextView) this.findViewById(R.id.id_text_status);
id_call_stateinfo = (TextView) this.findViewById(R.id.id_call_stateinfo);
id_etext_ipport = (EditText) this.findViewById(R.id.id_etext_ipport);
id_text_version = (TextView) this.findViewById(R.id.id_text_version);
id_text_code = (TextView) findViewById(R.id.id_text_code);
id_etext_type = (EditText) findViewById(R.id.id_etext_type);
//权限
//开始启动linphone服务
startService(new Intent(this, LinphoneMiniManager.class));
//延时2秒启动监听,避免服务未启动设置监听方法出现异常
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
LinphoneMiniManager.getInstance().setActivityInterfaceListener(new ActivityInterface() {
@Override
public void onLinphone(String cmd, String msg) {
Log.e(TAG, "onLinphone监听返回 cmd-->" + cmd + " msg-->" + msg);
switch (cmd) {
case "reg_state":
id_text_status.setText(msg);
break;
case "show_code":
id_text_code.setText(msg);
break;
case "show_callinfo":
id_call_stateinfo.setText(msg);
if (msg.startsWith("Incoming CallSession"))
LinphoneMiniManager.getInstance().liLinJie();
break;
case "show_version":
id_text_version.setText(msg);
break;
default:
break;
}
}
});
}
}, 2000);
}
/**
* 注册
*
* @param view
*/
public void reg(View view) {
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
String[] split = id_etext_ipport.getText().toString().split(":");
String host = split[0], port = split[1];
try {
String password = id_etext_regpwd.getText().toString();
String type = id_etext_type.getText().toString();
TransportType transport = TransportType.Udp;
if (type.indexOf("tcp") != -1) {
transport = TransportType.Tcp;
Toast.makeText(SipMainActivity.this, "tcp注册", Toast.LENGTH_SHORT).show();
} else if (type.indexOf("tls") != -1) {
transport = TransportType.Tls;
Toast.makeText(SipMainActivity.this, "tls注册", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(SipMainActivity.this, "udp注册", Toast.LENGTH_SHORT).show();
}
instance.lilin_reg(host + ":" + port, id_etext_regtext.getText().toString(), password, transport);
// instance.lilin_reg("192.168.10.146","1004","12345","5090");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 语音拨打
*
* @param view
*/
public void boda(View view) {
String[] split = id_etext_ipport.getText().toString().split(":");
String host = split[0], port = split[1];
Log.e(TAG, "语音拨打");
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.lilin_call(id_etext_dail.getText().toString(), id_etext_ipport.getText().toString(), false);
}
/**
* 挂断电话
*
* @param view
*/
public void guaduan(View view) {
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.hangUp();
}
/**
* 接电话
*
* @param view
*/
public void jie(View view) {
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.liLinJie();
Call ccall = instance.getLC().getCurrentCall();
if (ccall != null && ccall.getRemoteParams().videoEnabled()) {
startActivity(new Intent(SipMainActivity.this, VideoActivity.class));
}
}
/**
* 视频拨打
*
* @param view
*/
public void videoda(View view) {
// Toast.makeText(SipMainActivity.this,"无视频",Toast.LENGTH_SHORT ).show();
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.lilin_call(id_etext_dail.getText().toString(), id_etext_ipport.getText().toString(), true);
startActivity(new Intent(SipMainActivity.this, VideoActivity.class));
}
/**
* 是否扩音
*
* @param view
*/
public void kuoyin(View view) {
if (!LinphoneMiniManager.isReady()) {
Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
return;
}
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.lilin_enkuo();
}
public void senddtmf(View view) {
LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
instance.getLC().setUseInfoForDtmf(true);
Call currentCall = instance.getLC().getCurrentCall();
if (currentCall != null) {
char a = 2;
currentCall.sendDtmf(a);
Toast.makeText(SipMainActivity.this, "senddtmf", Toast.LENGTH_SHORT).show();
}
}
}
VideoActivity
package com.example.linphone;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceView;
import androidx.appcompat.app.AppCompatActivity;
import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.VideoDefinition;
import org.linphone.mediastream.video.AndroidVideoWindowImpl;
/**
* author : 吴明辉
* e-mail : 1412378121@qq.com
* date : 2022/3/2611:23
* git : https://gitee.com/yunianvh
* desc : AccountBuilder接电话时用到
*/
public class VideoActivity extends AppCompatActivity {
private static final String TAG = VideoActivity.class.getSimpleName();
private SurfaceView mVideoView, mCaptureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_sip_video);
init();
new AndroidVideoWindowImpl(mVideoView, mCaptureView, new AndroidVideoWindowImpl.VideoWindowListener() {
@Override
public void onVideoRenderingSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
Log.e(TAG, "onVideoRenderingSurfaceReady---video_ready");
mVideoView = surface;
LinphoneMiniManager.getInstance().getLC().setNativeVideoWindowId(vw);
}
@Override
public void onVideoRenderingSurfaceDestroyed(AndroidVideoWindowImpl vw) {
}
@Override
public void onVideoPreviewSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
Log.e(TAG, "onVideoPreviewSurfaceReady-----");
mCaptureView = surface;
LinphoneMiniManager.getInstance().getLC().setNativePreviewWindowId(mCaptureView);
//resizePreview();
}
@Override
public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) {
}
});
resizePreview();
}
private void resizePreview() {
Core lc = LinphoneMiniManager.getInstance().getLC();
if (lc.getCallsNb() > 0) {
Call call = lc.getCurrentCall();
if (call == null) {
call = lc.getCalls()[0];
}
if (call == null) {
return;
}
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenHeight = metrics.heightPixels;
int maxHeight = screenHeight / 4; // Let's take at most 1/4 of the screen for the camera preview
VideoDefinition videoSize = call.getCurrentParams().getSentVideoDefinition(); // It already takes care of rotation
if (videoSize.getWidth() == 0 || videoSize.getHeight() == 0) {
Log.w(TAG, "Couldn't get sent video definition, using default video definition");
videoSize = lc.getPreferredVideoDefinition();
}
int width = videoSize.getWidth();
int height = videoSize.getHeight();
Log.d(TAG, "Video height is " + height + ", width is " + width);
width = width * maxHeight / height;
height = maxHeight;
if (mVideoView == null) {
Log.e(TAG, "mCaptureView is null !");
return;
}
mVideoView.getHolder().setFixedSize(metrics.widthPixels, metrics.heightPixels);
Log.d(TAG, "Video preview size set to " + width + "x" + height);
}
}
private void init() {
mVideoView = (SurfaceView) findViewById(R.id.videoSurface);
mCaptureView = (SurfaceView) findViewById(R.id.videoCaptureSurface);
}
}
核心代码
package com.example.linphone;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.example.linphone.tools.AccountBuilder;
import com.example.linphone.tools.ActivityInterface;
import com.example.linphone.tools.LinphoneMiniUtils;
import org.linphone.core.AVPFMode;
import org.linphone.core.Address;
import org.linphone.core.AuthInfo;
import org.linphone.core.AuthMethod;
import org.linphone.core.Call;
import org.linphone.core.CallLog;
import org.linphone.core.CallParams;
import org.linphone.core.CallStats;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatRoom;
import org.linphone.core.Config;
import org.linphone.core.ConfiguringState;
import org.linphone.core.Content;
import org.linphone.core.Core;
import org.linphone.core.CoreException;
import org.linphone.core.CoreListener;
import org.linphone.core.EcCalibratorStatus;
import org.linphone.core.Event;
import org.linphone.core.Factory;
import org.linphone.core.Friend;
import org.linphone.core.FriendList;
import org.linphone.core.GlobalState;
import org.linphone.core.InfoMessage;
import org.linphone.core.NatPolicy;
import org.linphone.core.PayloadType;
import org.linphone.core.PresenceModel;
import org.linphone.core.ProxyConfig;
import org.linphone.core.PublishState;
import org.linphone.core.RegistrationState;
import org.linphone.core.SubscriptionState;
import org.linphone.core.TransportType;
import org.linphone.core.Transports;
import org.linphone.core.VersionUpdateCheckResult;
import org.linphone.core.VideoDefinition;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* author : 吴明辉
* e-mail : 1412378121@qq.com
* date : 2022/3/2611:23
* git : https://gitee.com/yunianvh
* desc : AccountBuilder接电话时用到
*/
public class LinphoneMiniManager extends Service implements CoreListener {
public static final String TAG = LinphoneMiniManager.class.getSimpleName();
private static LinphoneMiniManager mInstance;
private Context mContext;
private Core mLinPhoneCore;
private ScheduledThreadPoolExecutor poolExecutor;
private ScheduledFuture<?> future;
private Factory lcFactory;
private AudioManager mAudioManager;
private ActivityInterface listener;
public static boolean isReady() {
return mInstance != null;
}
public static LinphoneMiniManager getInstance() {
return mInstance;
}
public Core getLC() {
return mLinPhoneCore;
}
/**
* 设置回调监听,把注册,童话等状态回调出去
*
* @param listener
*/
public void setActivityInterfaceListener(ActivityInterface listener) {
this.listener = listener;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mContext = this;
lcFactory = Factory.instance();
lcFactory.setDebugMode(true, "lilinaini 34>>");
try {
String basePath = mContext.getFilesDir().getAbsolutePath();
copyAssetsFromPackage(basePath);
mLinPhoneCore = lcFactory.createCore(basePath + "/.linphonerc", basePath + "/linphonerc", mContext);
mLinPhoneCore.addListener(this);
/* getLC().setPreferredFramerate(15);
getLC().setVideoPreset("custom");
getLC().setUploadBandwidth(0);
getLC().setDownloadBandwidth(0);*/
startIterate();
setUserAgent();
mInstance = this;
mLinPhoneCore.setNetworkReachable(true); // Let's assume it's true
mAudioManager = ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE));
mAudioManager.setSpeakerphoneOn(true);
String[] dnsServer = new String[]{"8.8.8.8"};
mLinPhoneCore.setDnsServers(dnsServer);
mLinPhoneCore.enableAdaptiveRateControl(false);
mLinPhoneCore.start();
setSipPort(-1);
String preferredVideoSize = getPreferredVideoSize();
Log.e(TAG, preferredVideoSize);
//getConfig().setString("video", "size", "qcif");
//setPreferredVideoSize("cif");
//初始化完成把linphone版本通过回调接口返回回去
if (listener != null) listener.onLinphone("show_version", mLinPhoneCore.getVersion());
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "LinphoneMiniManager创建错误");
}
}
/**
* 设置sip端口号
*
* @param port
*/
public void setSipPort(int port) {
Transports transports = getLC().getTransports();
transports.setUdpPort(port);
transports.setTcpPort(port);
transports.setTlsPort(-1);
getLC().setTransports(transports);
}
/**
* 注册删除时候调用
*
* @param host
* @param username
* @param password
*/
public void setTurn(String host, String username, String password) {
if (getLC() == null) {
return;
}
NatPolicy nat = getOrCreateNatPolicy();
nat.setStunServer(host);
nat.enableIce(true);
nat.enableTurn(true);
AuthInfo authInfo = getLC().findAuthInfo(null, nat.getStunServerUsername(), null);
if (authInfo != null) {
Log.e(TAG, "方式1");
AuthInfo cloneAuthInfo = authInfo.clone();
getLC().removeAuthInfo(authInfo);
cloneAuthInfo.setUsername(username);
cloneAuthInfo.setUserid(username);
cloneAuthInfo.setPassword(password);
getLC().addAuthInfo(cloneAuthInfo);
} else {
Log.e(TAG, "方式2");
authInfo = Factory.instance().createAuthInfo(username, username, password, null, null, null);
getLC().addAuthInfo(authInfo);
}
nat.setStunServerUsername(username);
getLC().setNatPolicy(nat);
}
private NatPolicy getOrCreateNatPolicy() {
if (mLinPhoneCore == null) {
return null;
}
NatPolicy nat = mLinPhoneCore.getNatPolicy();
if (nat == null) {
nat = mLinPhoneCore.createNatPolicy();
}
return nat;
}
@Override
public void onDestroy() {
super.onDestroy();
endIterate();
}
private int iterateCount = 0;
private final int iterateTime = 20;
/**
* 循环检查linphone状态
*/
private void startIterate() {
poolExecutor = new ScheduledThreadPoolExecutor(1, r -> {
Thread thread = new Thread(r);
thread.setName("linPhone保活线程" + System.currentTimeMillis());
return thread;
});
future = poolExecutor.scheduleAtFixedRate(() -> {
try {
if (mLinPhoneCore != null) {
iterateCount++;
if (iterateCount % (10 * 1000 / iterateTime) == 0) {
iterateCount = 0;
ProxyConfig defaultProxyConfig = mLinPhoneCore.getDefaultProxyConfig();
if (defaultProxyConfig != null) {
RegistrationState state = defaultProxyConfig.getState();
if (state != null) {
Log.e(TAG, Thread.currentThread().getName() + "状态:" + state.toString() + ">>" + state.toInt());
}
}
}
mLinPhoneCore.iterate();
}
} catch (Exception e) {
Log.e(TAG, Thread.currentThread().getName() + "异常,重启线程");
endIterate();
startIterate();
}
}, 0, iterateTime, TimeUnit.MILLISECONDS);
}
/**
* 销毁循环检查linphone状态的线程
*/
private void endIterate() {
if (future != null) {
future.cancel(true);
future = null;
}
if (poolExecutor != null) {
poolExecutor.shutdown();
poolExecutor = null;
}
}
/**
* 把资源文件复制到指定目录
*
* @param basePath
*/
private void copyAssetsFromPackage(final String basePath) {
threadPool.execute(() -> {
try {
LinphoneMiniUtils.copyIfNotExist(mContext, R.raw.linphonerc_default, basePath + "/.linphonerc");
LinphoneMiniUtils.copyFromPackage(mContext, R.raw.linphonerc_factory, new File(basePath + "/linphonerc").getName());
LinphoneMiniUtils.copyIfNotExist(mContext, R.raw.lpconfig, basePath + "/lpconfig.xsd");
LinphoneMiniUtils.copyFromPackage(mContext, R.raw.assistant_create, new File(basePath + "/assistant_create.rc").getName());
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* 设置用户代理
*/
private void setUserAgent() {
try {
String versionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
if (versionName == null) {
versionName = String.valueOf(mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode);
}
mLinPhoneCore.setUserAgent("LinphoneMiniAndroid", versionName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* -------------------------------------------linphone监听 开始----------------------------------------------------------------------------------------------
*
* @param core
* @param globalState
* @param s
*/
@Override
public void onGlobalStateChanged(Core core, GlobalState globalState, String s) {
Log.e(TAG, ">onGlobalStateChanged " + s);
}
@Override
public void onRegistrationStateChanged(Core core, ProxyConfig proxyConfig, RegistrationState registrationState, String smessage) {
Log.e(TAG, "注册状态 onRegistrationStateChanged-->" + smessage);
//把注册状态通过回调接口返回回去
if (listener != null) listener.onLinphone("reg_state", smessage);
if (smessage.contains("successful")) {
String str = "音频:\n";
PayloadType[] audioCodecs = mLinPhoneCore.getAudioPayloadTypes();
for (PayloadType payloadType : audioCodecs) {
str += payloadType.getMimeType() + "-" + payloadType.getNormalBitrate() + "-" + payloadType.enabled() + "\n";
}
str += "\n视频:";
for (PayloadType payloadType1 : mLinPhoneCore.getVideoPayloadTypes()) {
// if(payloadType1.getMimeType().equalsIgnoreCase("VP8")) {payloadType1.enable(false);}
str += payloadType1.getMimeType() + "" + payloadType1.enabled() + "\n";
}
//把注册成功后音视频信息返回回去
if (listener != null) listener.onLinphone("show_code", str);
}
}
@Override
public void onCallStateChanged(Core core, Call call, Call.State state, String s) {
Log.e(TAG, "呼叫状态 onCallStateChanged-->" + call.getRemoteAddress().getUsername() + " >" + call.getRemoteAddressAsString() + " >" + s);
//过滤呼叫状态
if (s.startsWith("Incoming CallSession") || s.startsWith("Call released") || "Connected".equals(s)) {
//把呼叫状态返回回去
if (listener != null) listener.onLinphone("show_callinfo", s);
}
}
@Override
public void onNotifyPresenceReceived(Core core, Friend friend) {
}
@Override
public void onNotifyPresenceReceivedForUriOrTel(Core core, Friend friend, String s, PresenceModel presenceModel) {
}
@Override
public void onNewSubscriptionRequested(Core core, Friend friend, String s) {
}
@Override
public void onAuthenticationRequested(Core core, AuthInfo authInfo, AuthMethod authMethod) {
}
@Override
public void onCallLogUpdated(Core core, CallLog callLog) {
}
@Override
public void onMessageReceived(Core core, ChatRoom chatRoom, ChatMessage chatMessage) {
}
@Override
public void onMessageReceivedUnableDecrypt(Core core, ChatRoom chatRoom, ChatMessage chatMessage) {
}
@Override
public void onIsComposingReceived(Core core, ChatRoom chatRoom) {
Log.e(TAG, ">onIsComposingReceived " + chatRoom.getSubject());
}
@Override
public void onDtmfReceived(Core core, Call call, int i) {
Log.e(TAG, ">onDtmfReceived " + i + "收到");
}
@Override
public void onReferReceived(Core core, String s) {
Log.e(TAG, ">onReferReceived " + s);
}
@Override
public void onCallEncryptionChanged(Core core, Call call, boolean b, String s) {
}
@Override
public void onTransferStateChanged(Core core, Call call, Call.State state) {
}
@Override
public void onBuddyInfoUpdated(Core core, Friend friend) {
}
@Override
public void onCallStatsUpdated(Core core, Call call, CallStats callStats) {
}
@Override
public void onInfoReceived(Core core, Call call, InfoMessage infoMessage) {
Log.e(TAG, ">onInfoReceived " + infoMessage.getContent().toString());
}
@Override
public void onSubscriptionStateChanged(Core core, Event event, SubscriptionState subscriptionState) {
}
@Override
public void onNotifyReceived(Core core, Event event, String s, Content content) {
}
@Override
public void onSubscribeReceived(Core core, Event event, String s, Content content) {
}
@Override
public void onPublishStateChanged(Core core, Event event, PublishState publishState) {
Log.e(TAG, ">onInfoReceived " + publishState);
}
@Override
public void onConfiguringStatus(Core core, ConfiguringState configuringState, String s) {
}
@Override
public void onNetworkReachable(Core core, boolean b) {
}
@Override
public void onLogCollectionUploadStateChanged(Core core, Core.LogCollectionUploadState logCollectionUploadState, String s) {
}
@Override
public void onLogCollectionUploadProgressIndication(Core core, int i, int i1) {
}
@Override
public void onFriendListCreated(Core core, FriendList friendList) {
}
@Override
public void onFriendListRemoved(Core core, FriendList friendList) {
}
@Override
public void onCallCreated(Core core, Call call) {
Log.e(TAG, ">onCallCreated " + call + "" + call.getRemoteAddressAsString());
}
@Override
public void onVersionUpdateCheckResultReceived(Core core, VersionUpdateCheckResult versionUpdateCheckResult, String s, String s1) {
}
@Override
public void onChatRoomStateChanged(Core core, ChatRoom chatRoom, ChatRoom.State state) {
}
@Override
public void onQrcodeFound(Core core, String s) {
}
@Override
public void onEcCalibrationResult(Core core, EcCalibratorStatus ecCalibratorStatus, int i) {
}
@Override
public void onEcCalibrationAudioInit(Core core) {
}
@Override
public void onEcCalibrationAudioUninit(Core core) {
}
/**
* -------------------------------------------linphone监听 结束----------------------------------------------------------------------------------------------
*/
/**
* -------------------------------------------linphone公开方法 开始----------------------------------------------------------------------------------------------
* 注册
*
* @param host
* @param username
* @param password
* @param transport
* @throws Exception
*/
public void lilin_reg(String host, String username, String password, TransportType transport) throws Exception {
if (mLinPhoneCore == null) {
return;
}
Log.e(TAG, "lilin_reg 开始注册-->host: " + host + " username-->" + username + " password-->" + password + " transport-->" + transport);
for (ProxyConfig linphoneProxyConfig : mLinPhoneCore.getProxyConfigList()) {
mLinPhoneCore.removeProxyConfig(linphoneProxyConfig);
}
for (AuthInfo x : mLinPhoneCore.getAuthInfoList()) {
mLinPhoneCore.removeAuthInfo(x);
}
AccountBuilder builder = new AccountBuilder(mLinPhoneCore)
.setUsername(username)
.setDomain(host)
.setHa1(null)
.setUserid(username)
.setDisplayName("")//显示名
.setPassword(password);
builder.setAvpfEnabled(false);
String prefix = null;
if (prefix != null) {
builder.setPrefix(prefix);
}
String forcedProxy = "";//"39.108.0.211:11889";
if (!TextUtils.isEmpty(forcedProxy)) {
builder.setServerAddr(forcedProxy).setOutboundProxyEnabled(true);// .setAvpfRrInterval(5);
}
if (transport != null) {
builder.setTransport(transport);
}
try {
builder.saveNewAccount();
} catch (CoreException e) {
Log.e(TAG, ">tishi >>>>" + e.getMessage());
}
}
/**
* 初始化sip电话线程池
*/
private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1), new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setName("sip电话线程池");
return thread;
}
});
/**
* 打电话
*
* @param username
* @param host
* @param isVideoCall
*/
public void lilin_call(final String username, final String host, final boolean isVideoCall) {
threadPool.execute(() -> {
if (mLinPhoneCore == null) {
return;
}
Log.e(TAG, "lilin_call打电话 username-->" + username + " host-->" + host + " isVideoCall-->" + isVideoCall);
Address address = mLinPhoneCore.interpretUrl(username + "@" + host);
address.setDisplayName(username);
CallParams params = mLinPhoneCore.createCallParams(null);
//params.enableLowBandwidth(true);
//params.setAudioBandwidthLimit(0);
params.enableVideo(isVideoCall);
Call call = mLinPhoneCore.inviteAddressWithParams(address, params);
if (call == null) {
Log.e(TAG, "lilin error Could not place call to " + username);
}
});
}
/**
* 终止所有Calls
*/
public void hangUp() {
if (mLinPhoneCore == null) {
return;
}
mLinPhoneCore.terminateAllCalls();
}
/**
* 开启扩音或关闭
*/
public void lilin_enkuo() {
if (mAudioManager == null) {
return;
}
mAudioManager.setSpeakerphoneOn(mAudioManager.isSpeakerphoneOn() ? false : true);
}
/**
* 接电话
*/
public void liLinJie() {
threadPool.execute(() -> {
if (mLinPhoneCore == null) return;
Log.e(TAG, "liLinJie: 接电话");
Call currentCall = mLinPhoneCore.getCurrentCall();
if (currentCall != null) {
CallParams params = mLinPhoneCore.createCallParams(currentCall);
CallParams remoteParams = currentCall.getRemoteParams();
if (remoteParams != null && remoteParams.videoEnabled()) {
params.enableVideo(false);
Log.e(Thread.currentThread().getName(), "视频通话 模式" + getLC().getVideoPreset() + "fps" + getLC().getPreferredFramerate() + "带宽" + getLC().getUploadBandwidth() + "分辨率" + getLC().getPreferredVideoDefinition().getHeight());
} else {
Log.e(Thread.currentThread().getName(), "音频通话通话");
}
currentCall.acceptWithParams(params);
}
});
}
/**
* 获取Config配置
*
* @return
*/
public Config getConfig() {
Core core = getLC();
if (core != null) {
return core.getConfig();
}
if (!LinphoneMiniManager.isReady()) {
File linphonerc = new File(mContext.getFilesDir().getAbsolutePath() + "/.linphonerc");
if (linphonerc.exists()) {
return Factory.instance().createConfig(linphonerc.getAbsolutePath());
} else if (mContext != null) {
InputStream inputStream = mContext.getResources().openRawResource(R.raw.linphonerc_default);
InputStreamReader inputreader = new InputStreamReader(inputStream);
BufferedReader buffreader = new BufferedReader(inputreader);
StringBuilder text = new StringBuilder();
String line;
try {
while ((line = buffreader.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return Factory.instance().createConfigFromString(text.toString());
}
} else {
return Factory.instance().createConfig(mContext.getFilesDir().getAbsolutePath() + "/.linphonerc");
}
return null;
}
public String getPreferredVideoSize() {
return getConfig().getString("video", "size", "qvga");
}
public void setPreferredVideoSize(String preferredVideoSize) {
if (getLC() == null) {
return;
}
VideoDefinition preferredVideoDefinition = Factory.instance().createVideoDefinitionFromName(preferredVideoSize);
getLC().setPreferredVideoDefinition(preferredVideoDefinition);
}
/**
* -------------------------------------------linphone公开方法 结束----------------------------------------------------------------------------------------------
*/
}