I am developing a POS app to communicate with GP tom app.
The GP tom app uses an AIDL file. I have unpacked this file and created a bridge file with javo2op.exe. The connection to the GP tpm app works. Calling the function “registerV2()” in the first version works without errors. I don't know how to evaluate the result function “onRegisterV2Result” to get the result. In the second version I get an exception of the class EJNIFatal “Schwerer Fehler beim Aufrufen des Interfaces”.
Excerpt from the example by GP tom:
private final ITransactionRegisterListener registerV2Listener = new ITransactionRegisterListener.Stub() {
@Override
public void onRegisterResult(final RegisterResultEntity registerResultEntity) {
}
@Override
public void onRegisterV2Result(final String result) {
runOnUiThread(() -> {
try {
Log.d(LOGGER_TAG_RESPONSE, "transactionRegisterV2Result" + result);
final RegisterResultV2Entity resultEntity = new Gson()
.fromJson(result, RegisterResultV2Entity.class);
//Transaction ID used as an input to other methods
final String transactionId = resultEntity.getTransactionId();
Log.d(LOGGER_TAG_RESPONSE, "transactionId V2 = " + transactionId);
edtTransactionId.setText(transactionId);
edtTransactionId.setError(null);
//Just output result
tvResult2.setText("transactionRegisterV2Result" + result);
} catch (Exception e) {
Log.e(LOGGER_TAG_RESPONSE, "Register V2 Exception occurred", e);
toast("Register V2 Exception occurred: " + e.getMessage());
}
});
}
};
//register V2
private void registerV2() {
try {
final RegisterEntity entity = new RegisterEntity();
//Client id is optional
if (!edtClientApiId.getText().toString().trim().isEmpty()) {
entity.setClientID(edtClientApiId.getText().toString());
}
final String requestJson = new Gson().toJson(entity);
Log.d(LOGGER_TAG_REQUEST, "registerV2=" + requestJson);
iSmartconnectService.transactionRegisterV2(requestJson, registerV2Listener);
} catch (Exception e) {
Log.e(LOGGER_TAG_REQUEST, "registerV2 exception", e);
toast("Unable to registerV2. Exception occurred: " + e.getMessage());
}
}
Delphi App:
unit Main.View;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
System.Android.Service,
FMX.Helpers.Android,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.StdCtrls,
FMX.Controls.Presentation,
FMX.Objects,
FMX.Layouts,
FMX.Edit
{$IFDEF ANDROID}
,
Androidapi.JNI.Support,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.Helpers,
Androidapi.JNIBridge,
Androidapi.JNI.Util,
Androidapi.JNI.Os,
Androidapi.JNI.Net,
Androidapi.JNI.Java.Security,
Androidapi.JNI.JavaTypes,
Android.JNI.Aidl_Smartconnect, // generated with java2op.exe from aidl_smartconnect_v1.14.0
Java.gson
{$ENDIF }
;
const
AIDL_ACTION = 'com.globalpayments.atom.data.external.api.NexgoAPIService';
AIDL_PACKAGE = 'com.globalpayments.atom.dev';
type
TTransactionRegisterListener = class(TJInterfacedObject, JITransactionRegisterListener)
public
function asBinder: JIBinder; cdecl;
procedure onRegisterResult(registerResultEntity: JRegisterResultEntity); cdecl;
procedure onRegisterV2Result(string_: JString); cdecl;
end;
TMainFrm = class(TForm)
lblFormCaption: TLabel;
rectFormCaption: TRectangle;
edtAmount: TEdit;
layAmounts: TLayout;
layService: TLayout;
btnBindService: TSpeedButton;
btnUnbindService: TSpeedButton;
lblStatus: TLabel;
btnRegisterV2: TSpeedButton;
procedure btnBindServiceClick(Sender: TObject);
procedure btnUnbindServiceClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnRegisterV2Click(Sender: TObject);
private
{ Private-Deklarationen }
fIsConnected: Boolean;
fGPtomConnection: TRemoteServiceConnection;
fSmartconnectService: JISmartconnectService;
procedure OnHandleMessage(const AMessage: JMessage);
procedure OnServiceConnected(const ServiceMessenger: JMessenger);
procedure RegisterTransactionV2;
public
{ Public-Deklarationen }
end;
var
MainFrm: TMainFrm;
implementation
{$R *.fmx}
{ TMainFrm }
procedure TMainFrm.btnBindServiceClick(Sender: TObject);
var
PackageInfo: JPackageInfo;
begin
try
PackageInfo := TAndroidHelper.Context.getPackageManager.getPackageInfo(StringToJString(AIDL_PACKAGE), 0);
if PackageInfo <> nil then
begin
fGPtomConnection := TRemoteServiceConnection.Create;
fGPtomConnection.OnConnected := OnServiceConnected;
fGPtomConnection.OnHandleMessage := OnHandleMessage;
fGPtomConnection.BindService(AIDL_PACKAGE, AIDL_ACTION, TJContext.JavaClass.BIND_AUTO_CREATE);
end
else
begin
MainFrm.lblStatus.Text := 'GP tom nicht installiert';
btnUnbindService.Enabled := False;
end;
except
MainFrm.lblStatus.Text := 'GP tom nicht installiert';
btnUnbindService.Enabled := False;
end;
end;
procedure TMainFrm.btnRegisterV2Click(Sender: TObject);
begin
RegisterTransactionV2;
end;
procedure TMainFrm.btnUnbindServiceClick(Sender: TObject);
begin
if fIsConnected then
begin
fGPtomConnection.UnbindService;
fIsConnected := False;
MainFrm.lblStatus.Text := 'Disconnected from GP tom service';
btnBindService.Enabled := not fIsConnected;
btnUnbindService.Enabled := fIsConnected;
end;
end;
procedure TMainFrm.FormCreate(Sender: TObject);
begin
lblStatus.Text := '';
btnUnbindService.Enabled := False;
end;
procedure TMainFrm.OnHandleMessage(const AMessage: JMessage);
begin
end;
procedure TMainFrm.OnServiceConnected(const ServiceMessenger: JMessenger);
begin
fSmartconnectService := TJISmartconnectService_Stub.JavaClass.asInterface(ServiceMessenger.getBinder);
fIsConnected := True;
MainFrm.lblStatus.Text := 'Connected to GP tom service';
btnBindService.Enabled := not fIsConnected;
btnUnbindService.Enabled := fIsConnected;
end;
procedure TMainFrm.RegisterTransactionV2;
var
Entity: JRegisterEntity;
RegisterV2Listener: TTransactionRegisterListener;
RegisterV2Listener_1: JITransactionRegisterListener;
RegisterV2ResultJSON: JString;
RequestJSON: JString;
fJGson: JGson;
begin
Entity := TJRegisterEntity.Create;
fJGson := TJGson.Create;
RequestJSON := fJGson.toJson(Entity);
//begin variant 1
RegisterV2Listener_1 := TJITransactionRegisterListener_Stub.JavaClass.asInterface(fSmartconnectService.asBinder);
fSmartconnectService.transactionRegisterV2(RequestJSON, RegisterV2Listener_1); // ---> no exception, but i don't know how i get the onRegisterV2Result
//end variant 1
//begin variant 2
RegisterV2Listener := TTransactionRegisterListener.Create;
fSmartconnectService.transactionRegisterV2(RequestJSON, RegisterV2Listener); // ---> get exception EJNIFatalError
//end variant 2
end;
{ TTransactionRegisterListener }
function TTransactionRegisterListener.asBinder: JIBinder;
begin
end;
procedure TTransactionRegisterListener.onRegisterResult(
registerResultEntity: JRegisterResultEntity);
begin
end;
procedure TTransactionRegisterListener.onRegisterV2Result(string_: JString);
var
TransactionID: string;
ResultEntity: JRegisterResultV2Entity;
ResultString: string;
begin
ResultString := TAndroidHelper.JStringToString(string_);
end;
end.