ใน Android 9 คุณจะเข้าถึง Profile Management API (สาธารณะและ @SystemApi) ผ่านคลาส EuiccManager
ได้ eUICC Communication
API (@SystemApi เท่านั้น) มีให้ใช้งานผ่านคลาส EuiccCardManager
เกี่ยวกับ eUICC
ผู้ให้บริการสามารถสร้างแอปของผู้ให้บริการโดยใช้ EuiccManager เพื่อจัดการโปรไฟล์ดังที่แสดงในรูปที่ 1 แอปของผู้ให้บริการไม่จำเป็นต้องเป็นแอประบบ แต่ต้องมีสิทธิ์ของผู้ให้บริการที่ได้รับจากโปรไฟล์ eUICC แอป LPA (LUI และแบ็กเอนด์ LPA) ต้องเป็นแอประบบ (กล่าวคือรวมอยู่ในอิมเมจระบบ) เพื่อเรียกใช้ @SystemApi
รูปที่ 1 โทรศัพท์ Android ที่มีแอปของผู้ให้บริการและ LPA ของ OEM
นอกจากตรรกะในการเรียก EuiccCardManager
และพูดคุยกับ eUICC แล้ว แอป LPA ต้องใช้งานสิ่งต่อไปนี้
- ไคลเอ็นต์ SM-DP+ สื่อสารกับเซิร์ฟเวอร์ SM-DP+ เพื่อตรวจสอบสิทธิ์และดาวน์โหลดโปรไฟล์
- [ไม่บังคับ] SM-DS เพื่อรับโปรไฟล์ที่ดาวน์โหลดได้มากขึ้น
- การจัดการการแจ้งเตือนเพื่อส่งการแจ้งเตือนไปยังเซิร์ฟเวอร์เพื่ออัปเดตสถานะโปรไฟล์
- [ไม่บังคับ] การจัดการช่อง รวมถึงการเปลี่ยนระหว่างตรรกะ eSIM กับ pSIM ขั้นตอนนี้ไม่บังคับหากโทรศัพท์มีเพียงชิป eSIM เท่านั้น
- OTA ของ eSIM
แม้ว่าโทรศัพท์ Android จะมีแอป LPA มากกว่า 1 แอป แต่คุณจะเลือกได้เพียง 1 แอปเท่านั้นที่จะใช้เป็น LPA ที่ทำงานจริง โดยอิงตามลําดับความสําคัญที่กําหนดไว้ในไฟล์ AndroidManifest.xml
ของแต่ละแอป
ใช้ EuiccManager
LPA API เป็น API แบบสาธารณะผ่าน EuiccManager
(ในแพ็กเกจ android.telephony.euicc
) แอปของผู้ให้บริการสามารถรับอินสแตนซ์ของ EuiccManager
และเรียกใช้เมธอดใน EuiccManager
เพื่อรับข้อมูล eUICC และจัดการการสมัครใช้บริการ (เรียกว่าโปรไฟล์ในเอกสาร RSP ของ GSMA) เป็นอินสแตนซ์ SubscriptionInfo
หากต้องการเรียก API สาธารณะ ซึ่งรวมถึงการดาวน์โหลด เปลี่ยน และลบการสมัครใช้บริการ แอปของผู้ให้บริการต้องมีสิทธิ์ที่จำเป็น ผู้ให้บริการเครือข่ายมือถือจะเพิ่มสิทธิ์ของผู้ให้บริการในข้อมูลเมตาของโปรไฟล์ eUICC API จะบังคับใช้กฎสิทธิ์ของผู้ให้บริการตามกฎดังกล่าว
แพลตฟอร์ม Android ไม่จัดการกฎนโยบายโปรไฟล์ หากมีการประกาศกฎนโยบายในข้อมูลเมตาของโปรไฟล์ LPA จะเลือกวิธีจัดการขั้นตอนการดาวน์โหลดและการติดตั้งโปรไฟล์ได้ ตัวอย่างเช่น LPA ของ OEM บุคคลที่สามอาจจัดการกฎนโยบายโดยใช้รหัสข้อผิดพลาดพิเศษได้ (ระบบจะส่งรหัสข้อผิดพลาดจาก LPA ของ OEM ไปยังแพลตฟอร์ม จากนั้นแพลตฟอร์มจะส่งรหัสไปยัง LUI ของ OEM)
ดูข้อมูลเกี่ยวกับ API ของโปรไฟล์ที่เปิดใช้หลายรายการได้ที่โปรไฟล์ที่เปิดใช้หลายรายการ
API
คุณดู API ต่อไปนี้ได้ในเอกสารอ้างอิงEuiccManager
และ EuiccManager.java
รับอินสแตนซ์ (สาธารณะ)
รับอินสแตนซ์ของ EuiccManager
ถึง Context#getSystemService
ดูรายละเอียดได้ที่
getSystemService
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
เปิดใช้การตรวจสอบ (สาธารณะ)
ตรวจสอบว่ามีการเปิดใช้การสมัครใช้บริการแบบฝังหรือไม่ ซึ่งควรตรวจสอบก่อนเข้าถึง LPA API ดูรายละเอียดได้ที่
isEnabled
boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
return;
}
รับ EID (สาธารณะ)
รับ EID ที่ระบุฮาร์ดแวร์ eUICC ค่านี้อาจเป็นค่าว่างหาก eUICC ไม่พร้อมใช้งาน ผู้โทรต้องมีสิทธิ์ของผู้ให้บริการหรือสิทธิ์ READ_PRIVILEGED_PHONE_STATE
โปรดดูรายละเอียดที่ getEid
String eid = mgr.getEid();
if (eid == null) {
// Handle null case.
}
รับ EuiccInfo (สาธารณะ)
รับข้อมูลเกี่ยวกับ eUICC จะประกอบด้วยเวอร์ชันของระบบปฏิบัติการ ดูรายละเอียดได้ที่ getEuiccInfo
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
การสมัครใช้บริการการดาวน์โหลด (สาธารณะ)
ดาวน์โหลดการสมัครใช้บริการที่ระบุ (เรียกว่า "โปรไฟล์" ในเอกสาร RSP ของ GSMA) คุณสร้างการสมัครใช้บริการได้จากรหัสเปิดใช้งาน เช่น แยกวิเคราะห์รหัสเปิดใช้งานจากคิวอาร์โค้ด การดาวน์โหลดการติดตามเป็นการดำเนินการแบบไม่พร้อมกัน
ผู้โทรต้องมีสิทธิ์ WRITE_EMBEDDED_SUBSCRIPTIONS
หรือมีสิทธิ์ของผู้ให้บริการสำหรับการสมัครใช้บริการเป้าหมาย ดูรายละเอียดได้ที่
downloadSubscription
// Register receiver.
String action = "download_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(
receiver,
new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/, null /* handler */);
// Download subscription asynchronously.
DownloadableSubscription sub =
DownloadableSubscription.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */, callbackIntent);
เปลี่ยนการสมัครใช้บริการ (สาธารณะ)
เปลี่ยนเป็น (เปิดใช้) การสมัครใช้บริการที่ระบุ ผู้โทรต้องมีWRITE_EMBEDDED_SUBSCRIPTIONS
หรือมีสิทธิ์ของผู้ให้บริการสำหรับการสมัครใช้บริการที่เปิดใช้อยู่ในปัจจุบันและการสมัครใช้บริการเป้าหมาย ดูรายละเอียดได้ที่
switchToSubscription
// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/, null /* handler */);
// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);
เปลี่ยนการสมัครใช้บริการด้วยพอร์ต (สาธารณะ)
(ใช้ได้กับ Android 13 ขึ้นไป) สลับเป็น (เปิดใช้) การสมัครใช้บริการที่ระบุพร้อมระบุดัชนีพอร์ต
ผู้โทรต้องมี WRITE_EMBEDDED_SUBSCRIPTIONS
หรือมีสิทธิ์ระดับผู้ให้บริการสำหรับการสมัครใช้บริการที่เปิดใช้อยู่ในปัจจุบันและการสมัครใช้บริการเป้าหมาย
ดูรายละเอียดได้ที่
switchToSubscription
// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/, null /* handler */);
// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, 0 /*portIndex*/, callbackIntent);
พอร์ตซิมพร้อมใช้งานหรือไม่ (สาธารณะ)
public boolean isSimPortAvailable(int portIndex)
(ใช้ได้ใน Android 13) แสดงผลว่าดัชนีพอร์ตที่ส่งผ่านพร้อมใช้งานหรือไม่ พอร์ตจะพร้อมใช้งานหากไม่ได้เปิดใช้การสมัครใช้บริการ หรือแอปการโทรมีสิทธิ์ของผู้ให้บริการเหนือการสมัครใช้บริการที่ติดตั้งไว้ในพอร์ตที่เลือก ดูรายละเอียดได้ที่
isSimPortAvailable
ลบการสมัครใช้บริการ (สาธารณะ)
ลบการสมัครใช้บริการที่มีรหัสการสมัครใช้บริการ หากการสมัครใช้บริการเปิดใช้งานอยู่ ระบบจะปิดใช้การสมัครใช้บริการนั้นก่อน ผู้โทรต้องมีสิทธิ์ WRITE_EMBEDDED_SUBSCRIPTIONS
หรือสิทธิ์ของผู้ให้บริการสำหรับการสมัครใช้บริการเป้าหมาย โปรดดูรายละเอียดที่ deleteSubscription
// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/,
null /* handler */);
// Delete a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.deleteSubscription(1 /* subscriptionId */, callbackIntent);
ลบการสมัครใช้บริการทั้งหมด (API ของระบบ)
ลบการสมัครใช้บริการทั้งหมดในอุปกรณ์ ตั้งแต่ Android 11 เป็นต้นไป คุณควรระบุค่า EuiccCardManager#ResetOption
ที่เป็นค่า Enum เพื่อระบุว่าจะลบการสมัครใช้บริการทั้งหมดสำหรับการทดสอบ การทํางาน หรือทั้ง 2 ประเภทหรือไม่ ผู้โทรต้องมีสิทธิ์ WRITE_EMBEDDED_SUBSCRIPTIONS
// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver, new IntentFilter(action),
"example.broadcast.permission" /* broadcastPermission*/,
null /* handler */);
// Erase all operational subscriptions asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.eraseSubscriptions(
EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, callbackIntent);
เริ่มกิจกรรมการแก้ปัญหา (สาธารณะ)
เริ่มกิจกรรมเพื่อแก้ไขข้อผิดพลาดที่ผู้ใช้แก้ไขได้ หากการดำเนินการแสดงผลเป็น EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
ระบบจะเรียกใช้เมธอดนี้เพื่อแจ้งให้ผู้ใช้แก้ไขปัญหา วิธีการนี้จะเรียกได้เพียงครั้งเดียวสำหรับข้อผิดพลาดหนึ่งๆ
...
mgr.startResolutionActivity(getActivity(), 0 /* requestCode */, resultIntent, callbackIntent);
ค่าคงที่
หากต้องการดูรายการค่าคงที่ public
ใน EuiccManager
โปรดดูหัวข้อค่าคงที่