NecoArc 1 Posted Thursday at 08:41 PM (edited) I’m working with the TOPWISE SK210 device, which is a mini kiosk with a built-in printer and barcode scanner. Here in Brazil, this device is distributed by Gertec, and they provided me with the .jar files and the device manuals. I’m currently trying to integrate the scanner into a Delphi 12 test application. I can successfully call the scanner and trigger a reading, but I cannot retrieve the scanned result. Below is my Delphi code: procedure TForm1.FormCreate(Sender: TObject); begin // Registra o listener para interceptar mensagens de resultado de atividade FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage); FScannerAtivo := False; end; procedure TForm1.Button1Click(Sender: TObject); var scanner: JCodeScanner; config: JScanConfig; begin Activity := TAndroidHelper.Activity; if not Assigned(Activity) then begin LogDebug('ERRO'); Exit; end; scanner := TJCodeScanner.JavaClass.getInstance(Activity); scanner.scanCode(Activity); end; procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage); var ResultMsg: TMessageResultNotification; Intent: JIntent; ExtraString: JString; begin if not (M is TMessageResultNotification) then begin Exit; end; ResultMsg := TMessageResultNotification(M); if ResultMsg.ResultCode = TJActivity.JavaClass.RESULT_OK then begin logDebug('it work!') end else if ResultMsg.ResultCode = TJActivity.JavaClass.RESULT_CANCELED then begin logDebug('did not work') end; end; For comparison, here is the Java example that works as expected: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_code_scanner); codeScanner = CodeScanner.getInstance(this); btnStart = findViewById(R.id.btnStart); btnStart.setOnClickListener(view -> { codeScanner.scanCode(this); }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { String content = data.getStringExtra("content"); if (content != null) { consultaOrder.add(content); adapter.notifyDataSetChanged(); } }else { super.onActivityResult(requestCode, resultCode, data); } } Problem When running the Delphi code, the HandleActivityMessage method is always triggered with TJActivity.JavaClass.RESULT_CANCELED. It never returns RESULT_OK, so I cannot capture the scan result. Using Logcat, I found the following error message: 09-25 16:56:43.681 I/ActivityTaskManager( 1063): START u0 {cmp=com.embarcadero.Project1/br.com.gertec.easylayer.codescanner.SetActivity (has extras)} from uid 10126 09-25 16:56:43.685 E/JavaBinder(28668): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.embarcadero.Project1/br.com.gertec.easylayer.codescanner.SetActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared <intent-filter>? 09-25 16:56:43.685 E/JavaBinder(28668): at br.com.gertec.easylayer.codescanner.CodeScanner$1.onResult(CodeScanner.java:281) Investigation After checking, I noticed that my JNI file generated by java2op does not include codescanner.SetActivity. When I regenerated the JNI bindings using java2op, I confirmed that it was not created because of the following issue: br.com.gertec.easylayer.codescanner.SetActivity: the parent class (androidx.appcompat.app.AppCompatActivity) is not found Essentially, the problem seems to be that the SetActivity class is missing from my Delphi project because its parent (androidx.appcompat.app.AppCompatActivity) is not being resolved during JNI generation. does someone know what i can do to solve it? thanks in advance everyone Edited Thursday at 08:44 PM by NecoArc Share this post Link to post
Dave Nottage 640 Posted Thursday at 08:49 PM 2 minutes ago, NecoArc said: does someone know what i can do to solve it? You need to add this to the <queries> section of AndroidManifest.template.xml, e.g: <queries> <%queries-child-elements%> <!-- The following line has been added manually --> <package android:name="br.com.gertec.easylayer.codescanner" /> </queries> If there is documentation for the SDK, I expect they describe this - it might be different from above. Share this post Link to post
NecoArc 1 Posted Friday at 02:07 PM 16 hours ago, Dave Nottage said: You need to add this to the <queries> section of AndroidManifest.template.xml, e.g: <queries> <%queries-child-elements%> <!-- The following line has been added manually --> <package android:name="br.com.gertec.easylayer.codescanner" /> </queries> If there is documentation for the SDK, I expect they describe this - it might be different from above. I tried that, but it didn’t work. So, checking the logs, I attempted some additional fixes. First, I found the class codescanner.SetActivity inside my .jar file: package br.com.gertec.easylayer.codescanner; import android.content.Intent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import br.com.gertec.easylayer.R; public class SetActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_set); Intent intent = this.getIntent(); String s = intent.getStringExtra("result"); if (s != null) { Intent returnIntent = new Intent(); returnIntent.putExtra("content", s); this.setResult(-1, returnIntent); this.finish(); } else { this.finish(); } } Then I implemented the interface in my .jni file: JSetActivity = interface; JSetActivityClass = interface(JObjectClass) ['{D0B8C7AF-92C5-4BB5-8E1A-B76164E7AB10}'] end; [JavaSignature('br/com/gertec/easylayer/codescanner/SetActivity')] JSetActivity = interface(JObject) ['{EBB78E1F-92A4-4E1E-B55C-67130FCEB2A3}'] procedure onCreate(bundle: JBundle); cdecl; end; TJSetActivity = class(TJavaGenericImport<JSetActivityClass, JSetActivity>) end; TRegTypes.RegisterType('android.jni.easylayersk210.JSetActivity', TypeInfo(android.jni.easylayersk210.JSetActivity)); However, I don’t think my declaration is correct. SetActivity extends AppCompatActivity, but I can’t extend this class properly in Delphi. What I think it should be, but I couldn’t make it work because delphi do not recognize JAppCompatActivity, or i didn't find the correct uses path for it JSetActivityClass = interface(JAppCompatActivityClass) JSetActivity = interface(JAppCompatActivity) After this change, the log showed that I need to declare the activity: 09-26 10:51:28.083 I/ActivityTaskManager(1070): START u0 {cmp=com.embarcadero.Project1/br.com.gertec.easylayer.codescanner.SetActivity (has extras)} from uid 10129 09-26 10:51:28.086 E/JavaBinder(21949): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.embarcadero.Project1/br.com.gertec.easylayer.codescanner.SetActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared <intent-filter>? 09-26 10:51:28.086 E/JavaBinder(21949): at br.com.gertec.easylayer.codescanner.CodeScanner$1.onResult(CodeScanner.java:281) so i did <activity android:name="br.com.gertec.easylayer.codescanner.SetActivity" android:exported="true"> </activity> Now, instead of the previous error, the app crashes, saying that codescanner.SetActivity closed the app due to timeout, because it didn’t find the activity to return the result, i think. 09-26 11:05:35.026 W/ActivityTaskManager( 1070): Force finishing activity com.embarcadero.Project3/br.com.gertec.easylayer.codescanner.SetActivity 0 09-26 11:05:35.527 W/ActivityTaskManager( 1070): Activity top resumed state loss timeout for ActivityRecord{6f4eb43 u0 com.embarcadero.Project3/br.com.gertec.easylayer.codescanner.SetActivity} t272 f}} 09-26 11:05:35.528 W/ActivityTaskManager( 1070): Activity pause timeout for ActivityRecord{6f4eb43 u0 com.embarcadero.Project3/br.com.gertec.easylayer.codescanner.SetActivity} t272 f}} idk what i can do anymore Share this post Link to post
Dave Nottage 640 Posted Friday at 06:55 PM 4 hours ago, NecoArc said: android.content.ActivityNotFoundException: I guess this should have been a big clue. Sorry I missed it 🙂 4 hours ago, NecoArc said: idk what i can do anymore Did they provide any documentation for the SDK, or example apps? Even if it's in Java/Kotlin. If there's an example app you could check the AndroidManifest.xml to see if you have everything required in yours. Share this post Link to post