eUICC API

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

เกี่ยวกับ eUICC

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

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

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

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

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

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

ใช้ EuiccManager

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

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

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

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

API

คุณดู API ต่อไปนี้ได้ในเอกสารประกอบอ้างอิง และ EuiccManager.javaEuiccManager

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

รับอินสแตนซ์ของ 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 ค่านี้อาจเป็น Null หาก 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 ) คุณสร้างการสมัครใช้บริการได้จากรหัสเปิดใช้งาน ตัวอย่างเช่น คุณสามารถแยกวิเคราะห์รหัสเปิดใช้งานจากคิวอาร์โค้ดได้ การดาวน์โหลดข้อมูลการติดตาม เป็นการดำเนินการแบบไม่พร้อมกัน

ผู้โทรต้องมีสิทธิ์ 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);

พอร์ตซิมพร้อมใช้งาน (สาธารณะ)

public boolean isSimPortAvailable(int portIndex)

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

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

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