في Android 9، تتوفّر واجهات برمجة التطبيقات لإدارة الملف الشخصي (العامة و@SystemApi) من خلال الفئة EuiccManager
. واجهة برمجة التطبيقات (SystemApi فقط) لميزة eUICC
التواصل متاحة من خلال الفئة EuiccCardManager
.
لمحة عن شريحة eUICC
يمكن لمشغّلي شبكات الجوّال إنشاء تطبيقات مشغّلي شبكات الجوّال باستخدام EuiccManager لإدارة الملفات الشخصية، كما هو موضّح في الشكل 1. لا يُشترط أن تكون تطبيقات مشغّلي شبكات الجوَّال تطبيقات نظام، ولكن يجب أن تمتلك امتيازات مشغّل شبكة الجوَّال التي تمنحها ملفات تعريف eUICC. يجب أن يكون تطبيق LPA (واجهة المستخدم وLPA الخلفية) تطبيقًا للنظام (أي مضمّنًا في صورة النظام) للاتصال بواجهة برمجة التطبيقات SystemApi.
الشكل 1: هواتف Android المزوّدة بتطبيق مشغِّل شبكة الجوّال وبرنامج LPA من المصنّع الأصلي للجهاز
بالإضافة إلى منطق الاتصال بـ EuiccCardManager
والتواصل مع eUICC، يجب أن توفّر تطبيقات LPA
الميزات التالية:
- تواصل عميل SM-DP+ مع خادم SM-DP+ للمصادقة على الملفات الشخصية وتنزيلها
- [اختياري] SM-DS للحصول على المزيد من الملفات الشخصية المحتملة للتنزيل
- معالجة الإشعارات لإرسال إشعارات إلى الخادم بهدف تعديل حالة الملف الشخصي
- [اختياري] إدارة الفتحات، بما في ذلك التبديل بين منطق eSIM وpSIM هذا الإجراء اختياري إذا كان الهاتف يحتوي على شريحة eSIM فقط.
- تحديث شريحة eSIM عبر الهواء
على الرغم من أنّه يمكن أن يتوفّر أكثر من تطبيق LPA واحد في هاتف Android، يمكن اختيار تطبيق LPA واحد فقط
ليكون تطبيق LPA الفعلي الذي يعمل استنادًا إلى الأولوية المحدّدة فيملفAndroidManifest.xml
لكل تطبيق.
استخدام EuiccManager
تكون واجهات برمجة تطبيقات LPA علنية من خلال EuiccManager
(ضمن الحزمة
android.telephony.euicc
). يمكن لتطبيق مشغّل شبكة الجوّال الحصول على مثيل EuiccManager
،
واستخدام الطرق الواردة في EuiccManager
للحصول على معلومات eUICC وإدارة
الاشتراكات (المعروفة باسم الملفات الشخصية في مستندات GSMA RSP) على هيئة
مثيلات SubscriptionInfo.
لاستدعاء واجهات برمجة التطبيقات العامة، بما في ذلك عمليات تنزيل الاشتراكات وتبديلها وحذفها، يجب أن يكون لدى تطبيق مشغّل شبكة الجوَّال الامتيازات المطلوبة. تضيف شركة الجوّال امتيازات في البيانات الوصفية للملف التجاري. تفرض واجهة برمجة التطبيقات eUICC API قواعد امتيازات مشغّل شبكة الجوّال وفقًا لذلك.
لا يعالج نظام التشغيل Android قواعد سياسة الملف التجاري. إذا تمّ تحديد قاعدة سياسة في البيانات الوصفية للملف الشخصي، يمكن لـ LPA اختيار كيفية التعامل مع إجراء تنزيل الملف الشخصي وتثبيته. على سبيل المثال، من الممكن أن يعالج ملف APX لجهة خارجية تابعة لمصنعي المعدّات الأصلية قواعد السياسة باستخدام رمز خطأ خاص (يتم تمرير رمز الخطأ من ملف APX لجهة خارجية تابعة لمصنعي المعدّات الأصلية إلى المنصة، ثم تمرّر المنصة رمز الخطأ إلى ملف LUI لجهة خارجية تابعة لمصنعي المعدّات الأصلية).
للحصول على معلومات عن واجهات برمجة التطبيقات الخاصة بالملفات الشخصية المفعَّلة المتعددة، يُرجى الاطّلاع على مقالة الملفات الشخصية المفعَّلة المتعددة.
واجهات برمجة التطبيقات
يمكن العثور على واجهات برمجة التطبيقات التالية في
المستندات المرجعية لـ EuiccManager
و
EuiccManager.java
.
الحصول على مثيل (عام)
تحصل على نسخة من EuiccManager
حتى Context#getSystemService
.
للاطّلاع على التفاصيل، يُرجى الاطّلاع على
getSystemService
.
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
التحقق من تفعيل الميزة (علنية)
للتحقّق مما إذا كان الاشتراك المضمّن مفعّلاً يجب التحقّق من ذلك
قبل الوصول إلى واجهات برمجة تطبيقات LPA. للاطّلاع على التفاصيل، يُرجى الاطّلاع على
isEnabled
.
boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
return;
}
الحصول على معرّف شريحة SIM المضمّنة (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();
اشتراك لتنزيل المحتوى (متاح للجميع)
تنزيل الاشتراك المحدَّد (يُشار إليه باسم "الملف الشخصي" في مستندات GSMA RSP ) يمكن إنشاء الاشتراك من رمز تفعيل. على سبيل المثال، يمكن تحليل رمز التفعيل من رمز الاستجابة السريعة. تنزيل اشتراك هو عملية غير متزامنة.
يجب أن يكون لدى المتصل إذن 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);
هل منفذ شريحة SIM متاح (عام)؟
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);
محو جميع الاشتراكات (واجهة برمجة التطبيقات للنظام)
يؤدي هذا الإجراء إلى محو جميع الاشتراكات على الجهاز. اعتبارًا من الإصدار
11 من Android، عليك تقديم قيمة EuiccCardManager#ResetOption
قائمة بقيم ثابتة لتحديد ما إذا كنت تريد محو كل أنواع
الاشتراكات الاختبارية أو التشغيلية أو كليهما. يجب أن يكون لدى المتصل إذن 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
، اطّلِع على
الثوابت.