Java Question bindService in a Wrapper

TheMightySwe

Active Member
Licensed User
Longtime User
Hi all java-experts.

A cry for help from a java-newbee here.

I need this code to work inside a wrapper...

B4X:
    abstract void onPclServiceConnected();
   
    protected void initService()
    {
        if (!mBound)
        {
            Log.d(TAG, "initService" );
            mServiceConnection = new PclServiceConnection();
            Intent intent = new Intent(this, PclService.class);
            intent.putExtra("PACKAGE_NAME", "com.ingenico.pcltestappwithlib");
            intent.putExtra("FILE_NAME", "pairing_addr.txt");
            mBound = bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        }
    }

My code looks like this

B4X:
    abstract void onPclServiceConnected();
   
    protected void initService()
    {
        if (!mBound)
        {
            BA.Log("ISMPWrapper(CommonActivity)(initService)");
            mServiceConnection = new PclServiceConnection();
            Intent intent = new Intent(BA.applicationContext, PclService.class);
            //Intent intent = new Intent(this, PclService.class);
            intent.putExtra("PACKAGE_NAME", "se.iqpd.checkout.ismpcompanion");
            intent.putExtra("FILE_NAME", "pairing_addr.txt");
           
            mBound = bindService(intent, mServiceConnection, BA.applicationContext.BIND_AUTO_CREATE);
        }
    }

and fails at...

mBound = bindService(intent, mServiceConnection, BA.applicationContext.BIND_AUTO_CREATE);

Maybe all is completlly wrong, i don't know. If someone could help me with this I would be most greatful!
 

TheMightySwe

Active Member
Licensed User
Longtime User
LogCat connected to: B4A-Bridge: samsung GT-P5110-
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:se.iqpd.checkout.plus
** Activity (main) Create, isFirst = true **
RSSketchLibrary has been initialized.
** Service (httputils2service) Create **
** Service (httputils2service) Start **
ISMPWrapper(IsInitialized): IsInitialized=false
ISMPWrapper: Initialize
ISMPWrapper:(Initialize): Init service
ISMPWrapper(CommonActivity)(initService)
java.lang.NullPointerException
at android.content.ContextWrapper.bindService(ContextWrapper.java:377)
at se.iqpd.checkout.ismpcompanion.CommonActivity.initService(CommonActivity.java:150)
at se.iqpd.checkout.ismpcompanion.ISMPWrapper.Initialize(ISMPWrapper.java:530)
at se.iqpd.checkout.plus.main._activity_create(main.java:1004)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
at se.iqpd.checkout.plus.main.afterFirstLayout(main.java:98)
at se.iqpd.checkout.plus.main.access$100(main.java:16)
at se.iqpd.checkout.plus.main$WaitForLayout.run(main.java:76)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4514)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException
 

TheMightySwe

Active Member
Licensed User
Longtime User
Not something that I see here.


I got a new error when I used a snippet to see if the service is availible and started.

java.lang.IllegalStateException: System services not available to Activities before onCreate()


onCreate() How do I make that to run before i run the code above, that i run in Initialize now?
 

TheMightySwe

Active Member
Licensed User
Longtime User
I thought onCreate() in a class is executed automaticlly on creation. But apparentlly not so.


This is the error message.

B4X:
java.lang.IllegalStateException: System services not available to Activities before onCreate()
    at android.app.Activity.getSystemService(Activity.java:3989)
    at se.iqpd.checkout.plus.CommonActivity.isPCLServiceRunning(CommonActivity.java:177)
    at se.iqpd.checkout.plus.CommonActivity.initService(CommonActivity.java:157)
    at se.iqpd.checkout.plus.ISMPWrapper.Initialize(ISMPWrapper.java:412)
    at se.iqpd.checkout.plus.main._activity_resume(main.java:1440)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:158)
    at se.iqpd.checkout.plus.main.afterFirstLayout(main.java:104)
    at se.iqpd.checkout.plus.main.access$100(main.java:16)
    at se.iqpd.checkout.plus.main$WaitForLayout.run(main.java:76)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4514)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
    at dalvik.system.NativeStart.main(Native Method)

the isPCLServiceRunning() Code

B4X:
    private boolean isPCLServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (PclService.class.getName().equals(service.service.getClassName())) {
                BA.Log("ISMPWrapper(CommonActivity)(isPCLServiceRunning) = true");
                return true;
            }
        }
        BA.Log("ISMPWrapper(CommonActivity)(isPCLServiceRunning) = false");
        return false;
    }
 

TheMightySwe

Active Member
Licensed User
Longtime User
Activity_Resume happens after the native onCreate method.

Yes, I do the Initialize in Activity_Resume, maybe I should do it even later. In a CallSubDelay called in Activity_Resume


