❶ 如何打開slp文件
SLP是模擬的文件。用CIM自帶的模擬軟體打開吧。
不過此文件一般都是在編好以後直接看了,所以一般都把它刪除,沒什麼用
❷ 怎樣打開VOIP與SIP
打開SIP功能的方法,適用於JB2,JB3,JB5:
請在alps\mediatek\config\proct_nam\ProjectConfig.mk中,將MTK_SIP_SUPPORT置為yes即可
打開SIP功能的方法,適用於JB2之前的版本:
1. 在文件alps\mediatek\config\proct_name\android.software.sip.voip.xml中添加如下代碼
<permissions>
<feature name="android.software.sip" />
<feature name="android.software.sip.voip" />
</permissions>
2. 在文件alps\mediatek\config\proct_name\android.software.sip.xml
<permissions>
<feature name="android.software.sip" />
</permissions>
允許SIP使用GPRS,僅針對GB, GB2,GB3:
在文件alps\frameworks\base\core\res\res\values\Config.xml中將
<bool name="config_sip_wifi_only">true</bool>
修改為
<bool name="config_sip_wifi_only">false</bool>
注:JB2,JB3,JB5版本中SIP call功能與OP02互斥,不可以同時開啟。
原因是由於運營商的某些原因不允許開啟Sip功能。
如希望同時使用,可以修改mk去除互斥條件:
/alps/mediatek/build/addon/core/android_dep_rule.mak中去掉以下內容
############################################################
ifneq ($(filter OP02%, $(OPTR_SPEC_SEG_DEF)),)
ifeq ($(strip $(MTK_SIP_SUPPORT)),yes)
$(call dep-err-common, Please do not set OPTR_SPEC_SEG_DEF as OP02* or set MTK_SIP_SUPPORT as no)
endif
endif
1、VOIP基於SIP協議,SDK2.3包含一個SIP協議棧和框架API
2、VOIP位於android.net.sip包中,最重要的為SipManager類,可開發基於SIP的VOIP應用。使用時要包含android.permission.INTERNET和android.permission.USE_SIP許可權
3、如果在market中顯示僅支持VOIP API幸好的手機的話,發布時需要在androidManifest.xml中加入<uses_feature android:name = "android.software.sip" android:required = "true">和<uses_feature android:name = "android.software.sip.voip">
4、要支持SIP API
(1)僅Android2.3或更高版本平台支持
(2)不是所有設備都提供SIP支持,確保你的APP只安裝在支持SIP的裝置上
5、根據GOOGLE官方DEMO項目來擴展的概念
二、類及方法描述
1、一個基本的VOIP項目至少需要三個類SIPSettings(對SIP的基本設置身份驗證)、WalkieTalkieActivity(登錄到SIP設備供應商,注冊device去處理來電,撥打電話,在通話過程中用戶界面管理)、IncomingCallReceiver(監聽傳入的SIP電話,然後傳遞這些SIP電話給WalkieTalkieActivity控制)
2、
WalkieTalkieActivity
A、SipManager.newInstance()-->此方法中首先判斷context是否支持SIP API,若支持則new SipManager。SipManager構造函數中,實例化了一個ISIPService(運用的公式:
IBinder b =ServiceManager.getService(Context.SIP_SERVICE); //獲取系統相應的服務
ISipService service = ISipService.Stub.asInterface(bIBinder);)
上面這兩句代碼其實是使用了AIDL,就以SipService為例,步驟如下
Service端
1、編寫aidl文件:ISipService.aidl,並定義使用的介面(就等同於interface一樣)
2、使用makefile生成與之同名的java文件,SipService.java,此類繼承extends ISipService.Stub並實現介面定義的方法或者在SipService extends Service,並代碼中加入
ISipService.stub sipImpl = new ISipService.stub(){
//實現其介面方法,在SipService.java中是實現了一個名為start()的方法,裡面有句是ServiceManager.addService("sip",newSipService(context));表示SipService已經交給ServiceManager統一管理了
}
Client端
一(以SIPService為例)
1、而在需要用到SipService時,也就是我們構造SipManager的時候,就通過ServiceManager.getService(Context.SIP_SERVICE)獲得SIP的服務(類型為IBinder)
2、並調用 ISipService.Stub.asInterface(IBinder);去獲取一個SipService實例(前提是該Service一定是通過ServiceManager.addService的方式添加進去管理的,這樣才能找到此Service)
二(以普通Activity為例)
1、利用Intent intent = new Intent(Activity.this,SipService.class);-->bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);來綁定SERVICE,在serviceConnection的onServiceConnected方法中,使用IService.stub.asIntentface(IBinder);來獲取實例
B、SipManager創建好後,先從SharedPreference中獲取username,domain及pwd,如果第一次進來沒有設置這些的話則需要先創建賬戶,這里用EditTextPreference來保存用戶信息,好處是當填寫信息並返回後,EditTextPreference會自動將值放入SharedPreference中。我們假設username="woody";domain="192.168.12.30";pwd="910913"
C、這時,我們的SipManager以及用戶信息已經設定好了,接下來使用了這句SipProfile.Builder builder = new
SipProfile.Builder(username, domain);我們去看看SipProfile.Builder中做了些什麼:
SipURI mUri =mAddressFactory.createSipURI(username,serverDomain);
SipProfile mProfile.mDomain=serverDomain; //設置domain
(在mAddressFactory.createSipURl方法中,我選取了一些核心代碼)
StringBuffer uriString=new StringBuffer("sip:");
uriString.append(user);
uriString.append("@");
//if host is an IPv6 string we should enclose it in sq brackets
if(host.indexOf(':') !=host.lastIndexOf(':')&&host.trim().charAt(0) !='[')
host='['+host+']';
uriString.append(host);
StringMsgParser smp=new StringMsgParser();
SipUrl sipUri=smp.parseSIPUrl(uriString.toString());
return sipUri;
從以上代碼可以看出其實就是在Format SipURL罷了,裡面多加了個if host為IPV6的判斷(IPv4為為32位,十進制;IPv6為128位,16進制)。urlString最後為"sip:[email protected]",smp.parseSIPUrl()方法中,有關於是如何parse的就不做闡述了,總之最後返回了一個SipUri
D、接下來就是SipProfile sipProfile = SipProfile.Builder.build(); //返回一個SipProfile object
在SipProfile.Builder.build()中,設置了sipProfile的pwd值,刪除了之前SipUrl對象里的
password(mUri.setUserPassword(null);)、將sipProfile的address屬性設置為AddressImpl類型的對象值、調用AddressFactory.createURI返回一個SipUri,並sipProfile.mProxyAddress=sipUri.getHost();
E、創建PendingIntent對象:(Intent與PendingIntent區別在於Intent是及時啟動,而PendingIntent是不立刻反應,在特定的情況或通知下才啟動,適用於AlertClock等)
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
F、
SipManager.open(sipProfile,PendingIntent,null); //(實際是SIPService在做操作)設置localSIPProfile的callingID-->建立SIP連接(算是注冊至SIP Server)-->打開receiveCall
其中建立SIP連接,最後能追溯到是在SipSessionGroup.java的reset()方法中通過是注冊伺服器實現的,
注冊伺服器的步驟為:
(1)設置伺服器的屬性,例如伺服器的地址(IP_ADDRESS_PROP)、棧名(javax.sip.STACK_NAME)、發出去的路徑(localProfile中的javax.sip.OUTBOUND_PROXY)、線程池的大小(gov.nist.javax.sip.THREAD_POOL_SIZE)等,並且將這些屬性載入到伺服器中.
(2)通過SipFactory的靜態方法取得一個實例,然後通過SipFactory實例sipfactory
(3)創建一個SipStack實例sipstack(這一步獲得IP_ADDRESS_PROP,String address = Properties.getProperty("javax.sip.IP_ADDRESS");)
(4)用sipstack創建一個SipProvider實例sipProvider
(5)注冊SipListener
G、A~F步驟都是在做准備工作,大致的步驟如下:new SIPService-->new SIPManager-->設定用戶信息-->new SIPURI-->new SIPProfile-->new PendingIntent-->set sipProfile callingID-->(if profile.getAutoRegistation)open toReceiveCalls-->register SipService
現在是call someone~呼叫的工作是SipAudioCall類來完成(可用sipManager.makeAudioCall或takeAudioCall來實例化,SipAudioCall.startAudio時需要 RECORD_AUDIO, ACCESS_WIFI_STATE, and WAKE_LOCK permissions,
化,SipAudioCall.startAudio時需要 RECORD_AUDIO, ACCESS_WIFI_STATE, and WAKE_LOCK permissions,setSpeakerMode() 時需要MODIFY_AUDIO_SETTINGS permission)
【1】當需要呼叫時,使用sipManager.makeAudioCall(String localProfileURI, String peerProfileURI, SipAudioCall.listener,int timeout);來創建一個SipAudioCall,其中timeout以seconds為單位,過了timeout表示打電話超時。需要打給別人時使用makeAudioCall創建,接聽電話用takeAudioCall來創建sipAudioCall
【2】SipAudioCall中有一個嵌套的class:SipAudioCall.Listener(此類主要用於監聽SIP CALL,when[呼叫電話 or 接聽電話])
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onCallEstablished(SipAudioCall call) { //呼叫建立
call.startAudio(); //啟動音頻
call.setSpeakerMode(true); //調整為可講話模式
call.toggleMute(); //觸發無聲
updateStatus(call);
}
};
SipAudioCall call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
(以上例子為makeAudioCall)
【3】我們看看makeAudioCall()方法(makeAudioCall requires 2 sipProfile):
SipAudioCall call =new SipAudioCall(mContext, localProfile);
call.setListener(listener); //這兩句很簡單就是創建一個local的sipAudioCall
SipSession s = createSipSession(localProfile, null); -->mSipService.createSession(localProfile, null);// sipService來創建session,並保存在SipSessionGroupExt中
call.makeCall(peerProfile,s,null); //這句就是呼叫,最後追溯到實際是SipSession.makecall
總結:在發起通話中
首先是創建SipAudioCall.listener,以便監聽對話建立和對話結束,然後做相應的操作
然後是SipManager.makeAudioCall(localAdd,llistener,XXXX),在makeAudioCall方法中
A、創建一個sipAudioCall(localProfile)
B、創建SipSession以建立起會話
C、SipSession.makeCall(peerProfile,XXXX); //SipSession呼叫遠程profile
【4】關於接電話道理都差不多,takeAudioCall
通過之前設置的callingID來查找mSipService.getPendingSession(callId);來獲得SipSession。並創建SipAudioCall,然後attachCall就算接受電話了