| | |
| | | |
| | | |
| | | import com.hdl.hdllinphonesdk.R; |
| | | import com.hdl.hdllinphonesdk.activity.HDLLinphoneIntercomActivity; |
| | | import com.hdl.hdllinphonesdk.activity.HDLLinphoneReverseCallActivity; |
| | | import com.hdl.hdllinphonesdk.core.callback.PhoneCallback; |
| | | import com.hdl.hdllinphonesdk.core.callback.RegistrationCallback; |
| | | import com.hdl.hdllinphonesdk.core.linphone.KeepAliveHandler; |
| | |
| | | } |
| | | |
| | | public static Core getCore() { |
| | | if(sInstance == null){ |
| | | if (sInstance == null) { |
| | | return null; |
| | | } |
| | | return sInstance.mCore; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public IBinder onBind(Intent intent) { |
| | |
| | | |
| | | /** |
| | | * 添加通话状态回调 |
| | | * |
| | | * @param phoneCallback |
| | | */ |
| | | public static void addPhoneCallback(PhoneCallback phoneCallback) { |
| | | sPhoneCallback = phoneCallback; |
| | | } |
| | | |
| | | public static void removePhoneCallback() { |
| | | if (sPhoneCallback != null) { |
| | | sPhoneCallback = null; |
| | |
| | | |
| | | /** |
| | | * 添加注册状态回调 |
| | | * |
| | | * @param registrationCallback |
| | | */ |
| | | public static void addRegistrationCallback(RegistrationCallback registrationCallback) { |
| | | sRegistrationCallback = registrationCallback; |
| | | } |
| | | |
| | | public static void removeRegistrationCallback() { |
| | | if (sRegistrationCallback != null) { |
| | | sRegistrationCallback = null; |
| | |
| | | new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | mHandler.post( |
| | | new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | if (mCore != null) { |
| | | mCore.iterate(); |
| | | } |
| | | } |
| | | }); |
| | | mHandler.post(() -> { |
| | | if (mCore != null) { |
| | | mCore.iterate(); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | mTimer = new Timer("Linphone scheduler"); |
| | |
| | | public void onDestroy() { |
| | | removeAllCallback(); |
| | | logout(); |
| | | mCore.removeListener(mCoreListener); |
| | | mTimer.cancel(); |
| | | mCore.stop(); |
| | | // A stopped Core can be started again |
| | | // To ensure resources are freed, we must ensure it will be garbage collected |
| | | mCore = null; |
| | | |
| | | if (mTimer != null) { |
| | | mTimer.cancel(); |
| | | } |
| | | |
| | | if (mCore != null) { |
| | | mCore.removeListener(mCoreListener); |
| | | mCore.stop(); |
| | | // A stopped Core can be started again |
| | | // To ensure resources are freed, we must ensure it will be garbage collected |
| | | mCore = null; |
| | | } |
| | | // Don't forget to free the singleton as well |
| | | sInstance = null; |
| | | |
| | |
| | | * 初始化Linphone |
| | | */ |
| | | private void initLinphone() { |
| | | currentCallState = Call.State.Idle; |
| | | String basePath = getFilesDir().getAbsolutePath(); |
| | | Factory.instance().setLogCollectionPath(basePath); |
| | | Factory.instance().enableLogCollection(LogCollectionState.Enabled); |
| | |
| | | initCoreListener(); |
| | | copyAssetsFromPackage(basePath); |
| | | // Create the Core and add our listener |
| | | mCore = Factory.instance() |
| | | .createCore(basePath + "/.linphonerc", basePath + "/linphonerc", this); |
| | | mCore = Factory.instance().createCore(basePath + "/.linphonerc", |
| | | basePath + "/linphonerc", this); |
| | | mCore.addListener(mCoreListener); |
| | | // Core is ready to be configured |
| | | configureCore(); |
| | |
| | | @Override |
| | | public void onCallStateChanged(Core core, Call linphoneCall, Call.State state, String message) { |
| | | HDLLog.e(START_LINPHONE_LOGS, "callState: " + state.toString()); |
| | | HDLLog.e(START_LINPHONE_LOGS, "state.toInt()=" + state.toInt() + "==============message=========: " + message); |
| | | currentCallState = state; |
| | | if (sPhoneCallback != null) { |
| | | if (state == Call.State.IncomingReceived) { |
| | |
| | | } else if (state == Call.State.Connected) { |
| | | sPhoneCallback.callConnected(); |
| | | } else if (state == Call.State.Error) { |
| | | sPhoneCallback.error(); |
| | | sPhoneCallback.error(message); |
| | | } else if (state == Call.State.End) { |
| | | sPhoneCallback.callEnd(); |
| | | } else if (state == Call.State.Released) { |
| | |
| | | HDLLog.i(START_LINPHONE_LOGS, "registrationState: " + state); |
| | | |
| | | if (state.equals(RegistrationState.None.toString())) { |
| | | if (sRegistrationCallback != null){ |
| | | if (sRegistrationCallback != null) { |
| | | sRegistrationCallback.registrationNone(); |
| | | } |
| | | } else if (state.equals(RegistrationState.Progress.toString())) { |
| | | if (sRegistrationCallback != null){ |
| | | if (sRegistrationCallback != null) { |
| | | sRegistrationCallback.registrationProgress(); |
| | | } |
| | | } else if (state.equals(RegistrationState.Ok.toString())) { |
| | |
| | | |
| | | /** |
| | | * 收到注销成功后移除当前代理 |
| | | * |
| | | * @param core |
| | | * @param proxyConfig |
| | | */ |
| | |
| | | } |
| | | |
| | | //1.设置存储用户x509证书的目录的路径 |
| | | mCore.setUserCertificatesPath(userCerts); |
| | | //mCore.setUserCertificatesPath(userCerts); |
| | | mCore.setUserCertificatesPath(basePath); |
| | | //2.设置UserAgent |
| | | setUserAgent(); |
| | | //3.设置播放铃声 |
| | | // mCore.setNativeRingingEnabled(true); |
| | | // mCore.setRemoteRingbackTone(mRingSoundFile); |
| | | // mCore.setTone(ToneID.CallWaiting, mRingSoundFile); |
| | | // mCore.setRing(mRingSoundFile); |
| | | // mCore.setPlayFile(mPauseSoundFile); |
| | | //4.禁用手机摄像头视频采集 |
| | | // mCore.enableVideoCapture(false);//禁用手机摄像头视频采集 |
| | | mCore.setNetworkReachable(true); |
| | | //3.回声消除 |
| | | // mCore.setNetworkReachable(true); |
| | | //5.回声消除 |
| | | mCore.enableEchoCancellation(true); |
| | | mCore.enableEchoLimiter(true); |
| | | //4.自适应码率控制 |
| | | // mCore.enableEchoLimiter(false); |
| | | mCore.enableMic(true);//启用麦克风 |
| | | //6.自适应码率控制 |
| | | mCore.enableAdaptiveRateControl(true); |
| | | //5.audio 码率设置 |
| | | //7.audio 码率设置 |
| | | mCore.getConfig().setInt("audio", "codec_bitrate_limit", 36); |
| | | //6.视频尺寸偏好设置 默认qvga |
| | | VideoDefinition preferredVideoDefinition = |
| | | Factory.instance().createVideoDefinitionFromName("qvga"); |
| | | mCore.setPreferredVideoDefinition(preferredVideoDefinition); |
| | | //7.设置带宽限制,带宽单位为kbits/s, 0表示无限 |
| | | mCore.setUploadBandwidth(1536); |
| | | mCore.setDownloadBandwidth(1536); |
| | | //8.设置启用H264编码 |
| | | mCore.getConfig().setBool("app", "open_h264_download_enabled", true); |
| | | //9.设置视频的默认策略 |
| | | //8.视频相关设置 |
| | | mCore.setVideoPreset("custom");//视频预设为custom |
| | | mCore.setPreferredFramerate(5);//FPS优先设置为5 |
| | | VideoDefinition preferredVideoDefinition = Factory.instance().createVideoDefinitionFromName("qvga"); |
| | | mCore.setPreferredVideoDefinition(preferredVideoDefinition);//视频尺寸偏好默认qvga |
| | | //9.设置带宽限制,带宽单位为kbits/s, 0表示无限 |
| | | // mCore.setUploadBandwidth(1536); |
| | | // mCore.setDownloadBandwidth(1536); |
| | | //10.设置视频的默认策略 |
| | | VideoActivationPolicy vap = mCore.getVideoActivationPolicy(); |
| | | vap.setAutomaticallyInitiate(true); |
| | | mCore.setVideoActivationPolicy(vap); |
| | | //10.设置编码格式 |
| | | //11.设置编码格式 |
| | | setCodecMime(); |
| | | |
| | | // 全视通sip设置ca证书 |
| | | //mCore.setRootCa(basePath + "/rootca.pem"); |
| | | } |
| | | |
| | | /** |
| | | * 设置编码格式 |
| | | */ |
| | | private void setCodecMime() { |
| | | //1.启用PCMA PCMU 8000Hz |
| | | PayloadType[] ptList = mCore.getAudioPayloadTypes(); |
| | | for (PayloadType pt : ptList) { |
| | | |
| | | org.linphone.mediastream.Log.d("payloadaudio", pt.getMimeType()); |
| | | if (pt.getMimeType().equals("PCMA") && pt.getClockRate() == 8000) { |
| | | // HDLLog.i("payloadaudio", pt.getMimeType()); |
| | | if ((pt.getMimeType().equals("PCMA") || pt.getMimeType().equals("PCMU")) && pt.getClockRate() == 8000) { |
| | | pt.enable(true); |
| | | |
| | | } else { |
| | | pt.enable(false); |
| | | } |
| | | } |
| | | mCore.setAudioPayloadTypes(ptList); |
| | | |
| | | //2.设置VP8、H264、H265 等启用 |
| | | PayloadType[] ptVideoList = mCore.getVideoPayloadTypes(); |
| | | for (PayloadType pt : ptVideoList) { |
| | | // HDLLog.i("VideoPayload", pt.getMimeType()); |
| | | pt.enable(true); |
| | | } |
| | | mCore.setVideoPayloadTypes(ptVideoList); |
| | |
| | | |
| | | /** |
| | | * 设置是否启用铃声,目前发现设置无效待分析原因 |
| | | * |
| | | * @param use |
| | | */ |
| | | public void enableDeviceRingtone(boolean use) { |
| | |
| | | // mPauseSoundFile = basePath + "/toy_mono.wav"; |
| | | // copyIfNotExist(R.raw.toy_mono, basePath + "/toy_mono.wav"); |
| | | |
| | | // String mRootca = basePath + "/rootca.pem"; // 2022-05-23 对接全视通可视对讲添加的证书 |
| | | // copyIfNotExist(R.raw.freeview_rootca, mRootca); |
| | | |
| | | String mLPConfigXsd = basePath + "/lpconfig.xsd"; |
| | | copyIfNotExist(R.raw.lpconfig, mLPConfigXsd); |
| | | |
| | | } catch (IOException ioe) { |
| | | Log.e(ioe); |
| | | } |
| | |
| | | |
| | | /** |
| | | * copyIfNotExist |
| | | * |
| | | * @param ressourceId |
| | | * @param target |
| | | * @throws IOException |
| | |
| | | |
| | | /** |
| | | * copyFromPackage |
| | | * |
| | | * @param ressourceId |
| | | * @param target |
| | | * @throws IOException |
| | |
| | | |
| | | //通知ID |
| | | public static final int NOTIFICATION_ID = 2; |
| | | |
| | | /** |
| | | * 解决android8.0以上无法启动服务的问题 |
| | | */ |
| | | void hdlStartForeground() { |
| | | |
| | | } |
| | | |
| | | /** |
| | | * stopForeground |
| | | */ |