簡體   English   中英

在C ++ Builder中實例化Android SipManager

[英]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

對於我的應用程序,我已執行以下操作:

  1. 這樣可以編譯,但是在運行應用程序時會提示未找到方法init()。

     #if defined (_PLAT_ANDROID) _di_JObject obj; _di_JSipManager sipm; obj = TJSipManager::JavaClass->init(); sipm = TJSipManager::Wrap(((_di_ILocalObject)obj)->GetObjectID()); #endif 
  2. 該程序也可以編譯,但是在運行應用程序時,該程序具有“ Abort”異常類型。

     #if defined (_PLAT_ANDROID) _di_JSipManager sipm; sipm = TJSipManager::Create(); #endif 
  3. 它也可以編譯,但是在運行應用程序時,該類具有“訪問沖突”的異常類型。

     #if defined (_PLAT_ANDROID) _di_JSipManager sipm; sipm = TJSipManager::JavaClass; #endif 
  4. 這也可以編譯,但是當我嘗試打開配置文件時,它具有“ 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 ++構建器中實例化它時,似乎沒有任何類似的方法屬於此類。

  1. 我可以在C ++ Builder中實例化嗎?

  2. 什么是正確的方法?

  3. 如果不可能,是否有另一個庫可以使用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()方法(及其他方法),是因為它們都具有參數或返回類型,例如JContextJIntent它是從已經使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM