[英]Instantiate Android SipManager in c++ builder
我正在嘗試使用C ++生成器在Embarcadero中實例化SipManager(developer.android.com),但我找不到正確的方法。 為此,我正在使用Delphi接口實例。
在Java中是這樣的:
public static SipManager manager;
manager = SipManager.newInstance(context);
//Context is the application context for creating the manager object.
為了正確編譯接下來顯示的代碼,必須包括以下內容:
#include <System.Classes.hpp>
#if defined (_PLAT_ANDROID)
#include <Androidapi.Helpers.HPP>
#include <Androidapi.JNI.Net.HPP>
#include <Androidapi.JNI.os.HPP>
#include <Androidapi.JNI.Support.HPP>
#include <Androidapi.JNI.Media.HPP>
#endif
此外,還必須將“使用Sip”和“ Internet”權限添加到清單中。
基於我已經知道如何安裝WifiManager的事實,我嘗試了許多方法來執行此操作:
#if defined (_PLAT_ANDROID)
_di_JObject obj;
_diJWifiManager wm;
obj = SharedActivityContext()->getSystemService(TJContext::JavaClass->WIFI_SERVICE);
wm = TJWifiManager::Wrap(((_di_ILocalObject)obj)->GetObjectID());
wm->setWifiEnabled(true);
#endif
對於我的應用程序,我已執行以下操作:
這樣可以編譯,但是在運行應用程序時會提示未找到方法init()。
#if defined (_PLAT_ANDROID) _di_JObject obj; _di_JSipManager sipm; obj = TJSipManager::JavaClass->init(); sipm = TJSipManager::Wrap(((_di_ILocalObject)obj)->GetObjectID()); #endif
該程序也可以編譯,但是在運行應用程序時,該程序具有“ Abort”異常類型。
#if defined (_PLAT_ANDROID) _di_JSipManager sipm; sipm = TJSipManager::Create(); #endif
它也可以編譯,但是在運行應用程序時,該類具有“訪問沖突”的異常類型。
#if defined (_PLAT_ANDROID) _di_JSipManager sipm; sipm = TJSipManager::JavaClass; #endif
這也可以編譯,但是當我嘗試打開配置文件時,它具有“ Abort”的異常類型。
#if defined (_PLAT_ANDROID) _di_JSipManager sipm; _di_JContext context; _di_JSipProfileBuilder sippb; _di_JSipProfile sipp; context = SharedActivityContext()->getApplicationContext(); TJSipManager *sipn = new TJSipManager(); sipm = sipn->Wrap(((_di_ILocalObject)context) >GetObjectID()); _di_JString uri; uri = StringToJString("sip:165@40.134.279.145:5060"); sippb = TJSipProfile_Builder::JavaClass->init(uri); sipp = sippb->build(); sipm->open(sipp); #endif
如果僅執行SipProfile的一部分,則不會出現問題,並且將創建概要文件。
#if defined (_PLAT_ANDROID)
_di_JSipProfileBuilder sippb;
_di_JSipProfile sipp;
_di_JString uri;
uri = StringToJString("sip:165@40.134.279.145:5060");
sippb = TJSipProfile_Builder::JavaClass->init(uri);
sipp = sippb->build();
#endif
在Java中是這樣的:
public static SipProfile me;
SipProfile.Builder builder = new SipProfile.Builder("uri");
me = builder.build();
我想知道如何實例化C ++ Builder的SipManager。 在Java中,已經看到它使用了“ newInstance(context)”方法,但是當我嘗試在C ++構建器中實例化它時,似乎沒有任何類似的方法屬於此類。
我可以在C ++ Builder中實例化嗎?
什么是正確的方法?
如果不可能,是否有另一個庫可以使用C ++ Builder在Embarcadero中制作Sip應用程序?
在另一個論壇中,雷米回答:
“在C ++ Builder中應該像這樣簡單:
#if defined (_PLAT_ANDROID)
_di_JSipManager manager = TJSipManager::JavaClass->newInstance(SharedActivityContext());
// use manager as needed...
#endif
但是實際上,這是行不通的(至少在西雅圖,不知道更高版本),因為靜態newInstance()方法是從Androidapi.JNI.Net.hpp中的JSipManagerClass接口丟失的!
您可以嘗試使用Java2OP重新導入SipManager類,但是我不知道那是否最終會遇到相同的問題。”
但是我有Tokio的最新版本,但仍然有同樣的問題。 我將嘗試重新導入SipManager。
讓我們瀏覽一下您的產品,看看它們為什么不起作用:
1)您正在調用無參數Java構造函數,表面上顯示為init()
但此類並非旨在通過常規構造函數構造。 有人假設構造函數是私有的,但是無論如何,文檔說您都是通過newInstance()
創建一個實例的。
2)調用導入類的Create()
類方法通常與調用init()
幾乎相同,但通過不同的途徑進行。 給定init
不可用,它會失敗,只是此處出現其他症狀。
3)您已經聲明了Delphi JSipManager
實例方法接口類型的變量,然后為其分配了JavaClass
屬性,該屬性提供了Delphi JSipManagerClass
類方法的接口類型。 那兩個不一樣。 可能會出現錯誤。
4)模板類TJSipManager
是一個幫助程序(通過JavaClass
屬性)訪問類方法接口或通過調用構造函數創建的實例(可能通過Create()
或JavaClass->init()
)訪問實例方法。不應構造此模板類的實例-它沒有任何用處;繼續將上下文對象(通過Wrap()
)轉換為SipManager
絕望的消息-它們是完全不同的類型。
好的,現在讓我們看看為什么不起作用。
之所以在原始Delphi單元Androidapi.JNI.Net.pas中的JSipManagerClass
類方法接口中注釋newInstance()
方法(及其他方法),是因為它們都具有參數或返回類型,例如JContext
或JIntent
它是從已經使用Androidapi.JNI.Net.pas的單元(即單元Androidapi.JNI.GraphicsContentViewText.pas)定義和公開的。
Java2OP之所以將這些方法保留在那里,是因為它們存在,但將它們注釋掉以避免循環單元引用錯誤。
起作用的是在新的Delphi單元中重新定義SipManager
JNI Bridge類型,將該新單元添加到您的C ++項目中,包括其生成的標頭,然后從那里開始。
要制作單元,可以右鍵單擊項目管理器中的項目,然后選擇“添加新的單元-Delphi”。 如果僅使用C ++ Builder(不支持Delphi),只需在文本編輯器中創建單元。 它稱為Androidapi.JNI.SIP.pas,僅包含一種類型的導入: SipManager
為避免含糊不清,我將基本導入接口JSipManager2
稱為:
unit Androidapi.JNI.SIP;
interface
uses
Androidapi.JNIBridge,
Androidapi.JNI.Net,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Os;
type
// ===== Forward declarations =====
JSipManager2 = interface;//android.net.sip.SipManager
JSipManager2Class = interface(JObjectClass)
['{62C12348-C7E4-4B5E-AE75-715EAAFD4465}']
{class} function _GetEXTRA_CALL_ID: JString; cdecl;
{class} function _GetEXTRA_OFFER_SD: JString; cdecl;
{class} function _GetINCOMING_CALL_RESULT_CODE: Integer; cdecl;
{class} function getCallId(incomingCallIntent: JIntent): JString; cdecl;
{class} function getOfferSessionDescription(incomingCallIntent: JIntent): JString; cdecl;
{class} function isApiSupported(context: JContext): Boolean; cdecl;
{class} function isIncomingCallIntent(intent: JIntent): Boolean; cdecl;
{class} function isSipWifiOnly(context: JContext): Boolean; cdecl;
{class} function isVoipSupported(context: JContext): Boolean; cdecl;
{class} function newInstance(context: JContext): JSipManager2; cdecl;
{class} property EXTRA_CALL_ID: JString read _GetEXTRA_CALL_ID;
{class} property EXTRA_OFFER_SD: JString read _GetEXTRA_OFFER_SD;
{class} property INCOMING_CALL_RESULT_CODE: Integer read _GetINCOMING_CALL_RESULT_CODE;
end;
[JavaSignature('android/net/sip/SipManager')]
JSipManager2 = interface(JObject)
['{EDE899E1-4774-41FB-BC53-03BB69565231}']
procedure close(localProfileUri: JString); cdecl;
function createSipSession(localProfile: JSipProfile; listener: JSipSession_Listener): JSipSession; cdecl;
//function getSessionFor(incomingCallIntent: JIntent): JSipSession; cdecl;
function isOpened(localProfileUri: JString): Boolean; cdecl;
function isRegistered(localProfileUri: JString): Boolean; cdecl;
function makeAudioCall(localProfile: JSipProfile; peerProfile: JSipProfile; listener: JSipAudioCall_Listener; timeout: Integer): JSipAudioCall; cdecl; overload;
function makeAudioCall(localProfileUri: JString; peerProfileUri: JString; listener: JSipAudioCall_Listener; timeout: Integer): JSipAudioCall; cdecl; overload;
procedure open(localProfile: JSipProfile); cdecl; overload;
//procedure open(localProfile: JSipProfile; incomingCallPendingIntent: JPendingIntent; listener: JSipRegistrationListener); cdecl; overload;
procedure register(localProfile: JSipProfile; expiryTime: Integer; listener: JSipRegistrationListener); cdecl;
procedure setRegistrationListener(localProfileUri: JString; listener: JSipRegistrationListener); cdecl;
//function takeAudioCall(incomingCallIntent: JIntent; listener: JSipAudioCall_Listener): JSipAudioCall; cdecl;
procedure unregister(localProfile: JSipProfile; listener: JSipRegistrationListener); cdecl;
end;
TJSipManager2 = class(TJavaGenericImport<JSipManager2Class, JSipManager2>) end;
implementation
procedure RegisterTypes;
begin
TRegTypes.RegisterType('Androidapi.JNI.SIP.JSipManager2', TypeInfo(Androidapi.JNI.SIP.JSipManager2));
end;
initialization
RegisterTypes;
end.
然后在像這樣的一些C ++代碼中使用它:
...
// Cleanse build of lots of errors about __cdecl...
#define __cdecl
#include "Androidapi.JNI.SIP.hpp"
#include <Androidapi.Helpers.hpp>
...
_di_JSipManager2 manager = TJSipManager2::JavaClass->newInstance(TAndroidHelper::Context);
// use manager as needed...
這似乎可以編譯並執行OK,但是我沒有SIP服務,因此無法進一步解決。
作為分手注釋,不推薦使用全局SharedActivityContext()
函數TAndroidHelper
類現在包含所有此類東西,例如TAndroidHelper::Context
類的靜態方法/屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.