واجهات برمجة تطبيقات eUICC

في Android 9، واجهات برمجة تطبيقات إدارة الملف الشخصي (العامة @SystemApi) متاحة من خلال الفئة EuiccManager. اتصال eUICC تتوفّر واجهات برمجة التطبيقات (@SystemApi فقط) من خلال الفئة EuiccCardManager.

لمحة عن eUICC

يمكن لمشغِّلي شبكات الجوّال إنشاء تطبيقات مشغّل شبكة جوّال باستخدام EuiccManager لإدارة الملفات الشخصية، على النحو الموضّح. في الشكل 1. ليس من الضروري أن تكون تطبيقات مشغِّل شبكة الجوّال من تطبيقات نظام، ولكن يجب أن تتوفّر لدى مشغِّل شبكة الجوّال الامتيازات التي تمنحها الملفات الشخصية لـ eUICC. إنّ تطبيق LPA (LUI وLPA) الخلفية) إلى أن يكون تطبيق نظام (على سبيل المثال، مضمنًا في صورة النظام) للاتصال @SystemApi.

هاتف Android يشتمِل على تطبيق مشغّل شبكة الجوّال وLPA للمصنّع الأصلي للجهاز

الشكل 1. هواتف Android مع تطبيق مشغّل شبكة الجوّال و"إعلانات المنتجات داخل المتجر" الخاصة بالمصنّع الأصلي للجهاز

إلى جانب منطق الاتصال بـ EuiccCardManager والتحدّث إلى تطبيقات eUICC وتطبيقات LPA تنفيذ ما يلي:

  • عميل SM-DP+ يتحدث إلى خادم SM-DP+ للمصادقة تنزيل الملفات الشخصية
  • [اختياري] SM-DS للحصول على المزيد من الملفات الشخصية المحتملة القابلة للتنزيل
  • معالجة الإشعارات لإرسال إشعارات إلى الخادم تعديل حالة الملف الشخصي
  • [اختياري] إدارة الخانات، بما في ذلك التبديل بين منطق eSIM وpSIM ويكون هذا الإجراء اختياريًا إذا كان الهاتف يحتوي على شريحة eSIM فقط.
  • شريحة eSIM عبر الهواء

على الرغم من أنّه يمكن توفّر أكثر من تطبيق LPA واحد في هاتف Android، إلّا أنّ تطبيق LPA واحد يمكن اختيارها لتكون إعلانات الأنشطة التجارية المحلية الفعلية بناءً على الأولوية المحددة في الملف AndroidManifest.xml لكل تطبيق.

استخدام EuiccManager

واجهات برمجة تطبيقات LPA متاحة للجميع من خلال EuiccManager (ضمن الحزمة android.telephony.euicc). يمكن لتطبيق مشغّل شبكة الجوّال الحصول على مثيل EuiccManager، واستدعاء الطرق في EuiccManager للحصول على معلومات eUICC وإدارتها الاشتراكات (يُشار إليها باسم الملفات الشخصية في مستندات GSMA RSP) حالات SubscriptionInfo

لطلب البيانات من واجهات برمجة التطبيقات العلنية، بما في ذلك تنزيل الاشتراك والتبديل إليه وحذفه العمليات، يجب أن يحصل تطبيق مشغل شبكة الجوال على الامتيازات المطلوبة. مشغّل شبكة الجوّال الامتيازات التي تتم إضافتها بواسطة مشغّل شبكة الجوّال في البيانات الوصفية للملف الشخصي. قانون eUICC تفرض واجهة برمجة التطبيقات قواعد امتيازات مشغّل شبكة الجوّال وفقًا لذلك.

لا يعالج نظام Android الأساسي قواعد سياسة الملف الشخصي. إذا كانت قاعدة السياسة في بيانات الملف الشخصي، يمكن لـ LPA اختيار طريقة التعامل مع إجراء تنزيل الملف الشخصي وتثبيته. على سبيل المثال، من الممكن إعلانات LPA من المصنّع الأصلي للجهاز من أجل معالجة قواعد السياسة باستخدام رمز خطأ خاص (الخطأ تمرير الرمز من "LPA" للمصنّع الأصلي للجهاز إلى المنصة، ثم تمرر المنصة الكود إلى 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) (بشكل علني)

الحصول على معرّف شريحة SIM المضمّنة (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);

محو جميع الاشتراكات (واجهة برمجة تطبيقات النظام)

يمحو جميع الاشتراكات على الجهاز. بدءًا من Android 11، يجب تقديم 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، راجِع الثابت: