Activate eSIM using IPA

Kishan Vaghela
2 min readAug 24, 2022

--

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

  1. Open EUICC activity.
  2. 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.

--

--