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 :))

Code: Copy
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.

Code: Copy
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?
 
Something like:
Code: Copy
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....
 
I got some error...

Code: Copy
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");
 
Hi,

Also a similar error.. Do I need to cast it to the andriod.app.Application type/object?
 
Mmh, Getting frustrated here :mad: I have never done this before so I might (probably) making stupid mistakes.

I tried 2 things:

First:

Code: Copy
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:

Code: Copy
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):

Code: Copy
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 :

Code: Copy
** 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?
 
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.
 
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 :)
 
Finally it is working. This is the working code.

Code: Copy
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.
 
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:
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 :(
 
Finally it is working. This is the working code.

Code: Copy
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.
 
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.
 
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.
 
Back
Top