Linphone的使用
前些日子因为工作需要接触到SIP电话里的东西在各个网站上闲逛,发现了Linphone本来想先学这个东西。PJSIP是的,但是我的电脑编译有问题,所以我先研究一下linphone是的。因为它的集成相对方便,通过gradle集成即可。linphone这里就不描述相关的发展历史了。http://www.linphone.org/有介绍。去官网了解一下。以下是记录我学习集成的过程。
LinPhone的集成
我使用linphone语音通话和视频通话受网络环境影响。 :建议使用4个版本.2以上,因为4.以下版本跟4.2以上版本会有一些不同的类别或者已经去掉了。
implementation 'org.linphone:linphone-sdk-android:4.2 ' class PhoneVoiceUtils private constructor() { private var mLinphoneCore: Core? = null /** * 注册到服务器 * * @param name 账号名 * @param password 密码 * @param host IP地址:端口号 */ @JvmOverloads fun registerUserAuth( name: String?, password: String?, host: String?, type: TransportType? = TransportType.Udp ) { unRegisterUserAuth() // String identify = "sip:" name "@" host; val mAccountCreator = mLinphoneCore!!.createAccountCreator(null) mAccountCreator.username = name mAccountCreator.domain = host mAccountCreator.password = password mAccountCreator.transport = type val cfg = mAccountCreator.createProxyConfig() // Make sure the newly created one is the default mLinphoneCore!!.defaultProxyConfig = cfg } //取消注册 fun unRegisterUserAuth() { mLinphoneCore!!.clearAllAuthInfo() } /** * 注册了吗?* * @return */ val isRegistered: Boolean get() {
val serverBean: ServerBean? = mcontext?.let {
ServerInfo.getInfo(it) } val authInfos = mLinphoneCore!!.authInfoList if (authInfos.size > 0) {
for (authInfo in authInfos) {
if (authInfo.domain == serverBean?.domainPref) {
return true } } } return false } /** * 拨打电话 * * @param phone 手机号 * @return */ fun startSingleCallingTo( phone: String?, isVideoCall: Boolean ): Call? {
var call: Call? = null try {
val addressToCall = mLinphoneCore!!.interpretUrl(phone) val params = mLinphoneCore!!.createCallParams(null) params.enableVideo(false) if (addressToCall != null) {
call = mLinphoneCore!!.inviteAddressWithParams(addressToCall, params) } } catch (e: Exception) {
e.printStackTrace() } return call } /** * 挂断电话 */ fun hangUp() {
if (mLinphoneCore == null) {
mLinphoneCore = LinphoneManager.core } val currentCall = mLinphoneCore!!.currentCall if (currentCall != null) {
mLinphoneCore!!.terminateCall(currentCall) } else if (mLinphoneCore!!.isInConference) {
mLinphoneCore!!.terminateConference() } else {
mLinphoneCore!!.terminateAllCalls() } } /** * 是否静音 * * @param isMicMuted */ fun toggleMicro(isMicMuted: Boolean) {
if (mLinphoneCore == null) {
mLinphoneCore = LinphoneManager.core } mLinphoneCore!!.enableMic(isMicMuted) } /** * 接听来电 * * @param */ fun receiveCall() {
if (mLinphoneCore == null) {
mLinphoneCore = LinphoneManager.core } val call = mLinphoneCore!!.currentCall val isLowBandwidthConnection = !LinPhoneService.instance()?.getApplicationContext()?.let {
isHighBandwidthConnection( it ) }!! val params = mLinphoneCore!!.createCallParams(call) if (params != null) {
if (call!!.remoteParams.videoEnabled()) {
params.enableVideo(true) mLinphoneCore!!.enableVideoCapture(true) mLinphoneCore!!.enableVideoDisplay(true) } params.enableLowBandwidth(isLowBandwidthConnection) } android.util.Log.i( "infos", "来电是否视频:" + params!!.videoEnabled() + call!!.remoteParams.videoEnabled() ) call?.acceptWithParams(params) val remoteParams = call.remoteParams if (remoteParams != null && remoteParams.videoEnabled()) {
switchVideo(true) } else {
switchVideo(false) } } companion object {
@Volatile private var sPhoneVoiceUtils: PhoneVoiceUtils? = null private var mcontext: Context? = null fun getInstance(context: Context?): PhoneVoiceUtils {
mcontext = context if (sPhoneVoiceUtils == null) {
synchronized(PhoneVoiceUtils::class.java) {
if (sPhoneVoiceUtils == null) {
sPhoneVoiceUtils = PhoneVoiceUtils() } } } return sPhoneVoiceUtils!! } /** * 获取 LinphoneCore * @return LinphoneCore */ val lC: Core? get() = LinphoneManager.core } init {
mLinphoneCore = LinphoneManager.core }}
/** * 初始化 linphone */class LinphoneManager(private val mServiceContext: Context) : SensorEventListener {
private var mLinphoneFactoryConfigFile: String? = null var mLinphoneConfigFile: String? = null private var mAudioManager: AndroidAudioManager? = null private val mCallManager: CallManager? private val mPowerManager: PowerManager private var mLPConfigXsd: String? = null private var mLinphoneRootCaFile: String? = null private var mRingSoundFile: String? = null private var mRingBackSoundFile: String? = null private var mPauseSoundFile: String? = null private var mChatDatabaseFile: String? = null private var mUserCerts: String? = null private val mResources: Resources private var mProximitySensingEnabled = false private val mHasLastCallSasBeenRejected = false private val mIterateRunnable: Runnable? = null private var mProximityWakelock: WakeLock? = null private var mSensorManager: SensorManager ? = null private var mProximity: Sensor? = null private var mCore: Core? = null private var mCoreListener: CoreListener? = null private var mTimer: Timer? = null private val mHandler: Handler/***开始加载LinPhone**/ @Synchronized private fun startLibLinphone( context: Context, coreListener: CoreListener ) {
try {
mCoreListener = coreListener copyAssetsFromPackage() // Create the Core and add our listener mCore = Factory.instance() .createCore(mLinphoneConfigFile, mLinphoneFactoryConfigFile, context) mCore?.addListener(coreListener) mAudioManager = AndroidAudioManager(mServiceContext) initLibLinphone() //加载LinPhone // Core must be started after being created and configured mCore?.start() // We also MUST call the iterate() method of the Core on a regular basis val lTask: TimerTask = object : TimerTask() {
override fun run() {
mHandler.post {
if (mCore != null) {
mCore!!.iterate() } } } } mTimer = Timer("Linphone scheduler") mTimer!!.schedule(lTask, 0, 20) mProximityWakelock = mPowerManager.newWakeLock( PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, mServiceContext.pack