android 打电话模块,Android 语音通话模块介绍(三) CSipSimple介绍

语音通话模块介绍(三) CSipSimple介绍

CSipSimple简介

CSipSimple是基于PJSIP开源协议库实现的Android程序,这里主要围绕CSipSimple的功能实现讲解。凡是在CSipSimple中涉及到的Android知识点以及PJSIP相关内都会进一步的分析。

项目中主要有几个包:

api

包下主要是一些静态的常量,关于

sip

的管理。

db

包当然是数据库了,它也使用了标准的

ContentProvider

,其中一些建表的语句还是用

api

包中的类。

pjsip

就是这个库相关的类了,具体没有研究。在编译

jni

前,这部分是有问题的,因为它需要

jni

的调用,工程也会报错。编译后生成一些

jni

对应的调用文件就正常了,生成的文件在

org.pjsip

下。

utils

包就是一些帮助类,比如配置管理,音频自动聚焦。联系人,剪切版。

widgets

包是一些自定义的控件。

wizards

包是辅助用户的引导用的。

plugins

包是插件,没看出有什么用处。

service

包也是这里的重点:

MediaManager

音频管理的,控制不同的音频流,来电时的音频,蓝牙,静音等。

OutgoingCall

是呼出接收器,先通过这个拦截,可以拦截到系统电话的呼叫,与程序内的呼叫。然后自定义了选择器。

Downloader

处理下载的,更新的时候就是用这个下载的。默认使用的是

cacheDir

目录。

SipNotifications

是一个通知类,主要管理了通知。

SipService

这里的主要服务。

ui

包下就是关于界面的一些类了,

account

是添加帐户的。

filters

是关于帐户的过滤的,还使用了拖动排序的

ListView

calllog

就是通话日志了。日志有选择保存在系统的通话中还是软件中。

incall

就是来电的,与通话界面了。

dialpad

是拨号面板

还有一个包是

org.webrtc.videoengine

,这里是视频通话时用到的,一看名字就知道了

camera

暂时没有找到视频的插件的源码在哪里下载。但有编译好的

apk

。使用

x264

编码。

CSipSimple框架介绍

CSipSimple由应用层,JNI层,驱动层等组成。其中应用层和JNI层是该程序的核心,而驱动层根据设备提供。在应用层中,主要围绕了Android四大组件进行。其中:

Activity:完成界面UI显示;

Intent:主要是实现在Activity和Activity之间的切换

Service:完成activity和后台之间的联系以及进程间的通信

ContentProvider:完成数据保存及共享,主要保存一些设置,用户状态,好友等信息

Broadcast:主要完成在系统内信息的广播,一般会和ContentProvider结合,如当数据改变了,就携带信息发送广播,当所有已注册的广播接收器接收到内容之后进行解析之后进行相应的操作。

在JNI层,因为PJSIP核是基于C语言的,如果要用java调用,就必须封装本地的JNI库,从而实现从上到下的调用。

1 主界面

主界面是SipHome这个Activity。在该Activity中,引入了Andriod新版本才有的actionBar。ActionBar的作用可以统一页面导航和切换方式,可以突出显示一些重要的操作,而把一些不那么重要的或者使用频率低的放在overflow中。所以这里引入了4个Tab,分别对应DialerFragment,CallLogListFragment,FavListFragListFragment和ConversationFragment后通过使用ViewPager实现多页面切换就可以实现这几个activity的呈现。如图1.1:

0818b9ca8b590ca3270a3433284dd417.png

2一些基本参数设置

在进行相关操作,如添加用户,打电话,发送信息之前。一些必要的设置如,只使用WIFI,开启ICE功能,开启STUN功能等参数设置必不可少。所以在刚开始使用时,一般我们会打开上面介绍的设置菜单项,其路径为:com.csipsimple.ui.prefs.hc.MainPrefs这个MainPrefs。 这里讲解MainPrefs这个Acitivty是如何实现的。首先该activity使用“headers”来进行屏幕显示。其界面如图2所示,共有6个header。而通过xml文件下进行相关的xml编写然后在MainPrefs中的onBuilder方法进行加载即可。而各个header都有相应的class。如图1.2:Andriod使用ContentProvider来保存数据。这里参数保存,文件配置在DBProvider.class和Preference中,其中DBProvider中主要和添加用户注册,信息,filter等关联。

0818b9ca8b590ca3270a3433284dd417.png

3 添加用户(注册用户)

1

AccountsEditListFragment

中设置完相关参数信息后,跳转到

BasePrefsWizard

(

Intent

携带

wizardId

,我们这里使用的是

Basic

类型),可根据

wizardId

进行相应

wizard

的实例显示

2

当设置好注册用户的相关数据之后,点击保存按钮之后进入

BasePrefsWizard

下的

saveAccount

函数,在该函数中进行了

getContentResolver

().insert

语句,即关于操作

ContentProvider

的语句。这里根据

Uri

查询后进入

DBProvider

insert

方法,进而执行广播命令

getContext

().

