[GUIDE] How to add libretroshare to your Android app

There are a Maven repository where you can download libretroshare and add it to your Android project:

https://gitlab.com/elRepo.io/libretroshare/-/packages

Lets see step by step how to add it and use it.

Import libretroshare dependencies

On your android/app/build.gradle add the repository. See. You have to pay attention on dependency implementation where the last numbers are the target commit hash of the library (and could vary, check packages link above).

[...]
repositories {
    maven {
        url "https://gitlab.com/api/v4/projects/32902664/packages/maven"
    }
}

dependencies {
    [...]
    implementation "org.retroshare.service:libretroshare-MinApiLevel24-debug:f343db4c"
}

If is a flutter plugin add inside rootProject.allprojects :

rootProject.allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url "https://gitlab.com/api/v4/projects/32902664/packages/maven"
        }
    }
}

Add the service to your project

Then on the android manifest you have to declare the service and give some permissions:


    <application
[...]


        <service
            android:name="org.retroshare.service.RetroShareServiceAndroid"
        />
    </application>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
[...]

The service you have to declare could be org.retroshare.service.RetroShareServiceAndroid if you want to start the android service defined here.

However, you could make your own implementation for do a foreground service. In this case, the service should point to .MyOwnImplementation, and do a proper inheritance of RetroShareServiceAndroid.java.

Writing Android code

After that, start the service is so easy:


                        rService.start(
                            context,
                            rService.DEFAULT_JSON_API_PORT,
                            rService.DEFAULT_JSON_API_BINDING_ADDRESS
                        )

For more complex implementation on our flutter app we can do further steps:

  • We can use a permission handler to manage the permissions. Add the permission handler (you can find it here).

  • Then add the native calls codes:

{
                "getPlatformVersion" -> {
                    result.success("Android ${android.os.Build.VERSION.RELEASE}")
                }
                "hasPermissions" -> {
                    var hasPermissions = permissionHandler!!.isIgnoringBatteryOptimizations()
                            && permissionHandler!!.isWakeLockPermissionGranted()
                    result.success(hasPermissions)
                }
                "initialize" -> {
                    // todo: not working
                    val title = call.argument<String>("android.notificationTitle")
                    val text = call.argument<String>("android.notificationText")
                    val importance = call.argument<Int>("android.notificationImportance")
                    val iconName = call.argument<String>("android.notificationIconName")
                    val iconDefType = call.argument<String>("android.notificationIconDefType")

                    // todo: not working
                    // Set static values so the RetroShareServiceAndroid can use them later on to configure the notification
                    notificationImportance = importance ?: notificationImportance
                    notificationTitle = title ?: notificationTitle
                    notificationText = text ?: text
                    notificationIconName = iconName ?: notificationIconName
                    notificationIconDefType = iconDefType ?: notificationIconDefType

                    // Ensure wake lock permissions are granted
                    if (!permissionHandler!!.isWakeLockPermissionGranted()) {
                        result.error("PermissionError", "Please add the WAKE_LOCK permission to the AndroidManifest.xml in order to use background_sockets.", "")
                    }
//                    // Ensure ignoring battery optimizations is enabled
                    if (!permissionHandler!!.isIgnoringBatteryOptimizations()) {
                        if (activity != null) {
                            permissionHandler!!.requestBatteryOptimizationsOff(result, activity!!)
                        } else {
                            result.error("NoActivityError", "The plugin is not attached to an activity", "The plugin is not attached to an activity. This is required in order to request battery optimization to be off.")
                        }
                    }
                    result.success(true)
                }
                "enableBackgroundExecution" -> {
                    // Ensure all the necessary permissions are granted
                    if (!permissionHandler!!.isWakeLockPermissionGranted()) {
                        result.error("PermissionError", "Please add the WAKE_LOCK permission to the AndroidManifest.xml in order to use background_sockets.", "")
                    } else if (!permissionHandler!!.isIgnoringBatteryOptimizations()) {
                        result.error("PermissionError", "The battery optimizations are not turned off.", "")
                    } else {
                        rService.start(
                            context,
                            rService.DEFAULT_JSON_API_PORT,
                            rService.DEFAULT_JSON_API_BINDING_ADDRESS
                        )
                        result.success(true)
                    }
                }
                "disableBackgroundExecution" -> {
                    rService.stop(
                        context,
                    )
                    result.success(true)
                }
                else -> {
                    result.notImplemented()
                }
            }

Writing flutter side code

And if you do something similar to this you will be able to start stop RS from your flutter code.

Create foreground notification

Check this commit to see how to implement a custom RS service with a foreground notification.

Some key parts when inheriting from RetroShareServiceAndroid are to code a custom implementation for start and stop functions, see that kotlin can't inherit static java functions, so, check at commit above to see how to solve it.

Also remember to call super methods on onBind or onStartCommand etc...

Migrate from Qt RetroShare android app

As elRepo.io works before, it used the Qt embed RetroShare service apk. See this commit to see all changes made to migrate it to use the maven repository.

b36638df

If you already installed/compiled the app, maybe you need to uninstall it form device and clear caches on your IDE.

On the error Type org.retroshare.service.AssetHelper is defined multiple times we had to remove build folder.

Edited by selankon