eUICC API

Di Android 9, API pengelolaan profil (publik dan @SystemApi) tersedia melalui class EuiccManager. API komunikasi eUICC (khusus @SystemApi) tersedia melalui class EuiccCardManager.

Tentang eUICC

Operator dapat membuat aplikasi operator menggunakan EuiccManager untuk mengelola profil, seperti yang ditunjukkan dalam Gambar 1. Aplikasi operator tidak harus berupa aplikasi sistem, tetapi harus memiliki hak istimewa operator yang diberikan oleh profil eUICC. Aplikasi LAP (backend LUI dan LPA) harus berupa aplikasi sistem (yaitu, disertakan dalam image sistem) untuk memanggil @SystemApi.

Ponsel Android dengan Aplikasi Operator dan LPA OEM

Gambar 1. Ponsel Android dengan aplikasi operator dan LPA OEM

Selain logika memanggil EuiccCardManager dan berkomunikasi dengan eUICC, aplikasi LPA harus menerapkan hal berikut:

  • Klien SM-DP+ berkomunikasi dengan server SM-DP+ untuk mengautentikasi dan mendownload profil
  • [Opsional] SM-DS untuk mendapatkan lebih banyak profil yang berpotensi dapat didownload
  • Penanganan notifikasi untuk mengirim notifikasi ke server guna memperbarui status profil
  • [Opsional] Pengelolaan slot termasuk beralih antara logika eSIM dan pSIM. Ini bersifat opsional jika ponsel hanya memiliki chip eSIM.
  • OTA eSIM

Meskipun ponsel Android dapat menampilkan lebih dari satu aplikasi LPA, hanya satu LPA yang dapat dipilih untuk menjadi LPA kerja sebenarnya berdasarkan prioritas yang ditetapkan dalam file AndroidManifest.xml setiap aplikasi.

Menggunakan EuiccManager

LPA API bersifat publik melalui EuiccManager (dalam paket android.telephony.euicc). Aplikasi operator dapat mendapatkan instance EuiccManager, dan memanggil metode di EuiccManager untuk mendapatkan informasi eUICC dan mengelola langganan (disebut sebagai profil dalam dokumen GSMA RSP) sebagai instance SubscriptionInfo.

Untuk memanggil API publik termasuk operasi download, beralih, dan menghapus langganan, aplikasi operator harus memiliki hak istimewa yang diperlukan. Hak istimewa operator ditambahkan oleh operator seluler di metadata profil. eUICC API menerapkan aturan hak istimewa operator sebagaimana mestinya.

Platform Android tidak menangani aturan kebijakan profil. Jika aturan kebijakan dideklarasikan dalam metadata profil, LPA dapat memilih cara menangani prosedur download dan penginstalan profil. Misalnya, LPA OEM pihak ketiga dapat menangani aturan kebijakan menggunakan kode error khusus (kode error diteruskan dari LPA OEM ke platform, lalu platform meneruskan kode ke LUI OEM).

Untuk informasi tentang beberapa API profil yang diaktifkan, lihat Beberapa profil yang diaktifkan.

API

API berikut dapat ditemukan di dokumentasi referensi EuiccManager dan EuiccManager.java.

Mendapatkan instance (publik)

Mendapatkan instance EuiccManager melalui Context#getSystemService. Untuk mengetahui detailnya, lihat getSystemService.

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

Centang diaktifkan (publik)

Memeriksa apakah langganan tersemat diaktifkan. Hal ini harus diperiksa sebelum mengakses LPA API. Untuk detailnya, lihat isEnabled.

boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
    return;
}

Dapatkan EID (publik)

Mendapatkan EID yang mengidentifikasi hardware eUICC. Nilai ini mungkin null jika eUICC belum siap. Pemanggil harus memiliki hak istimewa operator atau izin READ_PRIVILEGED_PHONE_STATE. Untuk mengetahui detailnya, lihat getEid.

String eid = mgr.getEid();
if (eid == null) {
  // Handle null case.
}

Mendapatkan EuiccInfo (publik)

Mendapatkan informasi tentang eUICC. File ini berisi versi OS. Untuk mengetahui detailnya, lihat getEuiccInfo.

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

Langganan download (publik)

Mendownload langganan yang ditentukan (disebut sebagai "profil" di dokumen GSMA RSP). Langganan dapat dibuat dari kode aktivasi. Misalnya, kode aktivasi dapat diuraikan dari kode QR. Mendownload langganan adalah operasi asinkron.

Pemanggil harus memiliki izin WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan target. Untuk mengetahui detailnya, lihat downloadSubscription.

// Register receiver.
String action = "download_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(
        receiver,
        new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/, null /* handler */);

// Download subscription asynchronously.
DownloadableSubscription sub =
        DownloadableSubscription.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */, callbackIntent);

Beralih langganan (publik)

Beralih ke (mengaktifkan) langganan yang diberikan. Pemanggil harus memiliki WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan yang saat ini diaktifkan dan langganan target. Untuk mengetahui detailnya, lihat switchToSubscription.

// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/, null /* handler */);

// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

Beralih langganan dengan port (publik)

(Tersedia dari Android 13) Beralih ke (mengaktifkan) langganan tertentu dengan indeks port yang ditentukan. Pemanggil harus memiliki WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan yang saat ini diaktifkan dan langganan target. Untuk mengetahui detailnya, lihat switchToSubscription.

// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/, null /* handler */);

// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, 0 /*portIndex*/, callbackIntent);

Apakah port SIM tersedia (publik)

public boolean isSimPortAvailable(int portIndex)

(Tersedia dari Android 13) Menampilkan apakah indeks port yang diteruskan tersedia. Port tersedia jika tidak mengaktifkan langganan atau aplikasi panggilan memiliki hak istimewa operator atas langganan yang diinstal di port yang dipilih. Untuk detailnya, lihat isSimPortAvailable.

Menghapus langganan (publik)

Menghapus langganan dengan ID langganan. Jika saat ini aktif, langganan akan dinonaktifkan terlebih dahulu. Pemanggil harus memiliki hak istimewa WRITE_EMBEDDED_SUBSCRIPTIONS atau operator untuk langganan target. Untuk mengetahui detailnya, lihat deleteSubscription.

// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/,
        null /* handler */);

// Delete a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.deleteSubscription(1 /* subscriptionId */, callbackIntent);

Menghapus semua langganan (API sistem)

Menghapus semua langganan di perangkat. Mulai dari Android 11, Anda harus memberikan nilai enum EuiccCardManager#ResetOption untuk menentukan apakah akan menghapus semua jenis langganan pengujian, operasional, atau keduanya. Pemanggil harus memiliki izin WRITE_EMBEDDED_SUBSCRIPTIONS.

// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/,
        null /* handler */);

// Erase all operational subscriptions asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.eraseSubscriptions(
        EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, callbackIntent);

Memulai aktivitas penyelesaian (publik)

Memulai aktivitas untuk menyelesaikan error yang dapat diselesaikan pengguna. Jika operasi menampilkan EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, metode ini dapat dipanggil untuk meminta pengguna menyelesaikan masalah. Metode ini hanya dapat dipanggil sekali untuk error tertentu.

...
mgr.startResolutionActivity(getActivity(), 0 /* requestCode */, resultIntent, callbackIntent);

Konstanta

Untuk melihat daftar konstanta public di EuiccManager, lihat Konstanta.