في الإصدار 9 من نظام Android، تتوفّر واجهات برمجة التطبيقات لإدارة الملف الشخصي (المتاحة للجميع و @SystemApi) للفئة EuiccManager
. واجهة برمجة التطبيقات (SystemApi فقط) لاتصالات eUICC
تتوفّر من خلال الفئة EuiccCardManager
.
لمحة عن شريحة eUICC
يمكن لمشغّلي شبكات الجوّال إنشاء تطبيقات مشغّلي شبكات الجوّال باستخدام EuiccManager لإدارة الملفات الشخصية، كما هو موضّح في الشكل 1. لا يلزم أن تكون تطبيقات مشغِّل شبكة الجوّال تطبيقات نظام، ولكن يجب أن تتوفّر لها امتيازات مشغّل شبكة الجوّال التي تمنحها الملفات الشخصية لـ eUICC. يجب أن يكون تطبيق LPA (واجهة المستخدم وLPA الخلفية) تطبيقًا للنظام (أي مضمّنًا في صورة النظام) للاتصال بواجهة برمجة التطبيقات @SystemApi.
الشكل 1: هواتف Android مع تطبيق مشغّل شبكة الجوّال و"إعلانات المنتجات داخل المتجر" الخاصة بالمصنّع الأصلي للجهاز
بالإضافة إلى منطق طلب 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 قواعد امتيازات مشغِّل شبكة الجوّال وفقًا لذلك.
لا يعالج نظام التشغيل 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;
}
الحصول على رقم تعريف الجهاز (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
أو امتيازات carrier
للاشتراك المفعَّل الحالي والاشتراك المستهدَف.
لمعرفة التفاصيل، يُرجى الاطّلاع على 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
، اطّلِع على
الثوابت.