API ของ eUICC

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

เกี่ยวกับ eUICC

ผู้ให้บริการสามารถสร้างแอปของผู้ให้บริการโดยใช้ EuiccManager เพื่อจัดการโปรไฟล์ได้ดังต่อไปนี้ ในรูปที่ 1 แอปของผู้ให้บริการไม่จำเป็นต้องเป็นแอประบบ แต่ต้องมีผู้ให้บริการ สิทธิ์ที่ได้รับจากโปรไฟล์ eUICC CANNOT TRANSLATE แอป 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 ใน eSIM

แม้ว่าโทรศัพท์ Android จะมีแอป LPA ได้มากกว่า 1 แอป แต่ 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 เอกสาร ) การสมัครใช้บริการนี้สร้างขึ้นได้จากรหัสเปิดใช้งาน สำหรับ เช่น จะแยกวิเคราะห์รหัสเปิดใช้งานจากคิวอาร์โค้ดได้ การดาวน์โหลด การสมัครใช้บริการเป็นการดำเนินการที่ไม่พร้อมกัน

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