package com.hdl.hdllinphonesdk;
|
|
import android.content.Context;
|
import android.content.Intent;
|
import android.view.TextureView;
|
import android.widget.Toast;
|
|
import com.hdl.hdllinphonesdk.activity.HDLLinphoneIntercomActivity;
|
import com.hdl.hdllinphonesdk.callback.OnHDLLinphoneCallListener;
|
import com.hdl.hdllinphonesdk.callback.OnLPOpenDoorCallBack;
|
import com.hdl.hdllinphonesdk.core.callback.PhoneCallback;
|
import com.hdl.hdllinphonesdk.core.callback.RegistrationCallback;
|
import com.hdl.hdllinphonesdk.core.service.HDLLinphoneService;
|
import com.hdl.hdllinphonesdk.utils.HDLLog;
|
|
import org.linphone.core.AccountCreator;
|
import org.linphone.core.Address;
|
import org.linphone.core.AudioDevice;
|
import org.linphone.core.AuthInfo;
|
import org.linphone.core.Call;
|
import org.linphone.core.CallParams;
|
import org.linphone.core.Core;
|
import org.linphone.core.CoreException;
|
import org.linphone.core.Factory;
|
import org.linphone.core.ProxyConfig;
|
import org.linphone.core.TransportType;
|
|
import static java.lang.Thread.sleep;
|
|
/**
|
* Created by jlchen on 2021/8/4.
|
*/
|
public class HDLLinphoneKit {
|
public static final String KEY_TITLE_NAME = "lpTitleName";
|
public static final String HDLLinphoneKitNAME = "HDLLinphoneKit";
|
private volatile static HDLLinphoneKit instance;
|
private Context viewContext;
|
private ServiceWaitThread mServiceWaitThread;
|
private String mUsername, mPassword, mServerIP;
|
// private TextureView mRenderingView, mPreviewView;
|
private boolean isAutoJumpCallView;//是否自动跳转呼叫页面
|
|
private HDLLinphoneKit() {
|
|
}
|
|
/**
|
* getInstance
|
* @return HDLLinphoneKit
|
*/
|
public static synchronized HDLLinphoneKit getInstance() {
|
if (instance == null) {
|
synchronized (HDLLinphoneKit.class) {
|
if (instance == null) {
|
instance = new HDLLinphoneKit();
|
}
|
}
|
}
|
return instance;
|
}
|
|
/**
|
* 获取 LinphoneCore
|
*
|
* @return Core
|
*/
|
public Core getCore() {
|
if(!HDLLinphoneService.isReady()){
|
CheckIfNeedstartService();
|
return null;
|
}else {
|
return HDLLinphoneService.getCore();
|
}
|
}
|
|
/**
|
* 初始化Linphone
|
* @param context
|
*/
|
public void initLinphone(Context context) {
|
viewContext = context.getApplicationContext();
|
if (!HDLLinphoneService.isReady()) {
|
CheckIfNeedstartService();
|
} else {
|
|
}
|
}
|
|
/**
|
* startService
|
*/
|
private synchronized void CheckIfNeedstartService(){
|
startService(viewContext);
|
addCallback(new RegistrationCallback() {
|
@Override
|
public void registrationOk() {
|
super.registrationOk();
|
HDLLog.e(HDLLinphoneKitNAME, "registrationOk: ");
|
callBackRegistrationOk(viewContext);
|
|
}
|
|
@Override
|
public void registrationFailed() {
|
super.registrationFailed();
|
HDLLog.e(HDLLinphoneKitNAME, "registrationFailed: ");
|
// Toast.makeText(LoginActivity.this, "登录失败!", Toast.LENGTH_SHORT).show();
|
}
|
}, null);
|
}
|
|
/**
|
* 注册成功后,注册呼叫监听
|
*/
|
void callBackRegistrationOk(Context context) {
|
addCallback(null, new PhoneCallback() {
|
@Override
|
public void incomingCall(Call linphoneCall) {
|
super.incomingCall(linphoneCall);
|
if (linphoneCall != null) {
|
String callUsername = linphoneCall.getRemoteAddress().getUsername();
|
HDLLog.I("来电号码:" + callUsername);
|
// HDLLog.Log("来电号码DisplayName:" + linphoneCall.getRemoteAddress().getDisplayName());
|
if (mOnHDLLinphoneCallListener != null) {
|
mOnHDLLinphoneCallListener.onIncomingCall(callUsername);
|
}
|
}
|
|
if (isAutoJumpCallView) {
|
//是否需要自动打开呼叫页面
|
gotoHDLLinphoneIntercomActivity();
|
}
|
}
|
|
@Override
|
public void outgoingInit() {
|
super.outgoingInit();
|
|
}
|
|
@Override
|
public void callConnected() {
|
super.callConnected();
|
// 视频通话默认免提,语音通话默认非免提
|
toggleSpeaker(true);
|
// 所有通话默认非静音
|
toggleMicro(false);
|
}
|
|
@Override
|
public void callEnd() {
|
super.callEnd();
|
// context.sendBroadcast(new Intent(HDLLinphoneIntercomActivity.RECEIVE_FINISH_VIDEO_ACTIVITY));
|
|
}
|
});
|
}
|
|
/**
|
* 跳转打开呼叫页面
|
*/
|
public void gotoHDLLinphoneIntercomActivity() {
|
Intent intent = new Intent(viewContext, HDLLinphoneIntercomActivity.class);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
viewContext.startActivity(intent);
|
}
|
|
/**
|
* 开启服务
|
*
|
* @param context 上下文
|
*/
|
public void startService(Context context) {
|
try {
|
if (!HDLLinphoneService.isReady()) {
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
intent.setClass(context, HDLLinphoneService.class);
|
context.startService(intent);
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
// context.startForegroundService(intent);//解决android8.0以上无法启动服务的问题
|
// } else {
|
// context.startService(intent);
|
// }
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* onResume
|
*/
|
public void onResume() {
|
|
}
|
|
/**
|
* onPause
|
*/
|
public void onPause() {
|
|
}
|
|
/**
|
* onDestroy
|
*/
|
public void onDestroy() {
|
removePreviewWindow();
|
removeVideoWindow();
|
}
|
|
/**
|
* 设置 sip 账户信息
|
*
|
* @param username sip 账户
|
* @param password 密码
|
* @param serverIP sip 服务器
|
*/
|
public void setAccountAndLogin(String username, String password, String serverIP) {
|
mUsername = username;
|
mPassword = password;
|
mServerIP = serverIP;
|
login();
|
}
|
|
/**
|
* 添加注册状态、通话状态回调
|
*
|
* @param phoneCallback 通话回调
|
* @param registrationCallback 注册状态回调
|
*/
|
public void addCallback(RegistrationCallback registrationCallback,
|
PhoneCallback phoneCallback) {
|
if (HDLLinphoneService.isReady()) {
|
HDLLinphoneService.addRegistrationCallback(registrationCallback);
|
HDLLinphoneService.addPhoneCallback(phoneCallback);
|
} else {
|
mServiceWaitThread = new ServiceWaitThread(registrationCallback, phoneCallback);
|
mServiceWaitThread.start();
|
}
|
}
|
|
/**
|
* 登录到 SIP 服务器
|
*/
|
public void login() {
|
new Thread(new Runnable() {
|
@Override
|
public void run() {
|
while (!HDLLinphoneService.isReady()) {
|
try {
|
sleep(80);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
}
|
loginToServer();
|
}
|
}).start();
|
}
|
|
/**
|
* 退出清空账号
|
* enableRegister false
|
*/
|
public void logout() {
|
try {
|
Core core = HDLLinphoneService.getCore();
|
if (core != null) {
|
ProxyConfig[] configs = core.getProxyConfigList();
|
for (ProxyConfig config : configs) {
|
if (config != null) {
|
config.edit();
|
config.enableRegister(false);
|
config.done();
|
}
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 清除配置表, 切换账号时会用到
|
*/
|
public void clearProxyConfig(){
|
Core core = HDLLinphoneService.getCore();
|
if (core != null) {
|
core.setDefaultProxyConfig(null);
|
core.clearAllAuthInfo();//清除所有认证信息。
|
core.clearProxyConfig();//从配置中删除所有代理。
|
}
|
}
|
|
/**
|
* ServiceWaitThread
|
*/
|
private class ServiceWaitThread extends Thread {
|
private PhoneCallback mPhoneCallback;
|
private RegistrationCallback mRegistrationCallback;
|
|
ServiceWaitThread(RegistrationCallback registrationCallback, PhoneCallback phoneCallback) {
|
mRegistrationCallback = registrationCallback;
|
mPhoneCallback = phoneCallback;
|
}
|
|
@Override
|
public void run() {
|
super.run();
|
while (!HDLLinphoneService.isReady()) {
|
try {
|
sleep(80);
|
} catch (InterruptedException e) {
|
throw new RuntimeException("waiting thread sleep() has been interrupted");
|
}
|
}
|
HDLLinphoneService.addPhoneCallback(mPhoneCallback);
|
HDLLinphoneService.addRegistrationCallback(mRegistrationCallback);
|
mServiceWaitThread = null;
|
}
|
}
|
|
/**
|
* 登录 SIP 服务器
|
*/
|
private void loginToServer() {
|
try {
|
if (mUsername == null || mPassword == null || mServerIP == null) {
|
throw new RuntimeException("The sip account is not configured.");
|
}
|
registerUserAuth(mUsername, mPassword, mServerIP);
|
} catch (CoreException e) {
|
e.printStackTrace();
|
}
|
}
|
/**
|
* 提交账号和密码注册到服务器
|
*
|
* @param name
|
* @param password
|
* @param host
|
* @throws CoreException
|
*/
|
public void registerUserAuth(String name, String password, String host) throws CoreException {
|
Core mLinphoneCore = HDLLinphoneService.getCore();
|
if(mLinphoneCore == null) return;
|
|
AuthInfo authInfo = Factory.instance().createAuthInfo(name, null, password,
|
null, null, host);
|
|
AccountCreator mAccountCreator = mLinphoneCore.createAccountCreator(null);
|
mAccountCreator.setUsername(name);
|
mAccountCreator.setDomain(host);
|
mAccountCreator.setPassword(password);
|
mAccountCreator.setTransport(TransportType.Udp);
|
ProxyConfig prxCfg = mAccountCreator.createProxyConfig();
|
|
prxCfg.enableQualityReporting(false);
|
prxCfg.setQualityReportingCollector(null);
|
prxCfg.setQualityReportingInterval(0);
|
prxCfg.enableRegister(true);
|
mLinphoneCore.addProxyConfig(prxCfg);//添加代理配置。如果启用了注册,这将开始在代理上注册。
|
mLinphoneCore.addAuthInfo(authInfo);//添加认证信息到,该信息片段将在所有需要的SIP事务中使用身份验证
|
mLinphoneCore.setDefaultProxyConfig(prxCfg);//设置默认代理。
|
}
|
|
/**
|
* 呼叫
|
*/
|
public Call startSingleCallingTo(String userName, boolean isVideoCall) {
|
Core mLinphoneCore = HDLLinphoneService.getCore();
|
if(mLinphoneCore == null) return null;
|
|
Call call = null;
|
Core core = HDLLinphoneService.getCore();
|
if(core != null) {
|
Address addressToCall = core.interpretUrl(userName);
|
CallParams params = core.createCallParams(null);
|
|
if (isVideoCall) {
|
params.enableVideo(true);
|
params.enableLowBandwidth(false);
|
} else {
|
params.enableVideo(false);
|
}
|
|
if (addressToCall != null) {
|
call = core.inviteAddressWithParams(addressToCall, params);
|
}
|
}
|
return call;
|
}
|
|
/**
|
* 呼叫指定号码
|
*
|
* @param num 呼叫号码
|
*/
|
public void callTo(String num, boolean isVideoCall) {
|
if (!HDLLinphoneService.isReady() || !HDLLinphoneService.getCoreIsNotNull()) {
|
return;
|
}
|
if (!num.equals("")) {
|
startSingleCallingTo(num, isVideoCall);
|
}
|
}
|
|
/**
|
* 接听来电
|
*/
|
public void acceptCall() {
|
try {
|
if(HDLLinphoneService.getCore() == null) return;
|
Call currentCall = HDLLinphoneService.getCore().getCurrentCall();
|
CallParams params = HDLLinphoneService.getCore().createCallParams(currentCall);
|
params.enableVideo(true);
|
currentCall.acceptWithParams(params);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 接听来电
|
*/
|
public void acceptCallWithVideo(boolean enableVideo) {
|
try {
|
if(HDLLinphoneService.getCore() == null) return;
|
Call currentCall = HDLLinphoneService.getCore().getCurrentCall();
|
CallParams params = HDLLinphoneService.getCore().createCallParams(currentCall);
|
params.enableVideo(enableVideo);
|
currentCall.acceptWithParams(params);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 挂断电话
|
*/
|
public void hangUp() {
|
Core mLinphoneCore = HDLLinphoneService.getCore();
|
if(mLinphoneCore == null) return;
|
Call currentCall = mLinphoneCore.getCurrentCall();
|
if (currentCall != null) {
|
// mLinphoneCore.terminateCall(currentCall);
|
mLinphoneCore.terminateAllCalls();
|
} else if (mLinphoneCore.isInConference()) {
|
mLinphoneCore.terminateConference();
|
} else {
|
mLinphoneCore.terminateAllCalls();
|
}
|
}
|
|
/**
|
* 是否静音
|
*
|
* @param isMicMuted
|
*/
|
public void toggleMicro(boolean isMicMuted) {
|
Core mLinphoneCore = HDLLinphoneService.getCore();
|
if(mLinphoneCore == null) return;
|
mLinphoneCore.enableMic(!isMicMuted);
|
}
|
|
/**
|
* 是否外放
|
*
|
* @param isSpeakerEnabled
|
*/
|
public void toggleSpeaker(boolean isSpeakerEnabled) {
|
routeAudioToSpeakerHelper(isSpeakerEnabled);
|
}
|
|
/**
|
* 设置外放设备
|
*/
|
private void routeAudioToSpeakerHelper(boolean speakerOn) {
|
org.linphone.core.tools.Log.w("[Audio Manager] Routing audio to " + (speakerOn ? "speaker" : "earpiece"));
|
try {
|
if(HDLLinphoneService.getCore() == null) return;
|
if (HDLLinphoneService.getCore().getCallsNb() == 0) return;
|
Call currentCall = HDLLinphoneService.getCore().getCurrentCall();
|
if (currentCall == null) currentCall = HDLLinphoneService.getCore().getCalls()[0];
|
if (currentCall == null) return;
|
|
for (AudioDevice audioDevice : HDLLinphoneService.getCore().getAudioDevices()) {
|
if (speakerOn && audioDevice.getType() == AudioDevice.Type.Speaker) {
|
currentCall.setOutputAudioDevice(audioDevice);
|
return;
|
} else if (!speakerOn && audioDevice.getType() == AudioDevice.Type.Earpiece) {
|
currentCall.setOutputAudioDevice(audioDevice);
|
return;
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 设置 TextureView
|
*
|
* @param renderingView 远程 TextureView
|
* @param previewView 本地 TextureView
|
*/
|
public void setAndroidVideoWindow(final TextureView renderingView, final TextureView previewView) {
|
// mRenderingView = renderingView;
|
// mPreviewView = previewView;
|
setVideoWindow(renderingView);
|
setPreviewWindow(previewView);
|
|
}
|
|
/**
|
* 设置播放View
|
* @param o
|
*/
|
private void setVideoWindow(Object o) {
|
Core linphoneCore = HDLLinphoneService.getCore();
|
if (linphoneCore != null) {
|
linphoneCore.setNativeVideoWindowId(o);
|
}
|
}
|
/**
|
* 移除播放View
|
*/
|
private void removeVideoWindow() {
|
Core linphoneCore = HDLLinphoneService.getCore();
|
if (linphoneCore != null) {
|
linphoneCore.setNativeVideoWindowId(null);
|
}
|
}
|
|
/**
|
* 设置本机摄像头采集的View
|
* @param o
|
*/
|
private void setPreviewWindow(Object o) {
|
Core linphoneCore = HDLLinphoneService.getCore();
|
if (linphoneCore != null) {
|
linphoneCore.setNativePreviewWindowId(o);
|
}
|
}
|
/**
|
* 移除视频采集View
|
*/
|
private void removePreviewWindow() {
|
Core linphoneCore = HDLLinphoneService.getCore();
|
if (linphoneCore != null) {
|
linphoneCore.setNativePreviewWindowId(null);
|
}
|
}
|
|
/**
|
* 获取当前通话状态
|
*/
|
public Call.State getCallState() {
|
return HDLLinphoneService.getInstance().getCurrentCallState();
|
}
|
|
/**
|
* 获取当前通话状态是否为来电中
|
*/
|
public boolean isIncomingReceivedCallState() {
|
return HDLLinphoneService.getInstance().getCurrentCallState() == Call.State.IncomingReceived;
|
}
|
|
/**
|
* 是否自动跳转呼叫页面方案
|
*/
|
public boolean isAutoJumpCallView() {
|
return isAutoJumpCallView;
|
}
|
|
/**
|
* 设置是否自动跳转呼叫页面标志
|
* @param autoJumpCallView
|
*/
|
public void setAutoJumpCallView(boolean autoJumpCallView) {
|
isAutoJumpCallView = autoJumpCallView;
|
}
|
|
/**
|
* 开门回调接口
|
*/
|
private OnLPOpenDoorCallBack openOpenDoorCallBack;
|
|
/**
|
* setOpenOpenDoorCallBack
|
*/
|
public void setOpenOpenDoorCallBack(OnLPOpenDoorCallBack openOpenDoorCallBack) {
|
this.openOpenDoorCallBack = openOpenDoorCallBack;
|
}
|
|
/**
|
* 通知开门成功
|
*/
|
public void onOpenSuccess() {
|
if (openOpenDoorCallBack != null) {
|
openOpenDoorCallBack.onOpenSuccess();
|
}
|
}
|
|
/**
|
* 通知开门失败
|
*/
|
public void onOpenError(String mes) {
|
if (openOpenDoorCallBack != null) {
|
openOpenDoorCallBack.onOpenError(mes);
|
}
|
}
|
|
/**
|
* 呼叫页面相关操作回调接口
|
*/
|
private OnHDLLinphoneCallListener mOnHDLLinphoneCallListener;
|
|
/**
|
* 获取onHDLLinphoneCallListener
|
* 接听、挂断、开锁等 Listener实现
|
* @return OnHDLLinphoneCallListener
|
*/
|
public OnHDLLinphoneCallListener getOnHDLLinphoneCallListener() {
|
return mOnHDLLinphoneCallListener;
|
}
|
|
/**
|
* 设置onHDLLinphoneCallListener
|
* @param onHDLLinphoneCallListener
|
*/
|
public void setOnHDLLinphoneCallListener(OnHDLLinphoneCallListener onHDLLinphoneCallListener) {
|
mOnHDLLinphoneCallListener = onHDLLinphoneCallListener;
|
}
|
|
/**
|
* showToast
|
*/
|
private void showToast(String text) {
|
Toast.makeText(viewContext, text, Toast.LENGTH_SHORT).show();
|
}
|
}
|