JLChen
2021-08-20 c7f797851aadaeab49a83ce285b6c3fff2971517
HDLLinphoneSDKDemoNew/HDLLinphoneSDK/src/main/java/com/hdl/hdllinphonesdk/HDLLinphoneKit.java
@@ -2,8 +2,6 @@
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;
import android.widget.Toast;
@@ -12,17 +10,20 @@
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.linphone.LinphoneUtils;
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.CallStats;
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;
@@ -31,20 +32,22 @@
 */
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 TextureView mRenderingView, mPreviewView;
    private boolean isAutoJumpCallView;//是否自动跳转呼叫页面
    private HDLLinphoneKit() {
    }
    /**
     * getInstance
     * @return HDLLinphoneKit
     */
    public static synchronized HDLLinphoneKit getInstance() {
        if (instance == null) {
            synchronized (HDLLinphoneKit.class) {
@@ -57,33 +60,53 @@
    }
    /**
     * 获取 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()) {
            startService(context);
            addCallback(new RegistrationCallback() {
                @Override
                public void registrationOk() {
                    super.registrationOk();
                    Log.e(HDLLinphoneKitNAME, "registrationOk: ");
                    callBackRegistrationOk(viewContext);
                }
                @Override
                public void registrationFailed() {
                    super.registrationFailed();
                    Log.e(HDLLinphoneKitNAME, "registrationFailed: ");
//                    Toast.makeText(LoginActivity.this, "登录失败!", Toast.LENGTH_SHORT).show();
                }
            }, null);
            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);
    }
    /**
@@ -94,9 +117,15 @@
            @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);
                    }
                }
                String callUsername = linphoneCall.getRemoteAddress().getUsername();
                HDLLog.E("来电号码:" + callUsername);
                if (isAutoJumpCallView) {
                    //是否需要自动打开呼叫页面
                    gotoHDLLinphoneIntercomActivity();
@@ -137,38 +166,48 @@
    }
    /**
     * showToast
     */
    private void showToast(String text) {
        Toast.makeText(viewContext, text, Toast.LENGTH_SHORT).show();
    }
    /**
     * 开启服务
     *
     * @param context 上下文
     */
    public void startService(Context context) {
        if (!HDLLinphoneService.isReady()) {
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.setClass(context, HDLLinphoneService.class);
            context.startService(intent);
        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();
        }
    }
//    /**
//     * 设置 sip 账户信息
//     *
//     * @param username sip 账户
//     * @param password 密码
//     * @param serverIP sip 服务器
//     */
//    public void setAccount(String username, String password, String serverIP) {
//        mUsername = username;
//        mPassword = password;
//        mServerIP = serverIP;
//    }
    /**
     * onResume
     */
    public void onResume() {
    }
    /**
     * onPause
     */
    public void onPause() {
    }
    /**
     * onDestroy
     */
    public void onDestroy() {
        removePreviewWindow();
        removeVideoWindow();
    }
    /**
     * 设置 sip 账户信息
@@ -222,6 +261,7 @@
    /**
     * 退出清空账号
     * enableRegister false
     */
    public void logout() {
        try {
@@ -235,63 +275,29 @@
                        config.done();
                    }
                }
                core.clearAllAuthInfo();
                core.clearProxyConfig();
                core.clearAllAuthInfo();//清除所有认证信息。
//                core.clearProxyConfig();//从配置中删除所有代理。注意:目前不能直接删所有代理,因为服务器上还是标记已注册
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 呼叫指定号码
     *
     * @param num 呼叫号码
     * 清除配置表, 切换账号时会用到
     */
    public void callTo(String num, boolean isVideoCall) {
        LinphoneUtils.getInstance().callTo(num, isVideoCall);
    public void clearProxyConfig(){
        Core core = HDLLinphoneService.getCore();
        if (core != null) {
            core.clearAllAuthInfo();//清除所有认证信息。
            core.clearProxyConfig();//从配置中删除所有代理。
        }
    }
    /**
     * 接听来电
     * ServiceWaitThread
     */
    public void acceptCall() {
        LinphoneUtils.getInstance().acceptCall();
    }
//    /**
//     * 接听来电
//     */
//    public void acceptCallWithVideo(boolean enableVideo) {
//        LinphoneUtils.getInstance().acceptCallWithVideo(enableVideo);
//    }
    /**
     * 挂断当前通话
     */
    public void hangUp() {
        LinphoneUtils.getInstance().hangUp();
    }
    /**
     * 切换静音
     *
     * @param isMicMuted 是否静音
     */
    public void toggleMicro(boolean isMicMuted) {
        LinphoneUtils.getInstance().toggleMicro(isMicMuted);
    }
    /**
     * 切换免提
     *
     * @param isSpeakerEnabled 是否免提
     */
    public void toggleSpeaker(boolean isSpeakerEnabled) {
        LinphoneUtils.getInstance().toggleSpeaker(isSpeakerEnabled);
    }
    private class ServiceWaitThread extends Thread {
        private PhoneCallback mPhoneCallback;
        private RegistrationCallback mRegistrationCallback;
@@ -325,83 +331,203 @@
            if (mUsername == null || mPassword == null || mServerIP == null) {
                throw new RuntimeException("The sip account is not configured.");
            }
            LinphoneUtils.getInstance().registerUserAuth(mUsername, mPassword, mServerIP);
            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;
//    public static boolean getVideoEnabled() {
//        CallParams remoteParams = HDLLinphoneService.getCore().getCurrentCall().getRemoteParams();
//        return remoteParams != null && remoteParams.videoEnabled();
//    }
        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);//设置默认代理。
    }
    /**
     * 设置 SurfaceView
     * 呼叫
     */
    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;
//        mRenderingView = renderingView;
//        mPreviewView = previewView;
        setVideoWindow(renderingView);
        setPreviewWindow(previewView);
    }
    /**
     * onResume
     * 设置播放View
     * @param o
     */
    public void onResume() {
//        if (mRenderingView != null) {
//            ((TextureView) mRenderingView).onResume();
//        }
//        if (mAndroidVideoWindow != null) {
//            synchronized (mAndroidVideoWindow) {
//                LinphoneManager.getLc().setNativeVideoWindowId(mAndroidVideoWindow);
//            }
//        }
    }
    /**
     * onPause
     */
    public void onPause() {
//        if (mAndroidVideoWindow != null) {
//            synchronized (mAndroidVideoWindow) {
//                LinphoneManager.getLc().setNativeVideoWindowId(null);
//            }
//        }
//
//        if (mRenderingView != null) {
//            ((GLSurfaceView) mRenderingView).onPause();
//        }
    }
    /**
     * onDestroy
     */
    public void onDestroy() {
        mPreviewView = null;
        mRenderingView = null;
    }
//    private void fixZOrder(SurfaceView rendering, SurfaceView preview) {
//        rendering.setZOrderOnTop(false);
//        preview.setZOrderOnTop(true);
//        preview.setZOrderMediaOverlay(true); // Needed to be able to display control layout over
//    }
    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) {
@@ -409,28 +535,25 @@
        }
    }
    /**
     * 设置本机摄像头采集的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);
        }
    }
//    /**
//     * 获取 LinphoneCore
//     *
//     * @return LinphoneCore
//     */
//    public Core getLC() {
//        return HDLLinphoneService.getCore();
//    }
    /**
     * 获取当前通话状态
@@ -452,6 +575,11 @@
    public boolean isAutoJumpCallView() {
        return isAutoJumpCallView;
    }
    /**
     * 设置是否自动跳转呼叫页面标志
     * @param autoJumpCallView
     */
    public void setAutoJumpCallView(boolean autoJumpCallView) {
        isAutoJumpCallView = autoJumpCallView;
    }
@@ -491,12 +619,27 @@
     */
    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();
    }
}