เทคโนโลยี SIM แบบฝัง (eSIM หรือ eUICC) ช่วยให้ผู้ใช้อุปกรณ์เคลื่อนที่สามารถดาวน์โหลดโปรไฟล์ผู้ให้บริการและเปิดใช้งานบริการของผู้ให้บริการได้โดยไม่ต้องมีซิมการ์ดจริง เป็นข้อกำหนดระดับโลกที่ขับเคลื่อนโดย GSMA ซึ่งเปิดใช้งานการจัดเตรียม SIM ระยะไกล (RSP) ของอุปกรณ์เคลื่อนที่ใดๆ เริ่มต้นด้วย Android 9 เฟรมเวิร์ก Android มอบ API มาตรฐานสำหรับการเข้าถึง eSIM และจัดการโปรไฟล์การสมัครรับข้อมูลบน eSIM eUICC API เหล่านี้ช่วยให้บุคคลที่สามสามารถพัฒนาแอปของผู้ให้บริการและ Local Profile Assistant (LPA) ของตนเองบนอุปกรณ์ Android ที่รองรับ eSIM
LPA เป็นแอประบบแบบสแตนด์อโลนที่ควรรวมอยู่ในอิมเมจบิลด์ Android โดยทั่วไปการจัดการโปรไฟล์บน eSIM จะดำเนินการโดย LPA เนื่องจากทำหน้าที่เป็นสะพานเชื่อมระหว่าง SM-DP+ (บริการระยะไกลที่จัดเตรียม จัดเก็บ และจัดส่งแพ็คเกจโปรไฟล์ไปยังอุปกรณ์) และชิป eUICC LPA APK สามารถเลือกรวมองค์ประกอบ 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 ที่ใช้งานอย่างเหมาะสมจึงจะทำงานได้ และผู้เรียก EuiccCardManager
API ต้องเป็น LPA สิ่งนี้บังคับใช้โดยกรอบงาน Android
อุปกรณ์ที่ใช้ Android 10 ขึ้นไปสามารถรองรับอุปกรณ์ที่มี eSIM หลายอันได้ สำหรับข้อมูลเพิ่มเติม โปรดดู การรองรับ eSIM หลายอัน
การสร้างแอปผู้ให้บริการ
eUICC APIs ใน Android 9 ช่วยให้ผู้ให้บริการเครือข่ายมือถือสามารถสร้างแอปที่มีตราสินค้าของผู้ให้บริการเพื่อจัดการโปรไฟล์ของตนได้โดยตรง ซึ่งรวมถึงการดาวน์โหลดและการลบโปรไฟล์การสมัครสมาชิกของผู้ให้บริการ รวมถึงการสลับไปใช้โปรไฟล์ของผู้ให้บริการ
Euicผู้จัดการ
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 OS:
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
API จำนวนมาก เช่น downloadSubscription()
และ switchToSubscription()
ใช้การเรียกกลับ PendingIntent
เนื่องจากอาจใช้เวลาไม่กี่วินาทีหรือหลายนาทีจึงจะเสร็จสมบูรณ์ PendingIntent
จะถูกส่งไปพร้อมกับโค้ดผลลัพธ์ในพื้นที่ EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_
ซึ่งจัดเตรียมโค้ดข้อผิดพลาดที่เฟรมเวิร์กกำหนด เช่นเดียวกับโค้ดผลลัพธ์โดยละเอียดตามอำเภอใจที่เผยแพร่จาก LPA เป็น EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
ช่วยให้แอปผู้ให้บริการสามารถติดตามเพื่อวัตถุประสงค์ในการบันทึก/แก้ไขจุดบกพร่อง การเรียกกลับ PendingIntent
จะต้องเป็น BroadcastReceiver
หากต้องการดาวน์โหลดการสมัครสมาชิกที่ดาวน์โหลดได้ (สร้างจาก รหัสเปิดใช้งาน หรือรหัส QR):
// 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 และตัวอย่างโค้ดทั้งหมด โปรดดูที่ eUICC API
ข้อผิดพลาดที่แก้ไขได้
มีบางกรณีที่ระบบไม่สามารถดำเนินการ 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 ของอุปกรณ์ได้ และแอปของผู้ให้บริการแต่ละรายควรได้รับอนุญาตให้เข้าถึงเฉพาะโปรไฟล์ของผู้ให้บริการรายนั้นเท่านั้น ตัวอย่างเช่น ผู้ให้บริการ A ไม่ควรสามารถดาวน์โหลด เปิดใช้งาน หรือปิดใช้งานโปรไฟล์ที่เป็นของผู้ให้บริการ B
เพื่อให้แน่ใจว่ามีเพียงเจ้าของเท่านั้นที่สามารถเข้าถึงโปรไฟล์ได้ 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 OS และ SM-DP+ ต้องรองรับแท็กที่เป็นกรรมสิทธิ์ BF76
ในข้อมูลเมตาของโปรไฟล์ เนื้อหาแท็กควรเป็นกฎสิทธิ์ของผู้ให้บริการเดียวกันกับที่ส่งคืนโดยแอปเพล็ตกฎการเข้าถึง (ARA) ที่กำหนดใน UICC Carrier Privileges :
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 OS บนชิป eUICC ต้องรองรับอย่างน้อย GSMA RSP (Remote SIM Provisioning) 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
Google LPA จำเป็นต้องทราบสถานะการล็อกของผู้ให้บริการเพื่อให้สามารถอนุญาตให้ดาวน์โหลดหรือโอน eSIM สำหรับผู้ให้บริการที่ได้รับอนุญาตเท่านั้น มิฉะนั้นผู้ใช้อาจดาวน์โหลดและถ่ายโอน SIM และทราบในภายหลังว่าอุปกรณ์นั้นถูกล็อคโดยผู้ให้บริการรายอื่น
ผู้จำหน่ายหรือ OEM ต้องใช้ IRadioSim.getAllowedCarriers()HAL API
ผู้ขาย RIL / โมเด็มจะต้องเติมสถานะการล็อคและรหัสผู้ให้บริการของผู้ให้บริการที่อุปกรณ์ถูกล็อคโดยเป็นส่วนหนึ่งของ IRadioSimResponse.getAllowedCarriersResponse()HAL API
โมเด็มควรจดจำ eSIM โดยเปิดใช้งานโปรไฟล์การบูตเริ่มต้นเป็นซิมที่ถูกต้อง และเปิดซิมไว้
สำหรับอุปกรณ์ที่ใช้ Android 10 จะต้องกำหนดอาร์เรย์ ID สล็อต 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
ยูอิคเซอร์วิส
LPA ประกอบด้วยองค์ประกอบ 2 ส่วนแยกกัน (อาจใช้งานทั้งคู่ใน APK เดียวกัน): แบ็กเอนด์ LPA และ LPA UI หรือ LUI
หากต้องการใช้แบ็กเอนด์ LPA คุณต้องขยาย EuiccService
และประกาศบริการนี้ในไฟล์ Manifest ของคุณ บริการจะต้องได้รับอนุญาตจากระบบ android.permission.BIND_EUICC_SERVICE
เพื่อให้แน่ใจว่ามีเพียงระบบเท่านั้นที่สามารถเชื่อมโยงได้ บริการนี้ยังต้องมีตัวกรองเจตนาพร้อมกับการดำเนินการ android.service.euicc.EuiccService
ลำดับความสำคัญของตัวกรอง Intent ควรตั้งค่าเป็นค่าที่ไม่ใช่ศูนย์ ในกรณีที่มีการใช้งานหลายอย่างบนอุปกรณ์ ตัวอย่างเช่น:
<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 ที่ใช้งานอยู่และโต้ตอบกับเฟรมเวิร์กดังกล่าวตามความจำเป็นเพื่อรองรับ 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
และลำดับความสำคัญที่ไม่เป็นศูนย์ ตรรกะที่คล้ายกันใช้ในการเลือกการใช้งานสำหรับกิจกรรมเหล่านี้ เช่นเดียวกับการเลือกการใช้งาน 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 (เช่น หนึ่งที่ใช้ EuiccService
และอีกหนึ่งที่มีกิจกรรม LUI) ก็เป็นทางเลือกในการออกแบบ
EuicCardManager
EuiccCardManager
เป็นอินเทอร์เฟซสำหรับการสื่อสารกับชิป eSIM โดยมีฟังก์ชัน ES10 (ตามที่อธิบายไว้ในข้อกำหนด GSMA RSP) และจัดการคำสั่งคำขอ/ตอบกลับ APDU ระดับต่ำ ตลอดจนการแยกวิเคราะห์ ASN.1 EuiccCardManager
เป็น API ของระบบและสามารถเรียกได้โดยแอปที่มีสิทธิ์ของระบบเท่านั้น
รูปที่ 2 ทั้งแอปผู้ให้บริการและ LPA ใช้ Euicc API
API การดำเนินการโปรไฟล์ผ่าน EuiccCardManager
กำหนดให้ผู้เรียกเป็น LPA สิ่งนี้บังคับใช้โดยกรอบงาน Android ซึ่งหมายความว่าผู้เรียกจะต้องขยาย EuiccService
และได้รับการประกาศในไฟล์ Manifest ของคุณ ตามที่อธิบายไว้ในส่วนก่อนหน้า
เช่นเดียวกับ EuiccManager
หากต้องการใช้ EuiccCardManager
API นั้น 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
เพื่อใช้เรียกกลับ ออบเจ็กต์ Executor
นี้อาจทำงานบนเธรดเดียวหรือบนพูลเธรดที่คุณเลือก
EuiccCardManager
API ส่วนใหญ่มีรูปแบบการใช้งานเหมือนกัน ตัวอย่างเช่น หากต้องการโหลดแพ็คเกจโปรไฟล์ที่ถูกผูกไว้บน 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 สามารถริเริ่มโฟลว์นี้ได้ และ LPA สามารถควบคุมโฟลว์ UI ทั้งหมดได้ ซึ่งหมายความว่าจะไม่มีการแสดง UI ของแอปผู้ให้บริการ วิธีการนี้จะข้ามการตรวจสอบแท็ก BF76
และผู้ให้บริการเครือข่ายไม่จำเป็นต้องใช้โฟลว์การเปิดใช้งาน eSIM UI ทั้งหมด รวมถึงการดาวน์โหลดโปรไฟล์ eSIM และการจัดการข้อผิดพลาด
การกำหนดบริการจัดเตรียม eUICC ของผู้ให้บริการ
แอป LPA และผู้ให้บริการสื่อสารผ่านอินเทอร์เฟซ AIDL สองอินเทอร์เฟซ: ICarrierEuiccProvisioningService
และ IGetActivationCodeCallback
แอปผู้ให้บริการต้องใช้อินเทอร์เฟซ ICarrierEuiccProvisioningService
และเปิดเผยใน การประกาศรายการ 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 ซึ่งเป็นแอปที่มีสิทธิ์ของระบบเท่านั้นที่สามารถผูกเข้ากับบริการได้ บริการยังต้องมีตัวกรองเจตนาพร้อมกับการดำเนินการ 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
ไปยังแพ็คเกจแอปของผู้ให้บริการที่มีการดำเนินการ (ตัวรับแอปของผู้ให้บริการจะต้องได้รับการปกป้องในการประกาศรายการด้วย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 จะดำเนินขั้นตอนการเปิดใช้งานต่อไป หากแอปของผู้ให้บริการกำหนดว่าผู้ใช้ควรสแกนโค้ด QR แทนที่จะปล่อยให้ LPA ผูกบริการของแอปของผู้ให้บริการ แอปของผู้ให้บริการจะตอบสนองต่อ LPA โดยใช้setResult(int, Intent)
พร้อมด้วยRESULT_OK
และอินสแตนซ์Intent
ที่มีandroid.telephony.euicc.extra.USE_QR_SCANNER
พิเศษบูลีนandroid.telephony.euicc.extra.USE_QR_SCANNER
ตั้งค่าเป็นtrue
จากนั้น LPA จะตรวจสอบส่วนพิเศษและเปิดใช้เครื่องสแกน QR แทนการเชื่อมโยงการใช้งานICarrierEuiccProvisioningService
ของแอปผู้ให้บริการ - หากแอปของผู้ให้บริการขัดข้องหรือตอบสนองด้วย
RESULT_CANCELED
(นี่คือรหัสตอบกลับเริ่มต้น) LPA จะยกเลิกขั้นตอนการเปิดใช้งาน eSIM - หากแอปของผู้ให้บริการตอบสนองด้วยสิ่งอื่นที่ไม่ใช่
RESULT_OK
หรือRESULT_CANCELED
LPA จะถือว่าเป็นข้อผิดพลาด
ด้วยเหตุผลด้านความปลอดภัย LPA ไม่ควร ยอมรับรหัสเปิดใช้งานที่ให้มาในผลลัพธ์โดยตรง เพื่อให้แน่ใจว่าผู้โทรที่ไม่ใช่ LPA จะไม่สามารถรับรหัสเปิดใช้งานจากแอปของผู้ให้บริการได้
- หากแอปของผู้ให้บริการตอบสนองด้วย
การเปิดใช้งานขั้นตอนการเปิดใช้งาน LPA ในแอปผู้ให้บริการ
ตั้งแต่ Android 11 เป็นต้นไป แอปของผู้ให้บริการจะใช้ eUICC API เพื่อเริ่ม LUI สำหรับการเปิดใช้งาน eSIM ได้ วิธีการนี้จะแสดง UI ขั้นตอนการเปิดใช้งาน eSIM ของ LPA เพื่อเปิดใช้งานโปรไฟล์ eSIM จากนั้น LPA จะส่งการถ่ายทอดเมื่อการเปิดใช้งานโปรไฟล์ eSIM เสร็จสิ้น
LPA ต้องประกาศกิจกรรมรวมถึงตัวกรองเจตนาด้วยการดำเนินการ
android.service.euicc.action.START_EUICC_ACTIVATION
ลำดับความสำคัญของตัวกรอง Intent ควรตั้งค่าเป็นค่าที่ไม่ใช่ศูนย์ ในกรณีที่มีการใช้งานหลายอย่างบนอุปกรณ์ ตัวอย่างเช่น:<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 จะเปิดเครื่องสแกน QR เพื่อให้ผู้ใช้สแกนโค้ด QR ของโปรไฟล์ในด้าน LPA นั้น LPA จะเชื่อมโยงกับการใช้งาน
ICarrierEuiccProvisioningService
ของแอปผู้ให้บริการเพื่อดึงรหัสเปิดใช้งานและดาวน์โหลดโปรไฟล์ที่เกี่ยวข้อง LPA จะแสดงองค์ประกอบ UI ที่จำเป็นทั้งหมดในระหว่างการดาวน์โหลด เช่น หน้าจอการโหลดเมื่อขั้นตอนการเปิดใช้งาน LPA เสร็จสมบูรณ์ LPA จะตอบสนองต่อแอปผู้ให้บริการด้วยโค้ดผลลัพธ์ ซึ่งแอปผู้ให้บริการจัดการใน
onActivityResult(int, int, Intent)
- หาก LPA ดาวน์โหลดโปรไฟล์ eSIM ใหม่ได้สำเร็จ LPA จะตอบกลับด้วย
RESULT_OK
- หากผู้ใช้ยกเลิกการเปิดใช้งานโปรไฟล์ eSIM ใน LPA ผู้ใช้จะตอบกลับด้วย
RESULT_CANCELED
- หาก LPA ตอบสนองด้วยสิ่งอื่นที่ไม่ใช่
RESULT_OK
หรือRESULT_CANCELED
แอปของผู้ให้บริการจะถือว่าสิ่งนี้เป็นข้อผิดพลาด
ด้วยเหตุผลด้านความปลอดภัย LPA จะไม่ ยอมรับรหัสเปิดใช้งานโดยตรงในเจตนาที่ให้มา เพื่อให้แน่ใจว่าผู้โทรที่ไม่ใช่ LPA จะไม่สามารถรับรหัสเปิดใช้งานจากแอปของผู้ให้บริการได้
- หาก LPA ดาวน์โหลดโปรไฟล์ eSIM ใหม่ได้สำเร็จ LPA จะตอบกลับด้วย
รองรับ eSIM หลายอัน
สำหรับอุปกรณ์ที่ใช้ Android 10 หรือสูงกว่า คลาส EuiccManager
รองรับอุปกรณ์ที่มี eSIM หลายอัน อุปกรณ์ที่มี eSIM เดียวที่กำลังอัปเกรดเป็น Android 10 ไม่จำเป็นต้องแก้ไขใดๆ ในการใช้งาน LPA เนื่องจากแพลตฟอร์มจะเชื่อมโยงอินสแตนซ์ EuiccManager
กับ eUICC เริ่มต้นโดยอัตโนมัติ eUICC เริ่มต้นถูกกำหนดโดยแพลตฟอร์มสำหรับอุปกรณ์ที่มีวิทยุ HAL เวอร์ชัน 1.2 หรือสูงกว่า และโดย LPA สำหรับอุปกรณ์ที่มีวิทยุ HAL เวอร์ชันต่ำกว่า 1.2
ความต้องการ
หากต้องการรองรับ eSIM หลายอัน อุปกรณ์จะต้องมี eUICC มากกว่าหนึ่งอัน ซึ่งอาจเป็น eUICC ในตัวหรือช่องใส่ซิมจริงที่สามารถใส่ eUICC แบบถอดได้
ต้องใช้ Radio HAL เวอร์ชัน 1.2 ขึ้นไปเพื่อรองรับ eSIM หลายอัน แนะนำให้ใช้ Radio HAL เวอร์ชัน 1.4 และ RadioConfig HAL เวอร์ชัน 1.2
การนำไปปฏิบัติ
หากต้องการรองรับ eSIM หลายอัน (รวมถึง eUICC แบบถอดได้หรือ SIM แบบตั้งโปรแกรมได้) LPA ต้องใช้ EuiccService
ซึ่งจะได้รับ ID สล็อตที่สอดคล้องกับ ID การ์ดที่ผู้โทรให้มา
ทรัพยากร non_removable_euicc_slots
ที่ระบุใน arrays.xml
คืออาร์เรย์ของจำนวนเต็มที่แสดง ID สล็อตของ eUICC ในตัวของอุปกรณ์ คุณต้องระบุทรัพยากรนี้เพื่ออนุญาตให้แพลตฟอร์มพิจารณาว่า eUICC ที่แทรกไว้นั้นสามารถถอดออกได้หรือไม่
แอพผู้ให้บริการสำหรับอุปกรณ์ที่มี eSIM หลายอัน
เมื่อสร้างแอพผู้ให้บริการสำหรับอุปกรณ์ที่มี eSIM หลายอัน ให้ใช้เมธอด createForCardId
ใน EuiccManager
เพื่อสร้างออบเจ็กต์ EuiccManager
ที่ปักหมุดไว้กับ ID การ์ดที่กำหนด รหัสการ์ดเป็นค่าจำนวนเต็มที่ระบุ UICC หรือ eUICC บนอุปกรณ์โดยไม่ซ้ำกัน
หากต้องการรับ ID การ์ดสำหรับ eUICC เริ่มต้นของอุปกรณ์ ให้ใช้เมธอด getCardIdForDefaultEuicc
ใน TelephonyManager
เมธอดนี้จะส่งคืน UNSUPPORTED_CARD_ID
หากเวอร์ชันวิทยุ HAL ต่ำกว่า 1.2 และส่งคืน UNINITIALIZED_CARD_ID
หากอุปกรณ์ไม่ได้อ่าน eUICC
คุณยังสามารถรับ ID การ์ดจาก getUiccCardsInfo
และ getUiccSlotsInfo
(system API) ใน TelephonyManager
และ getCardId
ใน SubscriptionInfo
เมื่อออบเจ็กต์ EuiccManager
ได้รับการสร้างอินสแตนซ์ด้วย ID การ์ดเฉพาะ การดำเนินการทั้งหมดจะถูกส่งไปยัง eUICC ด้วย ID การ์ดนั้น หาก 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 แบบ end-to-end อย่างไรก็ตาม กรณีทดสอบพื้นฐานจะพร้อมใช้งานใน AOSP เพื่อให้แน่ใจว่า eUICC API ที่เปิดเผยนั้นใช้ได้ใน Android บิลด์
คุณควรตรวจสอบให้แน่ใจว่าบิลด์ผ่านกรณีทดสอบ CTS ต่อไปนี้ (สำหรับ API สาธารณะ): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts
ผู้ให้บริการที่ใช้แอปของผู้ให้บริการควรผ่านวงจรการประกันคุณภาพภายในองค์กรตามปกติ เพื่อให้แน่ใจว่าฟีเจอร์ที่นำไปใช้ทั้งหมดทำงานได้ตามที่คาดหวัง อย่างน้อยที่สุด แอพของผู้ให้บริการควรจะสามารถแสดงรายการโปรไฟล์การสมัครสมาชิกทั้งหมดที่เป็นของผู้ให้บริการรายเดียวกัน ดาวน์โหลดและติดตั้งโปรไฟล์ เปิดใช้งานบริการบนโปรไฟล์ สลับระหว่างโปรไฟล์ และลบโปรไฟล์
หากคุณกำลังสร้าง LPA ของคุณเอง คุณควรผ่านการทดสอบที่เข้มงวดกว่านี้มาก คุณควรทำงานร่วมกับผู้จำหน่ายโมเด็ม, ชิป eUICC หรือผู้จำหน่าย eSIM OS, ผู้จำหน่าย SM-DP+ และผู้ให้บริการ เพื่อแก้ไขปัญหาและรับรองการทำงานร่วมกันของ LPA ของคุณภายในสถาปัตยกรรม RSP การทดสอบด้วยตนเองในปริมาณมากเป็นสิ่งที่หลีกเลี่ยงไม่ได้ เพื่อความครอบคลุมการทดสอบที่ดีที่สุด คุณควรปฏิบัติตาม แผนการทดสอบ GSMA SGP.23 RSP