Mini App SDK for Android
Provides functionality to show a Mini App in Android Applications. The SDK offers features like downloading, caching, updating, and displaying of a Mini App. Mini App SDK also facilitates communication between a mini app and the host app via a message bridge.
Requirements
Supported Android Versions
This SDK supports Android API level 21 (Lollipop) and above.
Getting Started
#1 Add dependency to your app’s build.gradle
repositories {
jcenter()
// Needed only if you want to use snapshot releases
maven { url 'http://oss.jfrog.org/artifactory/simple/libs-snapshot/' }
}
dependency {
implementation 'com.rakuten.tech.mobile.miniapp:miniapp:${version}'
}
#2 Configure SDK settings in AndroidManifest.xml
The SDK is configured via manifest meta-data, the configurable values are:
Field | Datatype | Manifest Key | Optional | Default |
---|---|---|---|---|
Base URL | String | com.rakuten.tech.mobile.miniapp.BaseUrl |
❌ | 🚫 |
Host App Version | String | com.rakuten.tech.mobile.miniapp.HostAppVersion |
❌ | 🚫 |
Host App User Agent Info | String | com.rakuten.tech.mobile.miniapp.HostAppUserAgentInfo |
✅ | 🚫 |
App ID | String | com.rakuten.tech.mobile.ras.AppId |
❌ | 🚫 |
RAS Project Subscription Key | String | com.rakuten.tech.mobile.ras.ProjectSubscriptionKey |
❌ | 🚫 |
Note:
- We don’t currently host a public API, so you will need to provide your own Base URL for API requests.
- All meta-data values must be string values, including the value for
com.rakuten.tech.mobile.miniapp.HostAppVersion
. For example it could be set to the string value1.0.0
, but if you need to use a number value such as1.0
or1
, then you must declare the value in your string resources (res/values/strings.xml
) and reference the string ID in the manifest, for example@string/app_version
. - The host app info is the string which is appended to user-agent of webview. It should be a meaningful keyword such as host app name to differentiate other host apps.
In your AndroidManifest.xml
:
<manifest>
<application>
<!-- Base URL used for retrieving a Mini App -->
<meta-data
android:name="com.rakuten.tech.mobile.miniapp.BaseUrl"
android:value="https://www.example.com" />
<!-- Version of your app - used to determine feature compatibility for Mini App -->
<meta-data
android:name="com.rakuten.tech.mobile.miniapp.HostAppVersion"
android:value="your_app_version" />
<!-- App ID for the Platform API -->
<meta-data
android:name="com.rakuten.tech.mobile.ras.AppId"
android:value="your_app_id" />
<!-- Subscription Key for the Platform API -->
<meta-data
android:name="com.rakuten.tech.mobile.ras.ProjectSubscriptionKey"
android:value="your_subscription_key" />
<!-- Optional User Agent Information relating to the host app -->
<meta-data
android:name="com.rakuten.tech.mobile.miniapp.HostAppUserAgentInfo"
android:value="app_name/version_info" />
</application>
</manifest>
#3 Fetch Mini App Info
Information about Mini Apps can be fetched in two different ways: by using MiniApp.listMiniApp
to get a list of info for all Mini Apps, or by using MiniApp.fetchInfo
to get info for a single Mini App. Either method will return MiniAppInfo
objects with info about the Mini App such as name, icon URL, ID, version, etc.
Use MiniApp.listMiniApp
if you want a list of all Mini Apps:
CoroutineScope(Dispatchers.Default).launch {
try {
val miniAppList = MiniApp.instance().listMiniApp()
} catch(e: MiniAppSdkException) {
Log.e("MiniApp", "There was an error retrieving the list", e)
}
}
Or use MiniApp.fetchInfo
if you want info for a single Mini App and already know the Mini App’s ID:
CoroutineScope(Dispatchers.Default).launch {
try {
val miniAppInfo = MiniApp.instance().fetchInfo("MINI_APP_ID")
} catch(e: MiniAppSdkException) {
Log.e("MiniApp", "There was an error retrieving the Mini App info", e)
}
}
Note: This SDK uses suspend
functions, so you should use Kotlin Coroutines when calling the functions. These examples use Dispatchers.Default
, but you can use whichever CoroutineContext
and CouroutineScope
that is appropriate for your App.
#4 Implement the MiniAppMessageBridge
The MiniAppMessageBridge
is used for passing messages between the Mini App (JavaScript) and the Host App (your native Android App) and vice versa. Your App must provide the implementation for these functions and pass this implementation to the MiniApp#create
function.
val miniAppMessageBridge = object: MiniAppMessageBridge() {
override fun getUniqueId() = AppSettings.instance.uniqueId
override fun requestPermission(
miniAppPermissionType: MiniAppPermissionType,
callback: (isGranted: Boolean) -> Unit
) {
// Implementation details to request device permission for location
// .. .. ..
}
}
#5 Create and display a Mini App
Calling MiniApp.create
with a MiniAppInfo
object will download the Mini App if it has not yet been downloaded. A view will then be returned which will display the Mini App. The MiniAppInfo
object also contains information about the latest Mini App version, so make sure to fetch the latest MiniAppInfo
first.
class MiniAppActivity : Activity(), CoroutineScope {
override val coroutineContext = Dispatchers.Main
override fun onCreate(savedInstanceState: Bundle?) {
super(savedInstanceState)
setContentView(R.layout.loading)
val context = this
launch {
try {
val miniAppDisplay = withContext(Dispatchers.Default) {
val miniAppInfo = MiniApp.instance().fetchInfo("MINI_APP_ID") // Or use `MiniApp.listMiniApp` if you want the whole list of Mini Apps
MiniApp.instance().create(miniAppInfo, miniAppMessageBridge)
}
val miniAppView = miniAppDisplay.getMiniAppView(this@MiniAppActivity)
setContentView(miniAppView)
} catch (e: MiniAppSdkException) {
setContentView(R.layout.error_screen)
}
}
}
}
MiniAppDisplay.navigateBackward
and MiniAppDisplay.navigateForward
facilitates the navigation inside a mini app if the history stack is available in it. A common usage pattern could be to link it up to the Android Back Key navigation.
Advanced
Clearing up mini app display
For a mini app, it is required to destroy necessary view state and any services registered with, either automatically or manually. MiniAppDisplay
complies to Android’s LifecycleObserver
contract. It is quite easy to setup for automatic clean up of resources.
class MiniAppActivity : Activity(), CoroutineScope {
override fun onCreate(savedInstanceState: Bundle?) {
//...
launch {
val miniAppDisplay = withContext(Dispatchers.Default) {
MiniApp.instance().create("mini_app_id", "mini_app_version_id")
}
lifeCycle.addObserver(miniAppDisplay)
//...
}
}
}
To read more about Lifecycle
please see link.
On the other hand, when the consuming app manages resources manually or where it has more control on the lifecycle of views MiniAppDisplay.destroyView
should be called upon e.g. when removing a view from the view system, yet within the same state of parent’s lifecycle.
Navigating inside a mini app
For a common usage pattern, the navigation inside a mini app can be attached to the Android back key navigation as shown:
override fun onBackPressed() {
if(!miniAppDisplay.navigateBackward()) {
super.onBackPressed()
}
}
Troubleshooting
AppCompat Version
androidx.appcompat:appcompat
The stable version of AndroidX AppCompat library 1.1.0
had issues on old Android OS when creating Webview
with ActivityContext
.
We recommend using the updated versions of this library.
Changelog
See the full CHANGELOG.