Activate eSIM using IPA
I am sure you already gone through android docs to implements esim.
https://source.android.com/docs/core/connect/esim-overview
If you have basic requirement to activate esim without scanning QR code, this is blog is for you.
There are many ways to activate eSim
- Settings -> SIM management -> Scan QR code
- Implement vendor app that support downloading esim profile and activate using EuiccManager
- Implement own LPA application
- Use system LPA
you can refer https://source.android.com/docs/core/connect/esim-overview for point 1, 2 and 3.
Here we will discuss about 4.
Let me list down simple steps to follow
- Open EUICC activity.
- Communicate using aidl
Open EUICC activity
We can directly open LPA app from your app. (Support after android 11)
We are passing EXTRA_USE_QR_SCANNER as false, because we don’t want to scan QR code.
try {
var intent = Intent(EuiccManager.ACTION_START_EUICC_ACTIVATION)
intent.putExtra(EuiccManager.EXTRA_USE_QR_SCANNER, false)
lPAActivityLauncher.launch(intent)
} catch (e: Exception) {
e.printStackTrace();
Toast.makeText(this,e.message,Toast.LENGTH_SHORT).show();
}
For security reasons, the LPA does not accept an activation code directly in the supplied intent. So we need to pass activation code using aidl
Communicate using aidl
The LPA and our app communicate through two AIDL interfaces: ICarrierEuiccProvisioningService
and IGetActivationCodeCallback
. The carrier app must implement an ICarrierEuiccProvisioningService
interface and expose it in its manifest declaration.
add two aidl file withing package android.service.euicc
ICarrierEuiccProvisioningService.aidl
package android.service.euicc;
import android.service.euicc.IGetActivationCodeCallback;
interface ICarrierEuiccProvisioningService {
void getActivationCode(in IGetActivationCodeCallback callback);
void getActivationCodeForEid(in String eid, in IGetActivationCodeCallback callback);
}
IGetActivationCodeCallback.aidl
package android.service.euicc;
interface IGetActivationCodeCallback {
oneway void onSuccess(String activationCode);
oneway void onFailure();
}
Implement CarrierEuiccProvisioningService in your package
package com.example.esimactivationtest
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.service.euicc.ICarrierEuiccProvisioningService
import android.service.euicc.IGetActivationCodeCallback
class CarrierEuiccProvisioningService : Service() {
val ACTIVATION_CODE = "" // activation code.
override fun onBind(intent: Intent?): IBinder? {
return binder
}
private val binder = object : ICarrierEuiccProvisioningService.Stub () {
override fun getActivationCode(callback: IGetActivationCodeCallback?) {
// you can write your own logic to fetch activation code from somewhere.
var activationCode : String = ACTIVATION_CODE
callback?.onSuccess(activationCode)
}
override fun getActivationCodeForEid(eid: String?, callback: IGetActivationCodeCallback?) {
var activationCode : String = ACTIVATION_CODE
callback?.onSuccess(activationCode)
}
}
}
declair CarrierEuiccProvisioningService in AndroidManifest.xml
<service
android:name=".CarrierEuiccProvisioningService"
android:exported="true"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS">
<intent-filter>
<action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/>
</intent-filter>
</service>
That’s all.