Trong Android 9, API quản lý hồ sơ (công khai và
@SystemApi) có sẵn thông qua lớp EuiccManager
. Giao tiếp eUICC
Các API (chỉ dành cho @SystemApi) được cung cấp thông qua lớp EuiccCardManager
.
Giới thiệu về eUICC
Nhà mạng có thể tạo ứng dụng của nhà mạng bằng EuiccManager để quản lý hồ sơ, như minh hoạ trong Hình 1. Ứng dụng của nhà mạng không nhất thiết phải là ứng dụng hệ thống nhưng cần phải có nhà mạng đặc quyền được cấp bởi hồ sơ eUICC. Một Ứng dụngLPA (LUI và LPA phần phụ trợ) cần phải là một ứng dụng hệ thống (tức là có trong hình ảnh hệ thống) để gọi @SystemApi.
Hình 1. Điện thoại Android có ứng dụng của nhà mạng và LPA của OEM (Nhà sản xuất thiết bị gốc)
Ngoài logic gọi EuiccCardManager
và trò chuyện với eUICC, các ứng dụng LPA
phải triển khai những nội dung sau:
- Máy khách SM-DP+ giao tiếp với máy chủ SM-DP+ để xác thực và tải hồ sơ xuống
- [Không bắt buộc] SM-DS để nhận thêm nhiều hồ sơ có thể tải xuống được
- Xử lý thông báo để gửi thông báo tới máy chủ cập nhật trạng thái của hồ sơ
- [Không bắt buộc] Quản lý vị trí sử dụng, bao gồm cả việc chuyển đổi giữa logic eSIM và pSIM. Bạn không bắt buộc phải làm việc này nếu điện thoại chỉ có chip eSIM.
- eSIM OTA
Mặc dù điện thoại Android có thể có nhiều ứng dụng LPA, nhưng chỉ có một ứng dụng LPA
có thể được chọn là LPA hoạt động thực tế dựa trên mức độ ưu tiên được xác định trong
tệp AndroidManifest.xml
của từng ứng dụng.
Sử dụng EuiccManager
Các API LPA được công khai qua EuiccManager
(trong gói
android.telephony.euicc
). Ứng dụng của nhà mạng có thể tải thực thể của EuiccManager
,
và gọi các phương thức trong EuiccManager
để lấy thông tin eUICC và quản lý
gói thuê bao (còn gọi là cấu hình trong các tài liệu GSMA RSP) dưới dạng
Các phiên bản SubscriptionInfo.
Để gọi các API công khai, bao gồm cả tải xuống, chuyển đổi và xoá gói thuê bao , thì ứng dụng của nhà mạng phải có các đặc quyền cần thiết. Nhà mạng đặc quyền do nhà mạng di động thêm vào trong siêu dữ liệu của hồ sơ. eUICC API sẽ thực thi các quy tắc về đặc quyền của nhà mạng theo đó.
Nền tảng Android không xử lý các quy tắc chính sách hồ sơ. Nếu một quy tắc chính sách được khai báo trong siêu dữ liệu hồ sơ, LPA có thể chọn cách xử lý quy trình tải xuống và cài đặt hồ sơ. Ví dụ: có thể là LPA OEM của bên thứ ba để xử lý các quy tắc chính sách bằng cách sử dụng mã lỗi đặc biệt (lỗi mã được truyền từ OEM LPA đến nền tảng, sau đó nền tảng truyền cho OEM LUI).
Để biết thông tin về nhiều API hồ sơ được bật, hãy xem Nhiều hồ sơ được bật.
API
Bạn có thể tìm thấy các API sau trong
Tài liệu tham khảo về EuiccManager
và
EuiccManager.java
.
Nhận thực thể (công khai)
Lấy thực thể của EuiccManager
thông qua Context#getSystemService
.
Để biết thông tin chi tiết, hãy xem
getSystemService
.
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
Đã bật tính năng kiểm tra (công khai)
Kiểm tra xem bạn đã bật gói thuê bao được nhúng hay chưa. Bạn cần kiểm tra điều này
trước khi truy cập API LPA. Để biết thông tin chi tiết, hãy xem isEnabled
.
boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
return;
}
Nhận EID (công khai)
Lấy EID (mã định danh dành cho eSIM) để xác định phần cứng eUICC. Giá trị này có thể rỗng nếu eUICC là
chưa sẵn sàng. Người gọi phải có đặc quyền của nhà mạng hoặc
Quyền READ_PRIVILEGED_PHONE_STATE
. Để biết thông tin chi tiết, hãy xem
getEid
.
String eid = mgr.getEid();
if (eid == null) {
// Handle null case.
}
Tải EuiccInfo (công khai)
Nhận thông tin về eUICC. Tệp này có chứa phiên bản hệ điều hành. Để biết thông tin chi tiết,
xem
getEuiccInfo
.
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
Tải gói thuê bao xuống (công khai)
Tải gói thuê bao đã cho xuống (còn gọi là "hồ sơ" trong GSMA RSP chứng từ). Bạn có thể tạo gói thuê bao bằng mã kích hoạt. Cho ví dụ: mã kích hoạt có thể được phân tích cú pháp từ mã QR. Tải xuống thuê bao là một hoạt động không đồng bộ.
Phương thức gọi phải có quyền WRITE_EMBEDDED_SUBSCRIPTIONS
hoặc
có đặc quyền của nhà mạng đối với gói thuê bao đích. Để biết thông tin chi tiết, hãy xem
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);
Chuyển gói thuê bao (công khai)
Chuyển sang (bật) gói thuê bao đã cho. Phương thức gọi phải có
WRITE_EMBEDDED_SUBSCRIPTIONS
hoặc có đặc quyền của nhà mạng đối với
đã bật gói thuê bao và gói thuê bao mục tiêu. Để biết thông tin chi tiết, hãy xem
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);
Chuyển gói thuê bao bằng cổng (công khai)
(Có trên Android 13) Chuyển sang (bật)
gói thuê bao đã cho có chỉ mục cổng được chỉ định.
Người gọi phải có WRITE_EMBEDDED_SUBSCRIPTIONS
hoặc có nhà mạng
dành cho gói thuê bao đã kích hoạt hiện tại và gói thuê bao đích.
Để biết thông tin chi tiết, hãy xem
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);
Có cổng SIM không (công khai)
public boolean isSimPortAvailable(int portIndex)
(Có từ Android 13) Trả về liệu giá trị
chỉ mục cổng truyền sẽ có sẵn. Một cổng sẽ được cung cấp nếu
chưa bật gói thuê bao hoặc ứng dụng gọi có đặc quyền của nhà mạng đối với
gói thuê bao trên cổng đã chọn. Để biết thông tin chi tiết, hãy xem isSimPortAvailable
.
Xoá gói thuê bao (công khai)
Xoá một gói thuê bao có mã nhận dạng gói thuê bao. Nếu gói thuê bao hiện là
đang hoạt động, thì trước tiên sẽ bị tắt. Phương thức gọi phải có
WRITE_EMBEDDED_SUBSCRIPTIONS
hoặc đặc quyền của nhà mạng đối với mục tiêu
của bạn. Để biết thông tin chi tiết, hãy xem
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);
Xoá tất cả gói thuê bao (API hệ thống)
Xoá tất cả các gói thuê bao trên một thiết bị. Kể từ Android
11, bạn nên cung cấp EuiccCardManager#ResetOption
giá trị enum để chỉ định xóa tất cả các bài kiểm thử, hoạt động hay cả hai loại
gói thuê bao. Phương thức gọi phải có quyền 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);
Bắt đầu hoạt động giải quyết (công khai)
Bắt đầu một hoạt động để giải quyết lỗi có thể giải quyết được cho người dùng. Nếu một toán tử trả về
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
, phương thức này có thể là
để nhắc người dùng giải quyết vấn đề. Chỉ có thể gọi phương thức này
một lần cho một lỗi cụ thể.
...
mgr.startResolutionActivity(getActivity(), 0 /* requestCode */, resultIntent, callbackIntent);
Hằng số
Để xem danh sách các hằng số public
trong EuiccManager
, hãy xem
Hằng số.