Java Question My First Library (testflightapp wrapper)

marcel

Active Member
Licensed User
Longtime User
Hi,

I thought it was simple. But I am stock. This is my library code so far (almost nothing :))

B4X:
package cyclone.b4a.testflightapp;

import com.testflightapp.lib.TestFlight;

import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@Version(1.0f)
@Permissions(values={"android.permission.INTERNET","android.permission.ACCESS_NETWORK_STATE"})
@ShortName("TestFlight")
@DependsOn(values={"TestFlight"})
@ActivityObject
public class TestFlightWrapper {

}

Now I need to include the code that normally is called directly into a java application.

B4X:
public class MyApplication extends Application {
            @Override
            public void onCreate() {
                super.onCreate();
                //Initialize TestFlight with your app token.
                TestFlight.takeOff(this, YOUR_APP_TOKEN);
                ...
            }
}

But I am not sure how to implement this in my library...

Can anyone help me with this?
 

marcel

Active Member
Licensed User
Longtime User
Something like:
B4X:
public class TestFlightWrapper {
private TestFlight tf;

public void Initialize() {

  tf = new TestFlight();
}

public void TakeOff(BA ba, ...)
{

  tf.takeOff(ba.context, ...);
}
}

Thanks! So ba.context is the same a this....
 

marcel

Active Member
Licensed User
Longtime User
I got some error...

B4X:
takeOff(android.app.Application,java.lang.String) in com.testflightapp.lib.TestFlight cannot be applied to (android.content.Context,java.lang.String)
  tf.takeOff(ba.context,"aaaaaaaaaa");
 

marcel

Active Member
Licensed User
Longtime User
Hi,

Also a similar error.. Do I need to cast it to the andriod.app.Application type/object?
 

marcel

Active Member
Licensed User
Longtime User
Mmh, Getting frustrated here :mad: I have never done this before so I might (probably) making stupid mistakes.

I tried 2 things:

First:

B4X:
package cyclone.b4a.testflightapp;

import com.testflightapp.lib.TestFlight;

import android.app.Application;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@Version(1.02f)
@Permissions(values={"android.permission.INTERNET","android.permission.ACCESS_NETWORK_STATE"})
@ShortName("TestFlightApp")

public class TestFlightWrapper extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        BA.Log("MyApplication onCreate");
        TestFlight.takeOff(this, "hidden");
        BA.Log("Takeoff done");
        // try your code after calling super.onCreate()
    }
}

and add in the manifest:

B4X:
SetApplicationAttribute(android:name, "cyclone.b4a.testflightapp.TestFlightWrapper")

This executes the application and the method OnCreate and after that the application just stops. It does not load the rest of my app.

In the second try I have (part of the code):

B4X:
public class TestFlightWrapper {
private TestFlight tf;

/*
*  Initialize the library testflightapp
*/
public void Initialize(BA ba) {
    BA.Log("Wrapper TestFlight Init");
    tf = new TestFlight();
    BA.Log("Wrapper TestFlight Init");
    tf.takeOff(ba.activity.getApplication(), "hidden");
}



and get the error :

B4X:
** Activity (main) Create, isFirst = true **
Wrapper TestFlight Init
main_activity_create (java line: 313)
java.lang.NoClassDefFoundError: com.testflightapp.lib.TestFlight
    at cyclone.b4a.testflightapp.TestFlightWrapper.Initialize(TestFlightWrapper.java:23)
    at com.yazula.android.main._activity_create(main.java:313)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    at com.yazula.android.main.afterFirstLayout(main.java:98)
    at com.yazula.android.main.access$100(main.java:16)
    at com.yazula.android.main$WaitForLayout.run(main.java:76)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4921)
    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:1027)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
    at dalvik.system.NativeStart.main(Native Method)

SO it cannot find the class TestFlight. So maybe this isn't a class and takeoff should be called like:

TestFlight.takeOff(ba.activity.getApplication(), "hidden");

this gives a java.lang.NullPointerException. Which make sense because the object might be null???? :confused:

Anyone to point me in the correct direction?
 

warwound

Expert
Licensed User
Longtime User
If your add @Permissions to a class that extends Application i think it will not have effect.
I'm sure i found this myself - the b4a compiler didn't add the permissions to the manifest.
I'm not 100% sure on that but it's worth checking the manifest of your compiled project to see if the permissions are added or not.

Next comment out the BA.Log statements - it might be that the BA object is not properly initialized when the Application subclass is constructed and that might cause an exception.

Lastly have you forgotten to add the @DependsOn annotation to the class which throws the NoClassDefFoundError exception?

Martin.
 

marcel

Active Member
Licensed User
Longtime User
Hi,

Thanks for trying to help me.

