เทคโนโลยีซิมแบบฝัง (eSIM หรือ eUICC) ช่วยให้ผู้ใช้โทรศัพท์มือถือ ดาวน์โหลดโปรไฟล์ผู้ให้บริการและเปิดใช้งานบริการของผู้ให้บริการได้โดยไม่ต้องมี ซิมการ์ดจริง ซึ่งเป็นข้อกำหนดระดับโลกที่ขับเคลื่อนโดย GSMA ซึ่งช่วยให้ การจัดสรรซิมระยะไกล (RSP) ของอุปกรณ์เคลื่อนที่ใดก็ได้ ตั้งแต่ Android 9 เป็นต้นไป เฟรมเวิร์ก Android จะมี API มาตรฐานสำหรับ การเข้าถึง eSIM และการจัดการโปรไฟล์การสมัครใช้บริการใน eSIM API ของ eUICC เหล่านี้ช่วยให้บุคคลที่สามพัฒนาแอปของผู้ให้บริการและผู้ช่วยโปรไฟล์ในเครื่อง (LPA) ของตนเองในอุปกรณ์ Android ที่พร้อมใช้งาน eSIM ได้
LPA เป็นแอปของระบบแบบสแตนด์อโลนที่ควรจะรวมอยู่ใน อิมเมจบิลด์ Android โดยทั่วไป LPA จะเป็นผู้จัดการโปรไฟล์ใน eSIM เนื่องจากทำหน้าที่เป็นตัวกลางระหว่าง SM-DP+ (บริการระยะไกลที่เตรียม จัดเก็บ และส่งแพ็กเกจโปรไฟล์ไปยังอุปกรณ์) กับชิป eUICC APK ของ LPA อาจมีคอมโพเนนต์ UI ที่เรียกว่า LPA UI หรือ LUI เพื่อ เป็นศูนย์กลางให้ผู้ใช้ปลายทางจัดการโปรไฟล์การสมัครใช้บริการที่ฝังไว้ทั้งหมด ได้ เฟรมเวิร์ก Android จะค้นหาและเชื่อมต่อกับ LPA ที่ดีที่สุดที่มีอยู่โดยอัตโนมัติ และกำหนดเส้นทางการดำเนินการ eUICC ทั้งหมดผ่านอินสแตนซ์ LPA
รูปที่ 1 สถาปัตยกรรม RSP ที่เรียบง่าย
ผู้ให้บริการเครือข่ายมือถือที่สนใจสร้างแอปของผู้ให้บริการควรดู API ใน
EuiccManager
ซึ่งมีฟีเจอร์การจัดการโปรไฟล์ระดับสูง เช่น
downloadSubscription()
, switchToSubscription()
และ
deleteSubscription()
หากคุณเป็น OEM อุปกรณ์ที่สนใจสร้างแอปของระบบ LPA ของคุณเอง คุณต้อง
ขยาย
EuiccService
เพื่อให้เฟรมเวิร์ก Android เชื่อมต่อกับบริการ LPA ของคุณได้ นอกจากนี้ คุณควรใช้ API ใน EuiccCardManager
ซึ่งมีฟังก์ชัน ES10x ตาม GSMA RSP v2.0
ฟังก์ชันเหล่านี้ใช้เพื่อออกคำสั่งไปยังชิป eUICC เช่น
prepareDownload()
, loadBoundProfilePackage()
, retrieveNotificationList()
และ resetMemory()
API ใน
EuiccManager
ต้องใช้แอป LPA ที่ติดตั้งอย่างถูกต้องจึงจะทำงานได้ และผู้เรียกใช้ API ของ
EuiccCardManager
ต้องเป็น LPA ซึ่งจะบังคับใช้โดยเฟรมเวิร์กของ Android
อุปกรณ์ที่ใช้ Android 10 ขึ้นไปจะรองรับ อุปกรณ์ที่มี eSIM หลายรายการ ดูข้อมูลเพิ่มเติมได้ที่การรองรับ eSIM หลายรายการ
สร้างแอปของผู้ให้บริการ
API ของ eUICC ใน Android 9 ช่วยให้ผู้ให้บริการเครือข่ายมือถือสร้างแอปที่มีการสร้างแบรนด์ของผู้ให้บริการเพื่อจัดการโปรไฟล์ของตนได้โดยตรง ซึ่งรวมถึงการดาวน์โหลดและลบโปรไฟล์การสมัครใช้บริการ ที่เป็นของผู้ให้บริการ รวมถึงการเปลี่ยนไปใช้โปรไฟล์ที่เป็นของผู้ให้บริการ
EuiccManager
EuiccManager
เป็นจุดแรกที่แอปจะโต้ตอบกับ LPA ซึ่งรวมถึงแอปของผู้ให้บริการที่ดาวน์โหลด ลบ และเปลี่ยนไปใช้
การสมัครใช้บริการที่เป็นของผู้ให้บริการ ซึ่งรวมถึงแอปของระบบ LUI ซึ่ง
มีตำแหน่ง/UI ส่วนกลางสำหรับจัดการการสมัครใช้บริการที่ฝังไว้ทั้งหมด และ
อาจเป็นแอปแยกต่างหากจากแอปที่ให้บริการ EuiccService
หากต้องการใช้ API สาธารณะ แอปของผู้ให้บริการต้องรับอินสแตนซ์ของ
EuiccManager
ผ่าน Context#getSystemService
ก่อน
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
คุณควรตรวจสอบว่าอุปกรณ์รองรับ eSIM หรือไม่ก่อนที่จะดำเนินการใดๆ เกี่ยวกับ eSIM
EuiccManager#isEnabled()
โดยทั่วไปจะแสดงผล true
หากมีการกำหนดฟีเจอร์
android.hardware.telephony.euicc
และมีแพ็กเกจ LPA
อยู่
if (mgr == null || !mgr.isEnabled()) {
return;
}
วิธีดูข้อมูลเกี่ยวกับฮาร์ดแวร์ eUICC และเวอร์ชันระบบปฏิบัติการของ eSIM
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
API หลายรายการ เช่น downloadSubscription()
และ switchToSubscription()
ใช้
PendingIntent
Callback เนื่องจากอาจใช้เวลาหลายวินาทีหรือหลายนาทีในการดำเนินการให้เสร็จสมบูรณ์
PendingIntent
จะส่งพร้อมรหัสผลลัพธ์ในช่อง
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_
ซึ่งมีรหัสข้อผิดพลาดที่กำหนดไว้ในเฟรมเวิร์ก
รวมถึงรหัสผลลัพธ์แบบละเอียดที่กำหนดเอง
ซึ่งส่งต่อจาก LPA เป็น EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
เพื่อให้
แอปของผู้ให้บริการติดตามเพื่อวัตถุประสงค์ในการบันทึก/แก้ไขข้อบกพร่อง PendingIntent
Callback ต้องเป็น BroadcastReceiver
วิธีดาวน์โหลดการสมัครใช้บริการที่ดาวน์โหลดได้ (สร้างจากรหัสเปิดใช้งานหรือคิวอาร์โค้ด)
// Register receiver.
static final String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
static final String LPA_DECLARED_PERMISSION
= "com.your.company.lpa.permission.BROADCAST";
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*/);
// If the result code is a resolvable error, call startResolutionActivity
if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR) {
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.startResolutionActivity(
activity,
0 /* requestCode */,
intent,
callbackIntent);
}
resultIntent = intent;
}
};
context.registerReceiver(receiver,
new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
LPA_DECLARED_PERMISSION /* broadcastPermission*/,
null /* handler */);
// Download subscription asynchronously.
DownloadableSubscription sub = DownloadableSubscription
.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
callbackIntent);
กำหนดและใช้สิทธิ์ใน AndroidManifest.xml
ดังนี้
<permission android:protectionLevel="signature" android:name="com.your.company.lpa.permission.BROADCAST" />
<uses-permission android:name="com.your.company.lpa.permission.BROADCAST"/>
วิธีเปลี่ยนไปใช้การสมัครใช้บริการโดยใช้รหัสการสมัครใช้บริการ
// Register receiver.
static final String ACTION_SWITCH_TO_SUBSCRIPTION = "switch_to_subscription";
static final String LPA_DECLARED_PERMISSION
= "com.your.company.lpa.permission.BROADCAST";
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_SWITCH_TO_SUBSCRIPTION),
LPA_DECLARED_PERMISSION /* broadcastPermission*/,
null /* handler */);
// Switch to a subscription asynchronously.
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);
ดูรายการ EuiccManager
API และตัวอย่างโค้ดทั้งหมดได้ที่
API ของ eUICC
ข้อผิดพลาดที่แก้ไขได้
ในบางกรณี ระบบอาจดำเนินการกับ eSIM ไม่สำเร็จ
แต่ผู้ใช้สามารถแก้ไขข้อผิดพลาดได้ เช่น downloadSubscription
อาจไม่สำเร็จหากข้อมูลเมตาของโปรไฟล์ระบุว่าต้องใช้รหัสยืนยันของผู้ให้บริการ
หรืออาจswitchToSubscription
ล้มเหลวหากแอปของผู้ให้บริการมีสิทธิ์ของผู้ให้บริการ
เหนือโปรไฟล์ปลายทาง (กล่าวคือ ผู้ให้บริการเป็นเจ้าของโปรไฟล์) แต่
ไม่มีสิทธิ์ของผู้ให้บริการเหนือโปรไฟล์ที่เปิดใช้อยู่ในปัจจุบัน และด้วยเหตุนี้จึง
ต้องได้รับความยินยอมจากผู้ใช้
สำหรับกรณีเช่นนี้ ระบบจะเรียกใช้การโทรกลับของผู้โทรด้วย
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
การเรียกกลับ
Intent
มีข้อมูลเพิ่มเติมภายในเพื่อให้เมื่อผู้โทรส่งไปยัง
EuiccManager#startResolutionActivity
จะขอความละเอียดผ่าน LUI ได้ การใช้รหัสยืนยันสำหรับ
ตัวอย่างอีกครั้ง
EuiccManager#startResolutionActivity
จะทริกเกอร์หน้าจอ LUI ที่อนุญาตให้ผู้ใช้ป้อนรหัสยืนยัน
หลังจากป้อนรหัสแล้ว ระบบจะดำเนินการดาวน์โหลดต่อ แนวทางนี้
ช่วยให้แอปของผู้ให้บริการควบคุมได้อย่างเต็มที่ว่าจะแสดง UI เมื่อใด แต่ก็ช่วยให้
LPA/LUI มีวิธีการที่ขยายได้สำหรับการเพิ่มการจัดการใหม่สำหรับปัญหาที่ผู้ใช้กู้คืนได้
ในอนาคตโดยไม่ต้องให้แอปไคลเอ็นต์เปลี่ยนแปลง
Android 9 กำหนดข้อผิดพลาดที่แก้ไขได้เหล่านี้ใน
EuiccService
ซึ่ง LUI ควรจัดการ
/**
* Alert the user that this action will result in an active SIM being
* deactivated. To implement the LUI triggered by the system, you need to define
* this in AndroidManifest.xml.
*/
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
"android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
* Alert the user about a download/switch being done for an app that doesn't
* currently have carrier privileges.
*/
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
"android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
/** Ask the user to resolve all the resolvable errors. */
public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
"android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";
สิทธิ์ของผู้ให้บริการขนส่ง
หากคุณเป็นผู้ให้บริการที่พัฒนาแอปของผู้ให้บริการเองซึ่งเรียกใช้ EuiccManager
เพื่อดาวน์โหลดโปรไฟล์ลงในอุปกรณ์ โปรไฟล์ของคุณควรมีกฎสิทธิ์ของผู้ให้บริการ
ที่สอดคล้องกับแอปของผู้ให้บริการในข้อมูลเมตา เนื่องจากโปรไฟล์การสมัครใช้บริการของผู้ให้บริการรายต่างๆ สามารถอยู่ร่วมกันใน eUICC ของอุปกรณ์ได้ และควรอนุญาตให้แอปของผู้ให้บริการแต่ละรายเข้าถึงได้เฉพาะโปรไฟล์ที่เป็นของผู้ให้บริการรายนั้น เช่น ผู้ให้บริการ ก ไม่ควรดาวน์โหลด เปิดใช้ หรือปิดใช้โปรไฟล์ที่เป็นของผู้ให้บริการ ข ได้
Android ใช้กลไกในการ
ให้สิทธิ์พิเศษแก่แอปของเจ้าของโปรไฟล์ (เช่น แอปของผู้ให้บริการ) เพื่อให้มั่นใจว่าเจ้าของโปรไฟล์เท่านั้นที่จะเข้าถึงโปรไฟล์ได้
แพลตฟอร์ม Android จะโหลดใบรับรองที่จัดเก็บไว้ในไฟล์กฎการเข้าถึง (ARF) ของโปรไฟล์
และให้สิทธิ์แก่แอปที่ลงนามด้วยใบรับรองเหล่านี้ในการเรียก
EuiccManager
API กระบวนการในภาพรวมมีดังนี้
- ผู้ให้บริการลงนามใน APK ของแอปผู้ให้บริการขนส่ง และเครื่องมือ apksigner จะแนบใบรับรองคีย์สาธารณะกับ APK
ผู้ให้บริการ/SM-DP+ จะเตรียมโปรไฟล์และข้อมูลเมตา ซึ่งรวมถึง ARF ที่มีข้อมูลต่อไปนี้
- ลายเซ็น (SHA-1 หรือ SHA-256) ของใบรับรองคีย์สาธารณะของแอปผู้ให้บริการ (ต้องระบุ)
- ชื่อแพ็กเกจของแอปผู้ให้บริการ (แนะนำอย่างยิ่ง)
แอปของผู้ให้บริการพยายามดำเนินการ eUICC ด้วย
EuiccManager
APIแพลตฟอร์ม Android จะยืนยันว่าแฮช SHA-1 หรือ SHA-256 ของ ใบรับรองของแอปที่เรียกตรงกับลายเซ็นของใบรับรองที่ได้จาก ARF ของ โปรไฟล์เป้าหมาย หากชื่อแพ็กเกจของแอปผู้ให้บริการรวมอยู่ใน ARF ชื่อแพ็กเกจของแอปผู้ให้บริการต้องตรงกับชื่อแพ็กเกจของแอปผู้โทรด้วย
หลังจากยืนยันลายเซ็นและชื่อแพ็กเกจ (หากมี) แล้ว ระบบจะให้สิทธิ์ของผู้ให้บริการแก่แอปที่เรียกใช้ในโปรไฟล์เป้าหมาย
เนื่องจากข้อมูลเมตาของโปรไฟล์อาจอยู่นอกโปรไฟล์เอง (เพื่อให้ LPA ดึงข้อมูลเมตาของโปรไฟล์จาก SM-DP+ ได้ก่อนที่จะดาวน์โหลดโปรไฟล์ หรือจาก ISD-R เมื่อโปรไฟล์ถูกปิดใช้) ข้อมูลเมตาจึงควรกำหนดกฎสิทธิ์ของผู้ให้บริการรายเดียวกันกับในโปรไฟล์
ระบบปฏิบัติการ eUICC และ SM-DP+ ต้องรองรับแท็กที่เป็นกรรมสิทธิ์ BF76
ในข้อมูลเมตาของโปรไฟล์
เนื้อหาของแท็กควรเป็นกฎสิทธิ์ของผู้ให้บริการขนส่งเดียวกันกับที่แอปเพล็ตกฎการเข้าถึง (ARA) ส่งคืน
ซึ่งกำหนดไว้ใน
สิทธิ์ของผู้ให้บริการขนส่งใน UICC
RefArDo ::= [PRIVATE 2] SEQUENCE { -- Tag E2
refDo [PRIVATE 1] SEQUENCE { -- Tag E1
deviceAppIdRefDo [PRIVATE 1] OCTET STRING (SIZE(20|32)), -- Tag C1
pkgRefDo [PRIVATE 10] OCTET STRING (SIZE(0..127)) OPTIONAL -- Tag CA
},
arDo [PRIVATE 3] SEQUENCE { -- Tag E3
permArDo [PRIVATE 27] OCTET STRING (SIZE(8)) -- Tag DB
}
}
ดูรายละเอียดเพิ่มเติมเกี่ยวกับการลงนามแอปได้ที่ลงนามแอป ดูรายละเอียดเกี่ยวกับสิทธิ์ของผู้ให้บริการได้ที่ สิทธิ์ของผู้ให้บริการ UICC
สร้างแอปผู้ช่วยโปรไฟล์ในพื้นที่
ผู้ผลิตอุปกรณ์สามารถใช้ Local Profile Assistant (LPA) ของตนเองได้ ซึ่งต้องเชื่อมต่อ กับ Android Euicc API ส่วนต่อไปนี้จะอธิบายภาพรวมคร่าวๆ เกี่ยวกับ การสร้างแอป LPA และการผสานรวมกับระบบ Android
ข้อกำหนดเกี่ยวกับฮาร์ดแวร์/โมเด็ม
LPA และระบบปฏิบัติการ eSIM ในชิป eUICC ต้องรองรับ GSMA RSP (การจัดสรรซิมระยะไกล) v2.0 หรือ v2.2 เป็นอย่างน้อย นอกจากนี้ คุณควรวางแผนที่จะใช้เซิร์ฟเวอร์ SM-DP+ และ SM-DS ที่มี RSP เวอร์ชันที่ตรงกันด้วย ดูสถาปัตยกรรม RSP โดยละเอียดได้ที่ ข้อกำหนดสถาปัตยกรรม RSP ของ GSMA SGP.21
นอกจากนี้ หากต้องการผสานรวมกับ eUICC API ใน Android 9 โมเด็มของอุปกรณ์ควรส่งความสามารถของเทอร์มินัลพร้อมการรองรับความสามารถของ eUICC ที่เข้ารหัส (การจัดการโปรไฟล์ในเครื่องและการดาวน์โหลดโปรไฟล์) นอกจากนี้ ยังต้องติดตั้งใช้งานเมธอดต่อไปนี้ด้วย
- iRadio HAL v1.1:
setSimPower
IRadio HAL v1.2:
getIccCardStatus
IRadioConfig HAL v1.0:
getSimSlotsStatus
IRadioConfig AIDL v1.0:
getAllowedCarriers
LPA ของ Google ต้องทราบสถานะการล็อกของผู้ให้บริการเพื่อให้สามารถอนุญาตการดาวน์โหลดหรือโอน eSIM สำหรับผู้ให้บริการที่อนุญาตเท่านั้น ไม่เช่นนั้น ผู้ใช้อาจดาวน์โหลดและโอนซิม แล้วจึงทราบในภายหลังว่าอุปกรณ์ล็อกกับผู้ให้บริการรายอื่น
ผู้ให้บริการหรือ OEM ต้องใช้ IRadioSim.getAllowedCarriers() HAL API
RIL / โมเด็มของผู้ให้บริการจะต้องระบุสถานะการล็อกและ carrierId ของผู้ให้บริการที่ล็อกอุปกรณ์ไว้เป็นส่วนหนึ่งของ IRadioSimResponse.getAllowedCarriersResponse()HAL API
โมเด็มควรรู้จัก eSIM ที่เปิดใช้โปรไฟล์การเปิดเครื่องเริ่มต้นเป็น ซิมที่ถูกต้องและเปิดเครื่องซิมไว้
สำหรับอุปกรณ์ที่ใช้ Android 10 ต้องกำหนดอาร์เรย์รหัสช่อง eUICC ที่ถอดออกไม่ได้ เช่น ดูarrays.xml
<resources>
<!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
eUICC, then the value of this array should be:
<integer-array name="non_removable_euicc_slots">
<item>1</item>
</integer-array>
If a device has three physical slots and slot 1 and 2 are eUICCs, then the value of
this array should be:
<integer-array name="non_removable_euicc_slots">
<item>1</item>
<item>2</item>
</integer-array>
This is used to differentiate between removable eUICCs and built in eUICCs, and should
be set by OEMs for devices which use eUICCs. -->
<integer-array name="non_removable_euicc_slots">
<item>1</item>
</integer-array>
</resources>
ดูรายการข้อกำหนดของโมเด็มทั้งหมดได้ที่ ข้อกำหนดของโมเด็มสำหรับการรองรับ eSIM
EuiccService
LPA ประกอบด้วยคอมโพเนนต์ 2 อย่างที่แยกจากกัน (อาจติดตั้งทั้ง 2 อย่างใน APK เดียวกันได้) ได้แก่ แบ็กเอนด์ของ LPA และ UI ของ LPA หรือ LUI
หากต้องการใช้แบ็กเอนด์ LPA คุณต้องขยาย
EuiccService
และประกาศบริการนี้ในไฟล์ Manifest บริการต้องกำหนดให้ใช้
android.permission.BIND_EUICC_SERVICE
สิทธิ์ของระบบเพื่อให้มั่นใจว่ามีเพียง
ระบบเท่านั้นที่เชื่อมโยงกับบริการได้ นอกจากนี้ บริการต้องมีตัวกรอง Intent ที่มีการดำเนินการ android.service.euicc.EuiccService
ด้วย ควรตั้งค่าลำดับความสำคัญของ Intent
Filter เป็นค่าที่ไม่ใช่ 0 ในกรณีที่มีการติดตั้งใช้งานหลายรายการ
ในอุปกรณ์ เช่น
<service
android:name=".EuiccServiceImpl"
android:permission="android.permission.BIND_EUICC_SERVICE">
<intent-filter android:priority="100">
<action android:name="android.service.euicc.EuiccService" />
</intent-filter>
</service>
ภายใน เฟรมเวิร์ก Android จะกำหนด LPA ที่ใช้งานอยู่และโต้ตอบกับ
LPA นั้นตามที่จำเป็นเพื่อรองรับ Android eUICC API ระบบจะค้นหา PackageManager
แอปทั้งหมดที่มีสิทธิ์ android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
ซึ่งระบุบริการสำหรับการดำเนินการ android.service.euicc.EuiccService
ระบบจะเลือกบริการที่มีลำดับความสำคัญสูงสุด หากไม่พบบริการ ระบบจะปิดใช้การรองรับ LPA
หากต้องการติดตั้งใช้งาน LUI คุณต้องระบุกิจกรรมสำหรับการดำเนินการต่อไปนี้
android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION
เช่นเดียวกับบริการ กิจกรรมแต่ละอย่างต้องต้องใช้android.permission.BIND_EUICC_SERVICE
สิทธิ์ของระบบ แต่ละรายการควรมี
ตัวกรอง Intent ที่มีการดำเนินการที่เหมาะสม หมวดหมู่ android.service.euicc.category.EUICC_UI
และลำดับความสำคัญที่ไม่ใช่ 0
ระบบจะใช้ตรรกะที่คล้ายกันในการเลือกการติดตั้งใช้งานสำหรับกิจกรรมเหล่านี้เช่นเดียวกับการเลือกการติดตั้งใช้งานของ EuiccService
เช่น
<activity android:name=".MyLuiActivity"
android:exported="true"
android:permission="android.permission.BIND_EUICC_SERVICE">
<intent-filter android:priority="100">
<action android:name="android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
<action android:name="android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.service.euicc.category.EUICC_UI" />
</intent-filter>
</activity>
ซึ่งหมายความว่า UI ที่ใช้หน้าจอเหล่านี้อาจมาจาก APK อื่นที่ไม่ใช่ APK ที่ใช้ EuiccService
การมี APK เดียวหรือหลาย APK (เช่น APK ที่ใช้ EuiccService
และ APK ที่มีกิจกรรม LUI) เป็นตัวเลือกการออกแบบ
EuiccCardManager
EuiccCardManager
เป็นอินเทอร์เฟซสำหรับสื่อสารกับชิป eSIM โดยมีฟังก์ชัน ES10 (ตามที่อธิบายไว้ในข้อกำหนด RSP ของ GSMA) และจัดการคำสั่งคำขอ/การตอบกลับ APDU ระดับต่ำ รวมถึงการแยกวิเคราะห์ ASN.1
EuiccCardManager
เป็น API ของระบบและเรียกใช้ได้เฉพาะแอปที่มีสิทธิ์ระดับระบบเท่านั้น
รูปที่ 2 ทั้งแอปของผู้ให้บริการและ LPA ใช้ Euicc API
API การดำเนินการในโปรไฟล์ผ่าน EuiccCardManager
กำหนดให้ผู้เรียกต้องเป็น LPA ซึ่งจะบังคับใช้โดยเฟรมเวิร์กของ Android ซึ่งหมายความว่าผู้โทรต้อง
ขยาย EuiccService
และประกาศในไฟล์ Manifest ตามที่อธิบายไว้ใน
ส่วนก่อนหน้า
เช่นเดียวกับ EuiccManager
ในการใช้ API ของ EuiccCardManager
LPA ของคุณต้อง
ได้รับอินสแตนซ์ของ EuiccCardManager
ผ่าน
Context#getSystemService
ก่อน
EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);
จากนั้นทำดังนี้เพื่อรับโปรไฟล์ทั้งหมดใน eUICC
ResultCallback<EuiccProfileInfo[]> callback =
new ResultCallback<EuiccProfileInfo[]>() {
@Override
public void onComplete(int resultCode,
EuiccProfileInfo[] result) {
if (resultCode == EuiccCardManagerReflector.RESULT_OK) {
// handle result
} else {
// handle error
}
}
};
cardMgr.requestAllProfiles(eid, AsyncTask.THREAD_POOL_EXECUTOR, callback);
ภายใน EuiccCardManager
จะเชื่อมโยงกับ EuiccCardController
(ซึ่งทำงานในกระบวนการของโทรศัพท์) ผ่านอินเทอร์เฟซ AIDL และเมธอด EuiccCardManager
แต่ละรายการจะได้รับการเรียกกลับจากกระบวนการของโทรศัพท์ผ่านอินเทอร์เฟซ AIDL อื่นที่เฉพาะเจาะจง เมื่อใช้ EuiccCardManager
API ผู้เรียก (LPA) ต้องระบุออบเจ็กต์
Executor
ซึ่งจะเรียกใช้ Callback Executor
ออบเจ็กต์นี้อาจทำงานใน
เธรดเดียวหรือในกลุ่มเธรดที่คุณเลือก
API ของ EuiccCardManager
ส่วนใหญ่มีรูปแบบการใช้งานเหมือนกัน ตัวอย่างเช่น หากต้องการโหลดแพ็กเกจโปรไฟล์ที่
ผูกไว้ลงใน eUICC ให้ทำดังนี้
...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
วิธีเปลี่ยนไปใช้โปรไฟล์อื่นที่มี ICCID ที่ระบุ
...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
วิธีรับที่อยู่ SM-DP+ เริ่มต้นจากชิป eUICC
...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
callback);
หากต้องการดึงข้อมูลรายการการแจ้งเตือนของเหตุการณ์การแจ้งเตือนที่ระบุ ให้ทำดังนี้
...
cardMgr.listNotifications(eid,
EuiccNotification.Event.INSTALL
| EuiccNotification.Event.DELETE /* events */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
เปิดใช้งานโปรไฟล์ eSIM ผ่านแอปของผู้ให้บริการ
ในอุปกรณ์ที่ใช้ Android 9 ขึ้นไป คุณสามารถใช้แอปของผู้ให้บริการเพื่อเปิดใช้งาน
eSIM และดาวน์โหลดโปรไฟล์ได้ แอปของผู้ให้บริการเครือข่ายสามารถดาวน์โหลดโปรไฟล์ได้โดย
เรียกใช้
downloadSubscription
โดยตรงหรือโดยการระบุรหัสเปิดใช้งานให้ LPA
เมื่อแอปของผู้ให้บริการดาวน์โหลดโปรไฟล์โดยการเรียกใช้
downloadSubscription
การเรียกใช้จะบังคับให้แอปจัดการโปรไฟล์ผ่านBF76
แท็กข้อมูลเมตา
ที่เข้ารหัสกฎสิทธิ์ของผู้ให้บริการสำหรับ
โปรไฟล์ หากโปรไฟล์ไม่มีแท็ก BF76
หรือแท็ก BF76
ไม่ตรงกับลายเซ็นของแอปผู้ให้บริการโทร ระบบจะปฏิเสธการดาวน์โหลด
ส่วนด้านล่างจะอธิบายการเปิดใช้งาน eSIM ผ่านแอปของผู้ให้บริการโดยใช้ รหัสเปิดใช้งาน
เปิดใช้งาน eSIM โดยใช้รหัสเปิดใช้งาน
เมื่อใช้รหัสเปิดใช้งานเพื่อเปิดใช้งานโปรไฟล์ eSIM แล้ว LPA จะดึง
รหัสเปิดใช้งานจาก
แอปของผู้ให้บริการและดาวน์โหลดโปรไฟล์ LPA สามารถเริ่มโฟลว์นี้ได้
และควบคุมโฟลว์ UI ทั้งหมดได้ ซึ่งหมายความว่าจะไม่มี UI ของแอปผู้ให้บริการ
แสดง วิธีนี้จะข้ามการตรวจสอบแท็ก BF76
และผู้ให้บริการเครือข่ายไม่จำเป็นต้อง
ติดตั้งใช้งานขั้นตอน UI การเปิดใช้งาน eSIM ทั้งหมด ซึ่งรวมถึงการดาวน์โหลดโปรไฟล์
eSIM และการจัดการข้อผิดพลาด
กำหนดบริการจัดสรร eUICC ของผู้ให้บริการขนส่ง
แอป LPA และแอปของผู้ให้บริการจะสื่อสารกันผ่านอินเทอร์เฟซ AIDL
2 รายการ
ICarrierEuiccProvisioningService
และ IGetActivationCodeCallback
แอปของผู้ให้บริการ
ต้องใช้ICarrierEuiccProvisioningService
อินเทอร์เฟซและ
เปิดเผยในประกาศในไฟล์ Manifest
LPA ต้องเชื่อมโยงกับ ICarrierEuiccProvisioningService
และใช้ IGetActivationCodeCallback
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้งานและ
แสดงอินเทอร์เฟซ AIDL ได้ที่การกำหนดอินเทอร์เฟซ AIDL
หากต้องการกำหนดอินเทอร์เฟซ AIDL ให้สร้างไฟล์ AIDL ต่อไปนี้ สำหรับทั้งแอป LPA และแอปของผู้ให้บริการ
ICarrierEuiccProvisioningService.aidl
package android.service.euicc; import android.service.euicc.IGetActivationCodeCallback; oneway interface ICarrierEuiccProvisioningService { // The method to get the activation code from the carrier app. The caller needs to pass in // the implementation of IGetActivationCodeCallback as the parameter. void getActivationCode(in IGetActivationCodeCallback callback); // The method to get the activation code from the carrier app. The caller needs to pass in // the activation code string as the first parameter and the implementation of // IGetActivationCodeCallback as the second parameter. This method provides the carrier // app the device EID which allows a carrier to pre-bind a profile to the device's EID before // the download process begins. void getActivationCodeForEid(in String eid, in IGetActivationCodeCallback callback); }
IGetActivationCodeCallback.aidl
package android.service.euicc; oneway interface IGetActivationCodeCallback { // The call back method needs to be called when the carrier app gets the activation // code successfully. The caller needs to pass in the activation code string as the // parameter. void onSuccess(String activationCode); // The call back method needs to be called when the carrier app failed to get the // activation code. void onFailure(); }
ตัวอย่างการใช้งาน LPA
หากต้องการเชื่อมโยงกับการติดตั้งใช้งาน ICarrierEuiccProvisioningService
ของแอปผู้ให้บริการ
LPA ต้องคัดลอกทั้ง ICarrierEuiccProvisioningService.aidl
และ
IGetActivationCodeCallback.aidl
ไปยังโปรเจ็กต์ของคุณ แล้วติดตั้งใช้งาน
ServiceConnection
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}
หลังจากเชื่อมโยงกับICarrierEuiccProvisioningService
การติดตั้งใช้งานของแอปของผู้ให้บริการแล้ว LPA จะเรียกใช้ getActivationCode
หรือ
getActivationCodeForEid
เพื่อรับรหัสเปิดใช้งานจากแอปของผู้ให้บริการโดย
ส่งการติดตั้งใช้งานของคลาส Stub IGetActivationCodeCallback
ความแตกต่างระหว่าง getActivationCode
กับ getActivationCodeForEid
คือ getActivationCodeForEid
อนุญาตให้ผู้ให้บริการผูกโปรไฟล์กับ EID ของอุปกรณ์ล่วงหน้าก่อนที่กระบวนการดาวน์โหลดจะเริ่มขึ้น
void getActivationCodeFromCarrierApp() {
IGetActivationCodeCallback.Stub callback =
new IGetActivationCodeCallback.Stub() {
@Override
public void onSuccess(String activationCode) throws RemoteException {
// Handle the case LPA success to get activation code from a carrier app.
}
@Override
public void onFailure() throws RemoteException {
// Handle the case LPA failed to get activation code from a carrier app.
}
};
try {
mCarrierProvisioningService.getActivationCode(callback);
} catch (RemoteException e) {
// Handle Remote Exception
}
}
ตัวอย่างการติดตั้งใช้งานสำหรับแอปของผู้ให้บริการ
หากต้องการให้ LPA ผูกกับแอปของผู้ให้บริการ แอปของผู้ให้บริการต้องคัดลอกทั้ง
ICarrierEuiccProvisioningService.aidl
และ IGetActivationCodeCallback.aidl
ไปยัง
โปรเจ็กต์ของคุณ และประกาศบริการ ICarrierEuiccProvisioningService
ในไฟล์
AndroidManifest.xml
บริการต้องกำหนดให้ใช้
android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
สิทธิ์ของระบบเพื่อให้แน่ใจว่า
มีเพียง LPA ซึ่งเป็นแอปที่มีสิทธิ์ของระบบเท่านั้นที่เชื่อมโยงกับบริการได้ บริการต้องมีตัวกรอง Intent ที่มี
การดำเนินการ android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE
ด้วย
AndroidManifest.xml
<application> ... <service android:name=".CarrierEuiccProvisioningService" android:exported="true" android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"> <intent-filter> <action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/> </intent-filter> </service> ... </application>
หากต้องการใช้บริการแอปของผู้ให้บริการ AIDL ให้สร้างบริการ ขยายคลาส Stub
และใช้เมธอด getActivationCode
และ getActivationCodeForEid
จากนั้น LPA จะเรียกใช้เมธอดใดเมธอดหนึ่งเพื่อดึงรหัสเปิดใช้งานโปรไฟล์
ได้ แอปของผู้ให้บริการควรตอบกลับโดยการเรียกใช้
IGetActivationCodeCallback#onSuccess
พร้อมรหัสเปิดใช้งานหากดึงรหัสจากเซิร์ฟเวอร์ของผู้ให้บริการได้สำเร็จ
หากไม่สำเร็จ แอปของผู้ให้บริการ
ควรตอบกลับด้วย IGetActivationCodeCallback#onFailure
CarrierEuiccProvisioningService.java
import android.service.euicc.ICarrierEuiccProvisioningService; import android.service.euicc.ICarrierEuiccProvisioningService.Stub; import android.service.euicc.IGetActivationCodeCallback; public class CarrierEuiccProvisioningService extends Service { private final ICarrierEuiccProvisioningService.Stub binder = new Stub() { @Override public void getActivationCode(IGetActivationCodeCallback callback) throws RemoteException { String activationCode = // do whatever work necessary to get an activation code (HTTP requests to carrier server, fetch from storage, etc.) callback.onSuccess(activationCode); } @Override public void getActivationCodeForEid(String eid, IGetActivationCodeCallback callback) throws RemoteException { String activationCode = // do whatever work necessary (HTTP requests, fetch from storage, etc.) callback.onSuccess(activationCode); } } }
เริ่ม UI ของแอปผู้ให้บริการในขั้นตอนการเปิดใช้งาน LPA
ในอุปกรณ์ที่ใช้ Android 11 ขึ้นไป LPA จะ เริ่ม UI ของแอปของผู้ให้บริการได้ ซึ่งจะเป็นประโยชน์เนื่องจากแอปของผู้ให้บริการอาจต้องใช้ข้อมูลเพิ่มเติมจากผู้ใช้ก่อนที่จะให้รหัสเปิดใช้งานแก่ LPA ตัวอย่างเช่น ผู้ให้บริการอาจกำหนดให้ผู้ใช้ต้องเข้าสู่ระบบเพื่อเปิดใช้งานหมายเลขโทรศัพท์หรือใช้บริการย้ายหมายเลขอื่นๆ
นี่คือกระบวนการเริ่มต้น UI ของแอปของผู้ให้บริการใน LPA
LPA จะเปิดโฟลว์การเปิดใช้งานของแอปผู้ให้บริการโดยการส่ง Intent
android.service.euicc.action.START_CARRIER_ACTIVATION
ไปยัง แพ็กเกจแอปผู้ให้บริการที่มีการดำเนินการ (ตัวรับแอปของผู้ให้บริการต้อง ได้รับการปกป้องในการประกาศไฟล์ Manifest ด้วยandroid:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
เพื่อ หลีกเลี่ยงการรับ Intent จากแอปที่ไม่ใช่ LPA)String packageName = // The carrier app's package name Intent carrierAppIntent = new Intent(“android.service.euicc.action.START_CARRIER_ACTIVATION”) .setPackage(packageName); ResolveInfo activity = context.getPackageManager().resolveActivity(carrierAppIntent, 0); carrierAppIntent .setClassName(activity.activityInfo.packageName, activity.activityInfo.name); startActivityForResult(carrierAppIntent, requestCode);
แอปของผู้ให้บริการจะทำงานโดยใช้ UI ของตัวเอง เช่น การเข้าสู่ระบบของผู้ใช้หรือการส่งคำขอ HTTP ไปยังแบ็กเอนด์ของผู้ให้บริการ
แอปของผู้ให้บริการจะตอบกลับ LPA โดยการเรียกใช้
setResult(int, Intent)
และfinish()
- หากแอปของผู้ให้บริการตอบกลับด้วย
RESULT_OK
LPA จะดำเนินการตามขั้นตอนการเปิดใช้งานต่อไป หากแอปของผู้ให้บริการพิจารณาว่าผู้ใช้ควรสแกนคิวอาร์โค้ดแทนการอนุญาตให้ LPA ผูกบริการของแอปของผู้ให้บริการ แอปของผู้ให้บริการจะตอบกลับ LPA โดยใช้setResult(int, Intent)
พร้อมRESULT_OK
และอินสแตนซ์Intent
ที่มีส่วนขยายบูลีนandroid.telephony.euicc.extra.USE_QR_SCANNER
ซึ่งตั้งค่าเป็นtrue
จากนั้น LPA จะตรวจสอบส่วนเสริมและเปิดใช้เครื่องสแกน QR แทนการเชื่อมโยง การติดตั้งใช้งานICarrierEuiccProvisioningService
ของแอปผู้ให้บริการ - หากแอปของผู้ให้บริการขัดข้องหรือตอบกลับด้วย
RESULT_CANCELED
(นี่คือรหัสการตอบกลับเริ่มต้น) LPA จะยกเลิกขั้นตอนการเปิดใช้งาน eSIM - หากแอปของผู้ให้บริการตอบกลับด้วยข้อความอื่นที่ไม่ใช่
RESULT_OK
หรือRESULT_CANCELED
LPA จะถือว่าเป็นการเกิดข้อผิดพลาด
ด้วยเหตุผลด้านความปลอดภัย LPA ไม่ควรยอมรับรหัสเปิดใช้งานที่ระบุใน Intent ผลลัพธ์โดยตรง เพื่อให้มั่นใจว่าผู้โทรที่ไม่ใช่ LPA จะไม่ได้รับรหัสเปิดใช้งานจากแอปของผู้ให้บริการ
- หากแอปของผู้ให้บริการตอบกลับด้วย
เปิดตัวขั้นตอนการเปิดใช้งาน LPA ในแอปของผู้ให้บริการ
ตั้งแต่ Android 11 เป็นต้นไป แอปของผู้ให้บริการจะใช้ eUICC API เพื่อเริ่ม LUI สำหรับการเปิดใช้งาน eSIM ได้ วิธีนี้จะแสดง UI ของขั้นตอนการเปิดใช้งาน eSIM ของ LPA เพื่อเปิดใช้งาน โปรไฟล์ eSIM จากนั้น LPA จะส่งการออกอากาศเมื่อการเปิดใช้งานโปรไฟล์ eSIM เสร็จสิ้น
LPA ต้องประกาศกิจกรรมซึ่งรวมถึงตัวกรอง Intent ที่มี
android.service.euicc.action.START_EUICC_ACTIVATION
การดำเนินการ ควรตั้งค่าลำดับความสำคัญ ของตัวกรอง Intent เป็นค่าที่ไม่ใช่ 0 ในกรณีที่มีการใช้งานหลายรายการ ในอุปกรณ์ เช่น<application> ... <activity android:name=".CarrierAppInitActivity" android:exported="true"> <intent-filter android:priority="100"> <action android:name="android.service.euicc.action.START_EUICC_ACTIVATION" /> </intent-filter> </activity> ... </application>
แอปของผู้ให้บริการจะทำงานโดยใช้ UI ของตัวเอง เช่น การเข้าสู่ระบบของผู้ใช้หรือการส่งคำขอ HTTP ไปยังแบ็กเอนด์ของผู้ให้บริการ
ในขั้นตอนนี้ แอปของผู้ให้บริการต้องพร้อมที่จะจัดหารหัสเปิดใช้งาน ผ่านการติดตั้งใช้งาน
ICarrierEuiccProvisioningService
แอปของผู้ให้บริการจะเปิดใช้ LPA โดยการเรียกใช้startActivityForResult(Intent, int)
ด้วยการดำเนินการandroid.telephony.euicc.action.START_EUICC_ACTIVATION
นอกจากนี้ LPA ยังตรวจสอบบูลีนพิเศษandroid.telephony.euicc.extra.USE_QR_SCANNER
ด้วย หากค่าเป็นtrue
LPA จะเปิดตัวสแกนคิวอาร์เพื่อให้ผู้ใช้สแกนคิวอาร์โค้ดโปรไฟล์ในฝั่ง LPA นั้น LPA จะเชื่อมโยงกับการใช้งาน
ICarrierEuiccProvisioningService
ของแอปของผู้ให้บริการเพื่อดึงรหัสเปิดใช้งาน และดาวน์โหลดโปรไฟล์ที่เกี่ยวข้อง LPA จะแสดงองค์ประกอบ UI ที่จำเป็นทั้งหมด ระหว่างการดาวน์โหลด เช่น หน้าจอการโหลดเมื่อขั้นตอนการเปิดใช้งาน LPA เสร็จสมบูรณ์แล้ว LPA จะตอบกลับแอปของผู้ให้บริการด้วยรหัสผลลัพธ์ ซึ่งแอปของผู้ให้บริการจะจัดการใน
onActivityResult(int, int, Intent)
- หาก LPA ดาวน์โหลดโปรไฟล์ eSIM ใหม่ได้สำเร็จ ระบบจะตอบกลับด้วย
RESULT_OK
- หากผู้ใช้ยกเลิกการเปิดใช้งานโปรไฟล์ eSIM ใน LPA ระบบจะตอบกลับด้วย
RESULT_CANCELED
- หาก LPA ตอบกลับด้วยข้อความอื่นที่ไม่ใช่
RESULT_OK
หรือRESULT_CANCELED
แอปของผู้ให้บริการจะถือว่านี่เป็นข้อผิดพลาด
ด้วยเหตุผลด้านความปลอดภัย LPA ไม่ยอมรับรหัสเปิดใช้งาน โดยตรงใน Intent ที่ระบุเพื่อให้มั่นใจว่าผู้โทรที่ไม่ใช่ LPA จะไม่ได้รับ รหัสเปิดใช้งานจากแอปของผู้ให้บริการ
- หาก LPA ดาวน์โหลดโปรไฟล์ eSIM ใหม่ได้สำเร็จ ระบบจะตอบกลับด้วย
รองรับ eSIM หลายรายการ
สำหรับอุปกรณ์ที่ใช้ Android 10 ขึ้นไป คลาส EuiccManager
รองรับอุปกรณ์ที่มี eSIM หลายรายการ
อุปกรณ์ที่มี eSIM เดียวซึ่งอัปเกรดเป็น
Android 10
ไม่จำเป็นต้องแก้ไขการติดตั้งใช้งาน LPA เนื่องจากแพลตฟอร์มจะเชื่อมโยงอินสแตนซ์ EuiccManager
กับ eUICC เริ่มต้นโดยอัตโนมัติ แพลตฟอร์มจะเป็นตัวกำหนด
eUICC เริ่มต้นสำหรับอุปกรณ์ที่มี HAL วิทยุเวอร์ชัน 1.2 ขึ้นไป และ LPA จะเป็นตัวกำหนดสำหรับอุปกรณ์ที่มี HAL วิทยุเวอร์ชันต่ำกว่า
1.2
ข้อกำหนด
หากต้องการรองรับ eSIM หลายซิม อุปกรณ์ต้องมี eUICC มากกว่า 1 รายการ ซึ่งอาจเป็น eUICC ในตัวหรือช่องใส่ซิมจริงที่สามารถใส่ eUICC แบบถอดออกได้
ต้องใช้ Radio HAL เวอร์ชัน 1.2 ขึ้นไปเพื่อรองรับ eSIM หลายรายการ ขอแนะนำให้ใช้ Radio HAL เวอร์ชัน 1.4 และ RadioConfig HAL เวอร์ชัน 1.2
การใช้งาน
หากต้องการรองรับ eSIM หลายรายการ (รวมถึง eUICC ที่ถอดออกได้หรือ SIM ที่ตั้งโปรแกรมได้) LPA ต้องติดตั้งใช้งาน
EuiccService
ซึ่งจะรับรหัสช่องที่สอดคล้องกับรหัสการ์ดที่ผู้โทรระบุ
non_removable_euicc_slots
ทรัพยากรที่ระบุใน
arrays.xml
คืออาร์เรย์ของจำนวนเต็มที่แสดงรหัสช่องของ
eUICC ในตัวของอุปกรณ์ คุณต้องระบุทรัพยากรนี้เพื่อให้แพลตฟอร์มพิจารณาได้ว่า
eUICC ที่แทรกนั้นถอดออกได้หรือไม่
แอปของผู้ให้บริการสำหรับอุปกรณ์ที่มี eSIM หลายรายการ
เมื่อสร้างแอปของผู้ให้บริการสำหรับอุปกรณ์ที่มี eSIM หลายรายการ ให้ใช้วิธี
createForCardId
ใน EuiccManager
เพื่อสร้างออบเจ็กต์ EuiccManager
ที่ปักหมุดไว้กับ
รหัสบัตรที่ระบุ รหัสการ์ดคือค่าจำนวนเต็มที่ระบุ UICC
หรือ eUICC ในอุปกรณ์อย่างไม่ซ้ำกัน
หากต้องการรับรหัสการ์ดสำหรับ eUICC เริ่มต้นของอุปกรณ์ ให้ใช้เมธอด
getCardIdForDefaultEuicc
ใน TelephonyManager
เมธอดนี้จะแสดงผล
UNSUPPORTED_CARD_ID
หากเวอร์ชัน HAL ของวิทยุต่ำกว่า 1.2 และจะแสดงผล
UNINITIALIZED_CARD_ID
หากอุปกรณ์ยังไม่ได้อ่าน eUICC
นอกจากนี้ คุณยังดูรหัสบัตรได้จาก
getUiccCardsInfo
และ getUiccSlotsInfo
(API ของระบบ) ใน TelephonyManager
รวมถึง
getCardId
ใน SubscriptionInfo
เมื่อมีการสร้างอินสแตนซ์ของออบเจ็กต์ EuiccManager
ด้วยรหัสการ์ดที่เฉพาะเจาะจง ระบบจะส่งการดำเนินการทั้งหมดไปยัง eUICC ที่มีรหัสการ์ดนั้น หาก eUICC เข้าถึงไม่ได้ (เช่น เมื่อปิดหรือนำออก) EuiccManager
จะใช้ไม่ได้อีกต่อไป
คุณใช้ตัวอย่างโค้ดต่อไปนี้เพื่อสร้างแอปของผู้ให้บริการขนส่งได้
ตัวอย่างที่ 1: รับการสมัครใช้บริการที่ใช้งานอยู่และสร้างอินสแตนซ์ EuiccManager
// Get the active subscription and instantiate an EuiccManager for the eUICC which holds
// that subscription
SubscriptionManager subMan = (SubscriptionManager)
mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int cardId = subMan.getActiveSubscriptionInfo().getCardId();
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
.createForCardId(cardId);
ตัวอย่างที่ 2: วนซ้ำผ่าน UICC และสร้างอินสแตนซ์ EuiccManager
สำหรับ eUICC ที่ถอดออกได้
// On a device with a built-in eUICC and a removable eUICC, iterate through the UICC cards
// to instantiate an EuiccManager associated with a removable eUICC
TelephonyManager telMan = (TelephonyManager)
mContext.getSystemService(Context.TELEPHONY_SERVICE);
List<UiccCardInfo> infos = telMan.getUiccCardsInfo();
int removableCardId = -1; // valid cardIds are 0 or greater
for (UiccCardInfo info : infos) {
if (info.isRemovable()) {
removableCardId = info.getCardId();
break;
}
}
if (removableCardId != -1) {
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
.createForCardId(removableCardId);
}
การตรวจสอบความถูกต้อง
AOSP ไม่ได้มาพร้อมกับการติดตั้งใช้งาน LPA และคุณไม่จำเป็นต้องมี LPA ใน Android ทุกรุ่น (โทรศัพท์บางรุ่นไม่รองรับ eSIM) ด้วยเหตุนี้ จึงไม่มีกรณีทดสอบ CTS แบบต้นทางถึงปลายทาง อย่างไรก็ตาม กรณีทดสอบพื้นฐาน พร้อมใช้งานใน AOSP เพื่อให้มั่นใจว่า API ของ eUICC ที่เปิดเผย ใช้ได้ในการสร้าง Android
คุณควรตรวจสอบว่าบิลด์ผ่านกรณีทดสอบ CTS ต่อไปนี้ (สำหรับ API สาธารณะ ): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts
ผู้ให้บริการที่ใช้แอปของผู้ให้บริการควรผ่านวงจรการประกันคุณภาพภายในตามปกติเพื่อให้แน่ใจว่าฟีเจอร์ทั้งหมดที่ใช้งานได้ทำงานตามที่คาดไว้ อย่างน้อยที่สุด แอปของผู้ให้บริการควรแสดงโปรไฟล์การสมัครใช้บริการทั้งหมด ที่เป็นของผู้ให้บริการรายเดียวกัน ดาวน์โหลดและติดตั้งโปรไฟล์ เปิดใช้งานบริการ ในโปรไฟล์ สลับระหว่างโปรไฟล์ และลบโปรไฟล์ได้
หากคุณสร้าง LPA ของคุณเอง คุณควรทำการทดสอบที่เข้มงวดมากขึ้น คุณควรทำงานร่วมกับผู้ให้บริการโมเด็ม, ผู้ให้บริการชิป eUICC หรือระบบปฏิบัติการ eSIM, ผู้ให้บริการ SM-DP+ และผู้ให้บริการเครือข่ายเพื่อแก้ไขปัญหาและตรวจสอบความสามารถในการทำงานร่วมกันของ LPA ภายในสถาปัตยกรรม RSP การทดสอบด้วยตนเองจำนวนมากเป็นสิ่งที่หลีกเลี่ยงไม่ได้ คุณควรปฏิบัติตามแผนการทดสอบ RSP ของ GSMA SGP.23 เพื่อให้ครอบคลุมการทดสอบมากที่สุด