เทคโนโลยีซิมแบบฝัง (eSIM หรือ eUICC) ช่วยให้ผู้ใช้อุปกรณ์เคลื่อนที่ ดาวน์โหลดโปรไฟล์ของผู้ให้บริการและเปิดใช้บริการของผู้ให้บริการได้โดยไม่ต้องใช้ซิมการ์ดจริง ซึ่งเป็นข้อกำหนดระดับโลกที่ GSMA เป็นผู้กำหนด ซึ่งช่วยให้สามารถจัดสรรซิมจากระยะไกล (RSP) ของอุปกรณ์เคลื่อนที่ทุกรุ่น สำหรับ Android 9 เป็นต้นไป เฟรมเวิร์ก Android มี API มาตรฐานสำหรับการเข้าถึง eSIM และจัดการโปรไฟล์การสมัครใช้บริการใน eSIM eUICC API เหล่านี้ช่วยให้บุคคลที่สามพัฒนาแอปของผู้ให้บริการและผู้ช่วยโปรไฟล์ในเครื่อง (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 ที่ติดตั้งใช้งานอย่างถูกต้องจึงจะทํางานได้ และผู้ที่เรียกใช้
EuiccCardManager
API ต้องเป็น LPA เฟรมเวิร์ก Android จะบังคับใช้การดำเนินการนี้
อุปกรณ์ที่ใช้ Android 10 ขึ้นไปจะรองรับอุปกรณ์ที่มี eSIM หลายรายการ ดูข้อมูลเพิ่มเติมได้ที่การรองรับ eSIM หลายรายการ
สร้างแอปของผู้ให้บริการ
eUICC API ใน 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()
ใช้ Callback ของ PendingIntent
เนื่องจากอาจใช้เวลาหลายวินาทีหรือหลายนาทีจึงจะเสร็จสมบูรณ์
PendingIntent
จะส่งพร้อมกับรหัสผลลัพธ์ในพื้นที่ EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_
ซึ่งจะให้รหัสข้อผิดพลาดที่เฟรมเวิร์กกำหนด รวมถึงรหัสผลลัพธ์แบบละเอียดที่กำหนดเองซึ่งส่งต่อจาก LPA เป็น EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
ซึ่งช่วยให้แอปของผู้ให้บริการติดตามเพื่อวัตถุประสงค์ในการบันทึก/แก้ไขข้อบกพร่องได้ PendingIntent
การเรียกกลับต้องเป็น 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 และตัวอย่างโค้ดทั้งหมดได้ที่ eUICC API
ข้อผิดพลาดที่แก้ไขได้
ในบางกรณี ระบบไม่สามารถดำเนินการกับ eSIM ให้เสร็จสมบูรณ์ได้ แต่ผู้ใช้สามารถแก้ไขข้อผิดพลาดได้ ตัวอย่างเช่น downloadSubscription
อาจล้มเหลวหากข้อมูลเมตาของโปรไฟล์ระบุว่าจำเป็นต้องใช้รหัสยืนยันของผู้ให้บริการ หรือ switchToSubscription
อาจดำเนินการไม่สำเร็จหากแอปของผู้ให้บริการมีสิทธิ์ระดับผู้ให้บริการในโปรไฟล์ปลายทาง (กล่าวคือ ผู้ให้บริการเป็นเจ้าของโปรไฟล์) แต่ไม่มีสิทธิ์ระดับผู้ให้บริการในโปรไฟล์ที่เปิดใช้อยู่ในปัจจุบัน จึงต้องได้รับความยินยอมจากผู้ใช้
ในกรณีเหล่านี้ ระบบจะเรียกใช้การติดต่อกลับของผู้โทรด้วย EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
Callback
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
สร้างแอปผู้ช่วยโปรไฟล์ในเครื่อง
ผู้ผลิตอุปกรณ์สามารถใช้ผู้ช่วยโปรไฟล์ในเครื่อง (LPA) ของตนเองได้ ซึ่งต้องเชื่อมต่อกับ Android Euicc API ส่วนต่อไปนี้แสดงภาพรวมคร่าวๆ ของการสร้างแอป LPA และการผสานรวมกับระบบ Android
ข้อกำหนดเกี่ยวกับฮาร์ดแวร์/โมเด็ม
LPA และระบบปฏิบัติการ eSIM บนชิป eUICC ต้องรองรับ GSMA RSP (การจัดเตรียม SIM จากระยะไกล) 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 หรือ LUI ของ LPA
หากต้องการใช้แบ็กเอนด์ LPA คุณต้องขยาย EuiccService
และประกาศบริการนี้ในไฟล์ Manifest บริการต้องกำหนดสิทธิ์android.permission.BIND_EUICC_SERVICE
ของระบบเพื่อให้มั่นใจว่ามีเพียงระบบเท่านั้นที่เชื่อมโยงกับบริการได้ บริการต้องมีตัวกรอง Intent ที่มีการดำเนินการ android.service.euicc.EuiccService
ด้วย ควรตั้งค่าลำดับความสำคัญของตัวกรอง Intent เป็นค่าที่ไม่ใช่ 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
สิทธิ์ของระบบ เช่นเดียวกับบริการ แต่ละรายการควรมีตัวกรองความตั้งใจที่มีการดำเนินการที่เหมาะสม หมวดหมู่ 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 (เช่น แบบที่ใช้ EuiccService
และ APK ที่มีกิจกรรม LUI) คือทางเลือกในการออกแบบ
EuiccCardManager
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
ที่เรียกใช้ Callback ออบเจ็กต์ Executor
นี้อาจทำงานในชุดข้อความเดียวหรือใน Thread Pool ที่คุณเลือก
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 สามารถเริ่มโฟลว์นี้ได้ และสามารถควบคุมโฟลว์ 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
เพื่อรับรหัสเปิดใช้งานจากแอปผู้ให้บริการโดยส่งผ่านการใช้งานคลาสสแต็บ 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 จะตรวจสอบข้อมูลเพิ่มเติมและเปิดใช้งานเครื่องมือสแกนคิวอาร์แทนการเชื่อมโยงการใช้งาน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 จะเชื่อมโยงกับการใช้งาน
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 เพื่อให้มั่นใจว่า eUICC API ที่เปิดเผยนั้นใช้งานได้ใน 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 เพื่อให้การทดสอบครอบคลุมมากที่สุด