API eUICC

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

Tentang eUICC

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

Ponsel Android dengan Aplikasi Operator dan OEM LPA

Gambar 1. Ponsel Android dengan aplikasi operator dan OEM LPA

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

  • Klien SM-DP+ berbicara dengan server SM-DP+ untuk mengautentikasi dan mengunduh profil
  • [Opsional] SM-DS untuk mendapatkan lebih banyak profil potensial yang dapat diunduh
  • Penanganan notifikasi untuk mengirimkan notifikasi ke server untuk memperbarui status profil
  • [Opsional] Manajemen slot termasuk peralihan antara logika eSIM dan pSIM. Ini opsional jika ponsel hanya memiliki chip eSIM.
  • eSIM OTA

Meskipun lebih dari satu aplikasi LPA dapat ada di ponsel Android, hanya satu LPA yang dapat dipilih untuk menjadi LPA yang berfungsi sebenarnya berdasarkan prioritas yang ditentukan dalam file AndroidManifest.xml setiap aplikasi.

Menggunakan EuiccManager

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

Untuk memanggil API publik termasuk operasi pengunduhan, peralihan, dan penghapusan langganan, aplikasi operator harus memiliki hak istimewa yang diperlukan. Hak istimewa operator ditambahkan oleh operator seluler di metadata profil. API eUICC menerapkan aturan hak istimewa operator.

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

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

Lebah

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

Dapatkan contoh (publik)

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

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

Periksa diaktifkan (publik)

Memeriksa apakah langganan tertanam diaktifkan. 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 perangkat keras eUICC. Ini mungkin nol jika eUICC belum siap. Penelepon harus memiliki hak istimewa operator atau izin READ_PRIVILEGED_PHONE_STATE . Untuk detailnya, lihat getEid .

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

Dapatkan EuiccInfo (publik)

Mendapatkan informasi tentang eUICC. Ini berisi versi OS. Untuk detailnya, lihat getEuiccInfo .

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

Unduh langganan (publik)

Mengunduh langganan tertentu (disebut sebagai "profil" dalam dokumen GSMA RSP). Langganan dapat dibuat dari kode aktivasi. Misalnya, kode aktivasi dapat diuraikan dari kode QR. Mengunduh langganan adalah operasi asinkron.

Penelepon harus memiliki izin WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan target. Untuk 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 tertentu. Penelepon harus memiliki WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan yang diaktifkan saat ini dan langganan target. Untuk 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. Penelepon harus memiliki WRITE_EMBEDDED_SUBSCRIPTIONS atau memiliki hak istimewa operator untuk langganan yang diaktifkan saat ini dan langganan target. Untuk 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 (umum)

public boolean isSimPortAvailable(int portIndex)

(Tersedia dari Android 13) Mengembalikan apakah indeks port yang lewat tersedia. Port tersedia jika langganan tidak diaktifkan atau aplikasi panggilan memiliki hak istimewa operator atas langganan yang diinstal pada port yang dipilih. Untuk detailnya, lihat isSimPortAvailable .

Hapus langganan (publik)

Menghapus langganan dengan ID langganan. Jika langganan saat ini aktif, langganan tersebut dinonaktifkan terlebih dahulu. Penelepon harus memiliki hak istimewa WRITE_EMBEDDED_SUBSCRIPTIONS atau operator untuk langganan target. Untuk 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);

Hapus semua langganan (API sistem)

Menghapus semua langganan di perangkat. Mulai Android 11, Anda harus memberikan nilai enum EuiccCardManager#ResetOption untuk menentukan apakah akan menghapus semua jenis langganan pengujian, operasional, atau kedua-duanya. Penelepon 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);

Mulai aktivitas resolusi (publik)

Memulai aktivitas untuk mengatasi kesalahan yang dapat diselesaikan pengguna. Jika operasi mengembalikan EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR , metode ini dapat dipanggil untuk meminta pengguna menyelesaikan masalah. Metode ini hanya dapat dipanggil satu kali untuk kesalahan tertentu.

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

Konstanta

Untuk melihat daftar konstanta public di EuiccManager , lihat Constants .