Java Question Extends Service Library

walterf25

Expert
Licensed User
Longtime User
Hi All, i am currently working on a NFCEmulator library wrapper, i found a full project online which emulates an NFC card and another project that acts as the reader, i have been able to run both of these projects with Android Studio and they both seem to work as expected.

Now i am trying to create a wrapper for the NFCEmulator part but i am having some problems wrapping my head around the Extends Service part, I've looked at the example found here, my B4A Project compiles and runs just fine but I just don't get the expected results, below is part of the code for the wrapper.
B4X:
public class B4ANFCEmulatorWrapper extends HostApduService{
    
    private String TAG = "Host Card Emulator";
    private String STATUS_SUCCESS = "9000";
    private String STATUS_FAILED = "6F00";
    private String CLA_NOT_SUPPORTED = "6E00";
    private String INS_NOT_SUPPORTED = "6D00";
    private String AID = "A0000002471001";
    private static final String SAMPLE_LOYALTY_CARD_AID = "F222222222";
    private String SELECT_INS = "A4";
    public String DEFAULT_CLA = "EB";
    private int MIN_APDU_LENGTH = 12;
    
    
    // ISO-DEP command HEADER for selecting an AID.
    // Format: [Class | Instruction | Parameter 1 | Parameter 2]
    private static final String SELECT_APDU_HEADER = "00A40400";
    // "OK" status word sent in response to SELECT AID command (0x9000)
    private static final byte[] SELECT_OK_SW = hexStringToByteArray("9000");
    // "UNKNOWN" status word sent in response to invalid APDU command (0x0000)
    private static final byte[] UNKNOWN_CMD_SW = hexStringToByteArray("0000");
    private static final byte[] SELECT_APDU = BuildSelectApdu(SAMPLE_LOYALTY_CARD_AID);
    
    private NFCEmulator nfc;
    
    
      @Override public void onCreate() {
      BA.Log("inside onCreate of B4ANFCEmulator library");
      BA.Log("this.getClass: " + this.getClass().toString());
      super.onCreate();
      startService(new Intent(this, this.getClass())); //Important if the service will be boundinstead of started.
      }
    

    @Override
    public void onDeactivated(int arg0) {
        // TODO Auto-generated method stub
        BA.Log("onDeactivated: " + arg0);
        nfc.mba.raiseEvent(this, mEventName + "_ondeactivated", new Object[] {arg0});
    }

    @Override
    public byte[] processCommandApdu(byte[] arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        BA.Log("arg0: " + arg0 + " Bundle: " + arg1.toString());
        nfc.mba.raiseEvent(this, mEventName + "_processcommandapdu", new Object[] {arg0});
        if (arg0 == null) {
            BA.Log("STATUS_FAILED: " + hexStringToByteArray(STATUS_FAILED));
            return hexStringToByteArray(STATUS_FAILED);
        }

According to the Android Studio Project, i need to add the following to the Manifest File and which I did.
CreateResource(xml, apduservice.xml, <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/servicedesc"
android:requireDeviceUnlock="false">
<aid-group android:description="@string/aiddescription"
android:category="other">
<aid-filter android:name="F222222222"/>
</aid-group>
</host-apdu-service>)

AddManifestText(<uses-feature android:name="android.hardware.nfc.hce"
android:required="true" />)

AddPermission(android.permission.NFC)

AddServiceText(nfctargeet, <intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>)


SetServiceAttribute(nfctargeet, android:exported, true)
SetServiceAttribute(nfctargeet, android:permission, "android.permission.BIND_NFC_SERVICE")
AddApplicationText( <meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apduservice" />)
nfctargeet is the name of the Service which starts just fine, but I don't see the onDeactivated or the processCommandApdu functions being raised at all, the code inside the service is the following:
B4X:
#Region  Service Attributes
    #StartAtBoot: False
    
#End Region

#Extends: com.genesis.nfcemulator.B4ANFCEmulatorWrapper


Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private nfc As NFCEmulator
End Sub

Sub Service_Create
    
    nfc.Initialize("nfc")
End Sub

Has anyone else successfully created a library wrapper where there is a need to Extend a Service, if so would you maybe give me some tips or hints about what i may be doing wrong, as I mentioned the B4A project compiles and runs fine, I do not receive any error logs in the filtered or Unfiltered logs, i have the NFCEmulator app running on my Samsung Galaxy S10+ and the NFC Card Reader app running on my other Samsung Galaxy S9+ when i place both phones back to back i can see the NFC Card Reader app trying to communicate with the Emulator side but as I also mentioned the processCommandApdu function does not seem to be invoked at all, that function is needed obviously to look at the NFC Card Reader app's requests and send a response accordingly.

Any help will be greatly appreciated.

Thanks,
Walter
 

walterf25

Expert
Licensed User
Longtime User
This is probably not needed: startService(new Intent(this, this.getClass())); //Important if the service will be boundinstead of started.

Check the generated AndroidManifest.xml file and see whether it matches the Android Studio manifest file.
Hi @Erel Thanks, i checked the AndroidManifest.xml file while everything looked OK, i did find a line that wasn't where it was supposed to, I moved the line inside the Intent Filter Tag and everything seems good now.

Thanks,
Walter
 
Top