If your add @Permissions to a class that extends Application i think it will not have effect.
I'm sure i found this myself - the b4a compiler didn't add the permissions to the manifest.
I'm not 100% sure on that but it's worth checking the manifest of your compiled project to see if the permissions are added or not.

I tried this also with no effect. The program does not continue. It seem that only some part is executed and then is stops. There is nothing in the log file of a crash or anything else.

Next comment out the BA.Log statements - it might be that the BA object is not properly initialized when the Application subclass is constructed and that might cause an exception.

I removed that one. but unfortunatly not an improvement.

Lastly have you forgotten to add the @DependsOn annotation to the class which throws the NoClassDefFoundError exception?

I do not understand this correctly. When I add f.e. @DependsOn(values="TestFlight") then I get in the main program when I use my wrapper library a compiler error: A referenced library is missing: testflight

So I though this option was only needed when you are dependen on other B4A libs.

I am completly lost here. I am not sure I do the right thing and which of the options (extend the application or not) I need to follow. I really like to use the testflightlib because it is very handy for beta testing and remote loging.. We will use this also in iOs.

And in basic is is just 2 functions that needs to be wrapped, which sounds easy but is not :)
 

marcel

Active Member
Licensed User
Longtime User
Finally it is working. This is the working code.

B4X:
package cyclone.b4a.testflightapp;

import com.testflightapp.lib.TestFlight;

import android.app.Application;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@Version(1.05f)
@Permissions(values={"android.permission.INTERNET","android.permission.ACCESS_NETWORK_STATE"})
@ShortName("TestFlightApp")
@DependsOn(values={"TestFlightLib"})
public class TestFlightWrapper {
private TestFlight tf;
private Application _app;

    /*
    *  Initialize the library testflightapp
    */
    public void Initialize(BA ba) {
        BA.Log("Wrapper TestFlight Init");
        tf = new TestFlight();
        if (tf == null) {
          BA.Log("TestFlight class is null");
        } else {
            BA.Log("Ready Takeoff");
            _app = ba.applicationContext;
            BA.Log("Ready app id");
            tf.takeOff(_app, "eeeeeaaaaa");
            BA.Log("Done take off");
        }
    }


    /*
    *  Log information to test www.testfligthapp.com
    */
    public void Log(String data)
    {
        tf.log(data);
    }
  
    /*
    *  PassCheckPoint information www.testfligthapp.com
    */
    public void PassCheckPoint(String data)
    {
      tf.passCheckpoint(data);
    }
}

:):)

When all functions is working correctly I will publish the library.
 

TpS

Member
Licensed User
Longtime User
Hello @marcel

Do we have any progress on this?
I´d like to use testflight as a platform for distributing my betas and this seems to be the way to go.

Regards

Edit: Never mind, just saw that Android Support was discontinued :/
 
Last edited:

marcel

Active Member
Licensed User
Longtime User
Yes, That was the problem. I have convert everything. USed it for a month to test and then it was discontinued because apple took it over :(
 

Theera

Well-Known Member
Licensed User
Longtime User
Finally it is working. This is the working code.

B4X:
package cyclone.b4a.testflightapp;

import com.testflightapp.lib.TestFlight;

import android.app.Application;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@Version(1.05f)
@Permissions(values={"android.permission.INTERNET","android.permission.ACCESS_NETWORK_STATE"})
@ShortName("TestFlightApp")
@DependsOn(values={"TestFlightLib"})
public class TestFlightWrapper {
private TestFlight tf;
private Application _app;

    /*
    *  Initialize the library testflightapp
    */
    public void Initialize(BA ba) {
        BA.Log("Wrapper TestFlight Init");
        tf = new TestFlight();
        if (tf == null) {
          BA.Log("TestFlight class is null");
        } else {
            BA.Log("Ready Takeoff");
            _app = ba.applicationContext;
            BA.Log("Ready app id");
            tf.takeOff(_app, "eeeeeaaaaa");
            BA.Log("Done take off");
        }
    }


    /*
    *  Log information to test www.testfligthapp.com
    */
    public void Log(String data)
    {
        tf.log(data);
    }
 
    /*
    *  PassCheckPoint information www.testfligthapp.com
    */
    public void PassCheckPoint(String data)
    {
      tf.passCheckpoint(data);
    }
}

:):)

When all functions is working correctly I will publish the library.

Where did you get java file? Please give me the link,I need to learn create this library.
 

Theera

Well-Known Member
Licensed User
Longtime User
Thank you for reply. Do you still have the source code to convert this library? I would like to learn ,I can do only function to be library.
 

marcel

Active Member
Licensed User
Longtime User
Thank you for reply. Do you still have the source code to convert this library? I would like to learn ,I can do only function to be library.
The code is here above. The actual lib from testflight you do need to download but becuase this is not valid anymore you can't. So I think it is better to use something else to learn create libraries.
 
Top