Kotlin Android Dapp development issues.

Hi,
I am trying to make a Kotlin Android app. I have made some very basic code and it fails. Let me show my code first.

class ChatActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        val app = App(
            "com.example.safeapp",
            "SAFE Example",
            "myorg",
            "0.0.1"
        )
        ...
        ...
        val appExchangeInfo = AppExchangeInfo(app.id, "", app.name, app.vendor)
        val permissions = arrayOfNulls<ContainerPermissions>(0)
        val authRequest = AuthReq(appExchangeInfo, true, permissions, permissions.size.toLong(), 0)
        try {
            val request = Client.encodeAuthReq(authRequest) // This line fails
        } catch (e: Error) {
            throw e
        }
        ...
        ...
    }
}

When I try to run the app on an emulator I see error

    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.myorg.safe.safeapp, PID: 13676
        java.lang.BootstrapMethodError: Exception from call site #146 bootstrap method

Any help is appreciated.

2 Likes

hey @0mkara, before calling the SAFE APIs (which are written in Rust), you need to load the native libraries into memory. This is done by calling the following function:

Client.load(applicationContext)

4 Likes

Thanks for the info. Now I try to load native libraries like following.

Client.load(ChatActivity.instance)

I get another error after this

    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.myorg.safe.safeapp, PID: 15088
        java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/base.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_dependencies_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_resources_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_0_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_1_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_2_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_3_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_4_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_5_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_6_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_7_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_8_apk.apk", zip file "/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.myorg.safe.safeapp-ynZUtctTQHKunqVefs_b3A==/lib/x86, /system/lib]]] couldn't find "libsafe_app_jni.so"

Which basically says

couldn't find "libsafe_app_jni.so"

The Client.load() API requires the application context in order to get the app’s files directory to copy and load the native libraries. Does ChatActivity.instance return the context of the application?

I think it does. Otherwise Client.load() would not accept it as ApplocationContext. I will try again and if it does not work will share my code. :+1:

1 Like

This is a working snippet from my MainActivity.kt file that creates an auth request and sends it to the authenticator:

        Client.load(applicationContext)
        val app = App(
            "com.example.safeapp",
            "SAFE Example",
            "myorg",
            "0.0.1"
        )
        val appExchangeInfo = AppExchangeInfo(app.id, "", app.name, app.vendor)
        val permissions = arrayOfNulls<ContainerPermissions>(0)
        val authRequest = AuthReq(appExchangeInfo, true, permissions, permissions.size.toLong(), 0)
        val request = Client.encodeAuthReq(authRequest).get() // This line doesn't fail
        var intent = Intent(Intent.ACTION_VIEW, Uri.parse("safe-auth://" + app.id + "/" + request.uri))
        startActivity(intent)
3 Likes
Client.load(applicationContext)

This line itself gives me couldn't find "libsafe_app_jni.so" Error. Do I need to load any native libraries for this ?

That’s strange. How have you included the dependency in your project?
If you could please share your code in a repository, we can try to reproduce the issue on our end too. Thanks :slight_smile:

1 Like

https://gitlab.com/0mkara/safemsg
Here is my code.

2 Likes

After a quick glance I see that you’ve mentioned the x86 ABI in your build.gradle file.
The safe-app-android package is supported only on platforms with x86_64 or armeabi-v7a support. So trying to load the libs on a x86 emulator is probably the cause of the error.

EDIT: I fired up my x86 emulator and I was able to reproduce your error. Switching to a supported device / emulator will solve your issue.

2 Likes

Ok I changed my emulator to x86_64. Now I get a new error

Process: com.mathcody.safe.safemsg, PID: 6366
    java.lang.BootstrapMethodError: Exception from call site #151 bootstrap method
        at net.maidsafe.api.Session.setAdditionalSearchPath(Session.java:139)
        at net.maidsafe.api.Client.load(Client.java:36)
        at com.mathcody.safe.safemsg.ChatActivity.onCreate(ChatActivity.kt:26)
        ...
        Caused by: java.lang.ClassCastException: Bootstrap method returned null
1 Like

The safe-app-android library uses some Java 8 features. In order for your project to support this you will need to add the following in the android block of your build.gradle file.

compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
}

You can find more information on the android developer website.

1 Like

Thanks for the info @lionel.faber. This finally solved the issue.

Now there is a new issue. The app screen seems to keep flashing in some infinite loop. Although I see no error but logs say

/OpenGLRenderer: Davey! duration=828ms; Flags=0, IntendedVsync=6852234425328, Vsync=6853001091964, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=6853016166220, AnimationStart=6853016236000, PerformTraversalsStart=6853016318050, DrawStart=6853017864740, SyncQueued=6853019519700, SyncStart=6853021080060, IssueDrawCommandsStart=6853021137700, SwapBuffers=6853039065080, FrameCompleted=6853064294770, DequeueBufferDuration=203000, QueueBufferDuration=794000, 
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@40a35bf
I/JSA: set Tag for ViewHolder, position: 0
I/JSA: set Tag for ViewHolder, position: 1
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@c50ebc1
I/JSA: set Tag for ViewHolder, position: 0
I/JSA: set Tag for ViewHolder, position: 1
D/EGL_emulation: eglMakeCurrent: 0x7b08ac0724a0: ver 2 0 (tinfo 0x7b08ac00dcc0)
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@5250233
I/JSA: set Tag for ViewHolder, position: 0

If you know anything about it please inform.

1 Like

I had a look at the latest code in your repository and I’ve identified the issue. In your Android Manifest you have registered the safe-auth scheme for your application. The safe-auth scheme is registered for the SafeAuthenticator mobile application.

Encoding a request, prepending it with safe-auth and opening it will redirect you to the authenticator which can process the request. Since your application is registered with safe-auth when you send the auth request it starts the same application again, which sends another auth request and it’s stuck in an infinite loop.

The scheme that has to be registered for your application is your application’s ID. com.mathcody.safe.safemsg in this case.

Yes I tried that first. It gave me an error

Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=safe-auth://com.mathcody.safe.safemsg/bAAAAAAALQKL7KAAAAAABSAAAAAAAAAAAMNXW2LTNMF2GQY3PMR4S443BMZSS443BMZSW243HAEAAAAAAAAAAAAAMAAAAAAAAAAAFGQKGIUQEK6DBNVYGYZIIAAAAAAAAAAAG2YLUNBRW6ZDZAEAAAAAAAAAAAAAB }

Do I need to install SafeAuthenticator mobile separately or what ?

Yes. You will need to download and install the safe authenticator application from the link. This will process and authorise application requests.

This topic was automatically closed after 60 days. New replies are no longer allowed.