eUICC APIs

ใน Android 9 API การจัดการโปรไฟล์ (สาธารณะและ @SystemApi) มีให้ใช้งานผ่านคลาส EuiccManager API การสื่อสาร eUICC (@SystemApi เท่านั้น) พร้อมใช้งานผ่านคลาส EuiccCardManager

เกี่ยวกับ eUICC

ผู้ให้บริการสามารถสร้างแอปของผู้ให้บริการโดยใช้ EuiccManager เพื่อจัดการโปรไฟล์ ดังแสดงในรูปที่ 1 แอปของผู้ให้บริการไม่จำเป็นต้องเป็นแอประบบ แต่ต้องมีสิทธิ์ของผู้ให้บริการที่ได้รับจากโปรไฟล์ eUICC แอป LPA (แบ็กเอนด์ LUI และ LPA) จะต้องเป็นแอประบบ (เช่น รวมอยู่ในอิมเมจระบบ) เพื่อเรียก @SystemApi

โทรศัพท์ Android พร้อมแอป Carrier และ OEM LPA

รูปที่ 1 โทรศัพท์ Android ที่มีแอปของผู้ให้บริการและ OEM LPA

นอกจากตรรกะในการเรียก EuiccCardManager และการพูดคุยกับ eUICC แล้ว แอป LPA ยังต้องใช้สิ่งต่อไปนี้:

  • ไคลเอนต์ SM-DP+ พูดคุยกับเซิร์ฟเวอร์ SM-DP+ เพื่อตรวจสอบสิทธิ์และดาวน์โหลดโปรไฟล์
  • [ไม่บังคับ] SM-DS เพื่อรับโปรไฟล์ที่สามารถดาวน์โหลดได้มากขึ้น
  • การจัดการการแจ้งเตือนเพื่อส่งการแจ้งเตือนไปยังเซิร์ฟเวอร์เพื่ออัปเดตสถานะโปรไฟล์
  • [ไม่บังคับ] การจัดการสล็อตรวมถึงการสลับระหว่างลอจิก eSIM และ pSIM นี่เป็นทางเลือกหากโทรศัพท์มีชิป eSIM เท่านั้น
  • อีซิม OTA

แม้ว่าจะสามารถแสดงแอป LPA ได้มากกว่าหนึ่งแอปในโทรศัพท์ Android แต่สามารถเลือกได้เพียง LPA เดียวให้เป็น LPA ที่ใช้งานได้จริงตามลำดับความสำคัญที่กำหนดไว้ในไฟล์ AndroidManifest.xml ของแต่ละแอป

การใช้ EuiccManager

LPA API เป็นแบบสาธารณะผ่าน EuiccManager (ภายใต้แพ็คเกจ android.telephony.euicc ) แอปผู้ให้บริการสามารถรับอินสแตนซ์ของ EuiccManager และเรียกใช้เมธอดใน EuiccManager เพื่อรับข้อมูล eUICC และจัดการการสมัครรับข้อมูล (เรียกว่าโปรไฟล์ในเอกสาร GSMA RSP) เป็นอินสแตนซ์ SubscriptionInfo

หากต้องการเรียก API สาธารณะ รวมถึงการดาวน์โหลด สลับ และลบการสมัครรับข้อมูล แอปของผู้ให้บริการจะต้องมีสิทธิ์ที่จำเป็น ผู้ให้บริการมือถือจะเพิ่มสิทธิ์ของผู้ให้บริการในข้อมูลเมตาของโปรไฟล์ eUICC API บังคับใช้กฎสิทธิ์ของผู้ให้บริการตามนั้น

แพลตฟอร์ม Android ไม่รองรับกฎนโยบายโปรไฟล์ หากมีการประกาศกฎนโยบายในข้อมูลเมตาของโปรไฟล์ LPA จะสามารถเลือกวิธีจัดการขั้นตอนการดาวน์โหลดและการติดตั้งโปรไฟล์ได้ ตัวอย่างเช่น เป็นไปได้ที่ OEM LPA บุคคลที่สามจะจัดการกฎนโยบายโดยใช้รหัสข้อผิดพลาดพิเศษ (รหัสข้อผิดพลาดจะถูกส่งจาก OEM LPA ไปยังแพลตฟอร์ม จากนั้นแพลตฟอร์มจะส่งรหัสไปยัง OEM LUI)

สำหรับข้อมูลเกี่ยวกับ API โปรไฟล์ที่เปิดใช้งานหลายรายการ โปรดดูที่ โปรไฟล์ที่เปิดใช้งานหลายโปรไฟล์

API

API ต่อไปนี้สามารถพบได้ใน เอกสารอ้างอิง EuiccManager และ EuiccManager.java

รับอินสแตนซ์ (สาธารณะ)

รับอินสแตนซ์ของ EuiccManager ผ่าน Context#getSystemService สำหรับรายละเอียด โปรดดูที่ getSystemService

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

เปิดใช้งานการตรวจสอบ (สาธารณะ)

ตรวจสอบว่าการสมัครสมาชิกแบบฝังเปิดใช้งานอยู่หรือไม่ ควรตรวจสอบสิ่งนี้ก่อนเข้าถึง LPA API สำหรับรายละเอียด โปรดดูที่ isEnabled

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