I call it like this

B4X:
If Companion.IsInitialized = False Then
    Companion.Initialize("Companion","1","961")       
End If

I know it's hard to see problems when you don't have the entire code. And i'm no wiz at java at all. I maybe have to give up on this.
 

TheMightySwe

Active Member
Licensed User
Longtime User
Do you have a good way to make sure that the code in onCreate() and other OS events is actually executed in a external library before you have "Initialized"?

What does the @override command mean?
 

TheMightySwe

Active Member
Licensed User
Longtime User
I'm trying to connect to a external payment terminal. And i would not mind avoid wrapping at all!

This one....

http://www.ingenico.com/en/products/payment-terminals/mobility/ismp-companion/

Via ether this library (attached) or the external service (also attached).

If that is possible inside B4A no one would be more happy than me. I have tried for six months now.

The problem is that the library require some SO-files and i don't know if B4A can handle them.
And the external service require some AIDL files that i also have no clue if B4A can handle.

I have asked and got the advice to build a wrapper, and that is what i trying to do.

I think i just need a nudge in the right direction to crack this task.

This is the example code given to the external service

4.3.2. Binding steps with PclService.apk
1. Declare an instance of the IPclService interface (generated based on the AIDL).
2. Implement ServiceConnection.
3. In your implementation of onServiceConnected(), you will receive an IBinder instance (called service). Call IPclService.Stub.asInterface((IBinder)service) to cast the returned parameter to IPclService type.
4. To connect, call Context.bindService(), passing in your ServiceConnection implementation.
5. Call the methods defined on IPclService interface. You should always trap RemoteException exceptions, which are thrown when the connection has broken; this will be the only exception thrown by remote methods.
6. To disconnect, call Context.unbindService() with the instance of your interface.
Note that you need the Context object to be able to bind/unbind the service. This object is available in Service and Activity object. You can access the context using the getApplicationContext() function
The example below shows how to bind and unbind to the PclService:


B4X:
public class YourActivity extends Activity {
// Declare IPclService interface
protected IPclService mPclService = null;
// Declare Serviceconnection
private PclServiceConnection mServiceConnection;
// Implement ServiceConnection
class PclServiceConnection implements ServiceConnection
{
public void onServiceConnected(ComponentName className, IBinder boundService )
{
mPclService = IPclService.Stub.asInterface((IBinder)boundService);
}

public void onServiceDisconnected(ComponentName className)
{
mPclService = null;
}
};
// You can call this method in onCreate for instance to bind to
// the service
private void initService()
{ mServiceConnection = new PclServiceConnection();
Intent i = new Intent();
i.setClassName( "com.ingenico.pclservice",
"com.ingenico.pclservice.PclService" );
getApplicationContext().bindService( i, this.mServiceConnection,
Context.BIND_AUTO_CREATE);
}
// You can call this method in onDestroy for instance to unbind
// from the service
private void releaseService()
{
getApplicationContext().unbindService( this.mServiceConnection);
}
};


And this is the example code for the library

4.3.3. Binding steps with PclServiceLib.jar
1. Declare an instance of the PclService interface.
2. Implement ServiceConnection.
3. In your implementation of onServiceConnected(), you will receive an IBinder instance (called service). Cast the returned parameter to LocalBinder type and get PclService instance with getService().
4. To connect, call Context.bindService(), passing in your ServiceConnection implementation.
5. Call the methods defined on IPclService interface.
6. To disconnect, call Context.unbindService() with the instance of your interface.

B4X:
public class YourActivity extends Activity {
// Declare PclService interface
protected PclService mPclService = null;
// Declare Serviceconnection
private PclServiceConnection mServiceConnection;
// Implement ServiceConnection
class PclServiceConnection implements ServiceConnection
{
public void onServiceConnected(ComponentName className, IBinder boundService )
{
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) boundService;
mPclService = (PclService) binder.getService();
}
public void onServiceDisconnected(ComponentName className)
{
mPclService = null;
}
};
// You can call this method in onCreate for instance
private void initService()
{ mServiceConnection = new PclServiceConnection();
Intent intent = new Intent(this, PclService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
// You can call this method in onDestroy for instance
private void releaseService()
{
unbindService(mServiceConnection);
}
};

If any of this methods to connect to the terminal is possible inside B4A, it would great.
 

Attachments

  • PclServiceLib_1.9.1.jar
    52.8 KB · Views: 268
  • PclService_1.9.1.apk
    405.9 KB · Views: 250
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User

TheMightySwe

Active Member
Licensed User
Longtime User
Don't wrap a full activity or service unless you must. It will be simpler. You can call it from anywhere you like as long as it gets called once.

I might not be absolutly sure what a wrapper is.

But I will try this now and hope I make a breakthrough.
 
Top