sendBroadcast

(

publishIntent

).

3

Csipsimple

在这里注册了两个广播,一个

AccountWidgetProvider

DynamicReceiver4

,我们这里只用到

DynamicReceiver4

,其注册方式为动态注册(在

SipService

注册了

DynamicReceiver4

广播接收器  )

4

当上面第二点分析的发出广播信息后,主要有两个

reciever

会做出相应的操作,分别

DynamicReceiver4

AccountWidgetProvider

5

DynamicReceiver4

中重写了

onReceive

即也是接收信息的函数。然后进入判断语句,上面发送的广播所携带的信息为

ACTION_SIP_ACCOUNT_CHANGED

这样的

action

根据这个

action

执行了

SipService.setAccountRegistration

()

这个函数,从而跳转到

service

中执行。这里也就是用户开始注册的位置。

6

PJSUA

操作

:

在上面的添加用户操作中,其实已经和底层的

JNI

打交道了,如执行

SipService.setAccountRegistration

()

这个函数之后就会调用底层的

JNI

库。而在执行这些

JNI

库之前。又关于

PJSUA

的一些初始化设置。这一节主要说明这个。在说明进行初始化之前,先说明下

PJSIP

库框架

(

语音通话模块介绍(一))

7

通过

SipService

onStart

()

函数,加载

JNI

(

会跳到

PjSipService

tryToLoadStack

方法执行

) ,

而何时进行

PJSUA

初始化,

CSipSimple

中,在

SipService

开始,当注册完广播接收器之后还进行了这一步:

deviceStateReceiver.startMonitoring

()

,程序进入

DynamicReciever4

startMonitoring

()

函数,进而在

onConnectivityChanged

()

函数中调用了

SipService

restartSipStack

函数,从而进入

startSipStack

()

函数并调用了

pjService.sipStart

()

方法。而这个

sipStart

()

函数就是

PJSUA

初始化的所在处。

8 在

sipStart

函数中,结合

PJSIP

开发文档。从开发文档中我们知道,基础的

PJSUA-API

控制

PJSUA

的创建,初始化,启动,同时还提供各种辅助功能。在

sipStart

函数中,通过

status =

pjsua.create

();

完成

pjsua

的创建,除其他事项外,还初始化

PJLIB

PJLIB-UTIL

,并创建了一个

SIP endpoint

。在调用任何

PJLIB

功能之前这是至关重要的一步。

9  进行了上面的初始化之后,并进行一些

General Configure

。一般情况下,应用程序都将通常需要执行一些任务,使用

pjsua_transport_create

()

方法(该方法是

C

语言)来创建

SIP

传输。故在

CSipSimple

中有

createTransport

这样的方法来创建

SIP

传输。完成这些初始化之后,应用程序必须调用

status =

pjsua.start

()

开始

PJSUA

,此函数将检查所有的配置是否正确,如果没有则采用默认配置

10 在前面步骤中,用户添加是从接收器

DynamicReceiver4

执行了

SipService.setAccountRegistration

这个函数开始的,确切的讲,连接底层

JNI

库的都在

PjSipService

中进行,此处也是这样。进入到

PjSipService

中的

setAccountRegistration

方法。然后根据

account

的不同情况进行不同的操作,首次添加用户将会进行这一步

status =

pjsua.acc_add

(

account.cfg

,

pjsuaConstants.PJ_FALSE

,

accId

)

这里

acc_add

即调用了底层的

JNI

库的

pjsuaJNI.acc_add

从而返回添加成功与否的状态。根据该状态进行相应状态的改变,从而改变显示界面,这个是内容观察者

ContentObserver

的作用,下面这个步骤分析下这个内容观察器。

11 在

CSipSimple

中很多地方使用了

ContentObserver

进行更新。

ContentObserver

是个内容观察者。看过

HeadFirst

模式的话就知道,其实

ContentObserver

正是基于观察者模式实现的。所谓观察者,目的就是观察(捕捉)特定的

Uri

引起的数据库变化,当其所观察的

Uri

发生改变了,便进行触发。正是因为

ContentObserver

的实现是基于观察者模式的,所以其使用显得尤其简单,我们只需创建一个特定的

ContentObserver

派生类(如图),重载父类构造函数以及

onChang

()

方法处理回调后的功能实现(即观察者模式中某一事件发生变化之后进行

notify

),然后要进行相应的注册,即注册内容观察者和取消注册的步骤即基本完成操作

4 拨打电话

Java

层接口调用的是

placeCall

()

函数,进入

placeCall

函数之后,如判断为

SIP

用户,则进行

SipService

方法调用,否则直接进行基本用户拨打,如图程序

:

0818b9ca8b590ca3270a3433284dd417.png

这里只说明使用

SIP

电话拨打情况。程序调用了

SipService

makeCallWithOptions

方法。进而进入

SipService

makeCallWithOptions

方法。如图所示:

0818b9ca8b590ca3270a3433284dd417.png

这样,最终调用

PJsipService

makeCall

。如图所示:

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值