รับ EID (สาธารณะ)

รับ EID ที่ระบุฮาร์ดแวร์ eUICC นี่อาจเป็นโมฆะหาก eUICC ยังไม่พร้อม ผู้โทรจะต้องมีสิทธิ์ของผู้ให้บริการหรือสิทธิ์ READ_PRIVILEGED_PHONE_STATE สำหรับรายละเอียด โปรดดู getEid

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

รับ EuiccInfo (สาธารณะ)

รับข้อมูลเกี่ยวกับ eUICC ข้อมูลนี้มีเวอร์ชันของระบบปฏิบัติการ สำหรับรายละเอียด โปรดดูที่ getEuiccInfo

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

ดาวน์โหลดการสมัครสมาชิก (สาธารณะ)

ดาวน์โหลดการสมัครรับข้อมูลที่ระบุ (เรียกว่า "โปรไฟล์" ในเอกสาร GSMA RSP) สามารถสร้างการสมัครสมาชิกได้จากรหัสเปิดใช้งาน ตัวอย่างเช่น รหัสเปิดใช้งานสามารถแยกวิเคราะห์จากรหัส QR ได้ การดาวน์โหลดการสมัครสมาชิกเป็นการดำเนินการแบบอะซิงโครนัส

ผู้โทรต้องมีสิทธิ์ WRITE_EMBEDDED_SUBSCRIPTIONS หรือมีสิทธิ์ของผู้ให้บริการสำหรับการสมัครสมาชิกเป้าหมาย สำหรับรายละเอียด โปรดดูที่ 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);

สลับการสมัครสมาชิก (สาธารณะ)

สลับไปที่ (เปิดใช้งาน) การสมัครสมาชิกที่กำหนด ผู้โทรต้องมี WRITE_EMBEDDED_SUBSCRIPTIONS หรือมีสิทธิ์ของผู้ให้บริการสำหรับการสมัครสมาชิกที่เปิดใช้งานปัจจุบันและการสมัครสมาชิกเป้าหมาย สำหรับรายละเอียด โปรดดูที่ 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);

สลับการสมัครสมาชิกด้วยพอร์ต (สาธารณะ)

(พร้อมใช้งานจาก Android 13) สลับเป็น (เปิดใช้งาน) การสมัครสมาชิกที่ระบุด้วยดัชนีพอร์ตที่ระบุ ผู้โทรต้องมี WRITE_EMBEDDED_SUBSCRIPTIONS หรือมีสิทธิ์ของผู้ให้บริการสำหรับการสมัครสมาชิกที่เปิดใช้งานปัจจุบันและการสมัครสมาชิกเป้าหมาย สำหรับรายละเอียด โปรดดูที่ 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);

มีพอร์ต SIM หรือไม่ (สาธารณะ)

public boolean isSimPortAvailable(int portIndex)

(พร้อมใช้งานจาก Android 13) ส่งคืนว่ามีดัชนีพอร์ตที่ส่งผ่านหรือไม่ พอร์ตจะใช้งานได้หากไม่มีการเปิดใช้งานการสมัครสมาชิกหรือแอปที่โทรมีสิทธิ์ของผู้ให้บริการมากกว่าการสมัครสมาชิกที่ติดตั้งบนพอร์ตที่เลือก สำหรับรายละเอียด โปรดดูที่ isSimPortAvailable

ลบการสมัครสมาชิก (สาธารณะ)

ลบการสมัครสมาชิกด้วย ID การสมัครสมาชิก หากการสมัครสมาชิกยังใช้งานอยู่ ระบบจะปิดการใช้งานก่อน ผู้โทรต้องมีสิทธิ์ WRITE_EMBEDDED_SUBSCRIPTIONS หรือผู้ให้บริการสำหรับการสมัครสมาชิกเป้าหมาย สำหรับรายละเอียด โปรดดูที่ 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);

ลบการสมัครสมาชิกทั้งหมด (ระบบ API)

ลบการสมัครสมาชิกทั้งหมดบนอุปกรณ์ ตั้งแต่ Android 11 เป็นต้นไป คุณควรระบุค่าแจงนับ EuiccCardManager#ResetOption เพื่อระบุว่าจะลบการสมัครใช้งานการทดสอบ การดำเนินการ หรือทั้งสองประเภททั้งหมดหรือไม่ ผู้โทรต้องมีสิทธิ์ 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);

เริ่มกิจกรรมการแก้ปัญหา (สาธารณะ)

เริ่มต้นกิจกรรมเพื่อแก้ไขข้อผิดพลาดที่ผู้ใช้แก้ไขได้ หากการดำเนินการส่งคืน EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR คุณสามารถเรียกใช้เมธอดนี้ได้เพื่อแจ้งให้ผู้ใช้แก้ไขปัญหา วิธีนี้สามารถเรียกได้เพียงครั้งเดียวเท่านั้นสำหรับข้อผิดพลาดเฉพาะ

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

ค่าคงที่

หากต้องการดูรายการค่าคง public ใน EuiccManager โปรดดู ค่าคงที่