Jump to content
Sign in to follow this  
NecoArc

How to call onActivityResult of my activity?/java2op not generating some classes

Recommended Posts

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 by NecoArc

Share this post


Link to post
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
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
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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×