پیاده‌سازی سیم‌کارت داخلی

فناوری سیم‌کارت داخلی (eSIM یا eUICC) به کاربران تلفن همراه امکان می‌دهد نمایه شرکت مخابراتی را بارگیری کنند و سرویس شرکت مخابراتی را بدون نیاز به سیم‌کارت فیزیکی فعال کنند. این یک مشخصه جهانی است که توسط GSMA هدایت می‌شود و تأمین سیم‌کارت از راه دور (RSP) را برای هر دستگاه همراهی امکان‌پذیر می‌کند. از Android 9 شروع می‌شود، چارچوب Android میاناهای برنامه‌سازی کاربردی استاندارد برای دسترسی به سیم‌کارت داخلی و مدیریت نمایه‌های اشتراک در سیم‌کارت داخلی ارائه می‌دهد. این eUICC APIs به طرف‌های سوم امکان می‌دهد برنامه‌های شرکت مخابراتی و دستیارهای نمایه محلی (LPAs) خودشان را در دستگاه‌های Android مجهز به سیم‌کارت داخلی توسعه دهند.

‫LPA یک برنامه سیستم مستقل است که باید در تصویر ساخت Android گنجانده شود. مدیریت نمایه‌ها در سیم‌کارت داخلی معمولاً توسط «عامل آماده‌سازی محلی» انجام می‌شود، زیرا این عامل به‌عنوان پلی بین SM-DP+ (سرویس راه دور که بسته‌های نمایه را برای دستگاه‌ها آماده، ذخیره، و ارسال می‌کند) و تراشه eUICC عمل می‌کند. «فایل نصب LPA» می‌تواند به‌صورت اختیاری شامل عنصر واسط کاربر (UI) به نام «واسط کاربر LPA» یا LUI باشد تا مکان مرکزی برای کاربر نهایی فراهم کند تا همه نمایه‌های اشتراک جاسازی‌شده را مدیریت کند. چارچوب Android به‌طور خودکار بهترین LPA دردسترس را پیدا می‌کند و به آن متصل می‌شود، و همه عملیات eUICC را ازطریق یک نمونه LPA هدایت می‌کند.

معماری ساده‌شده آماده‌سازی سیم‌کارت از دور (RSP)

شکل ۱. معماری ساده‌شده RSP

اپراتورهای شبکه تلفن همراه که علاقه‌مند به ایجاد برنامه شرکت مخابراتی هستند باید به میاناهای برنامه‌سازی کاربردی در EuiccManager، که عملیات مدیریت نمایه‌های سطح بالا مثل downloadSubscription()،‏ switchToSubscription()، و deleteSubscription() را ارائه می‌دهد، نگاه کنند.

اگر «سازنده اصلی محصول» دستگاهی هستید که به ایجاد برنامه سیستم LPA خودتان علاقه‌مندید، باید EuiccService را برای چارچوب Android گسترش دهید تا به خدمات LPA شما متصل شود. علاوه‌براین، باید از میاناهای برنامه‌سازی کاربردی در EuiccCardManager استفاده کنید که براساس GSMA RSP v2.0 توابع ES10x را ارائه می‌دهد. این توابع برای صدور فرمان به تراشه eUICC استفاده می‌شوند، مثل prepareDownload()، loadBoundProfilePackage()، retrieveNotificationList()، و resetMemory().

میاناهای برنامه‌سازی کاربردی در EuiccManager برای عملکرد به برنامه LPA با پیاده‌سازی صحیح نیاز دارند و فراخواننده EuiccCardManager میاناهای برنامه‌سازی کاربردی باید LPA باشد. این مورد توسط چارچوب Android اعمال می‌شود.

دستگاه‌های دارای Android 10 یا بالاتر می‌توانند از دستگاه‌های دارای چند سیم‌کارت داخلی پشتیبانی کنند. برای اطلاعات بیشتر، پشتیبانی از چند سیم‌کارت داخلی را ببینید.

ساختن برنامه شرکت مخابراتی

میاناهای برنامه‌سازی کاربردی eUICC در Android 9 به اپراتورهای شبکه تلفن همراه امکان می‌دهد برنامه‌هایی با نمانام شرکت مخابراتی برای مدیریت مستقیم تمایه‌هایشان ایجاد کنند. این شامل بارگیری و حذف نمایه‌های اشتراک متعلق به شرکت مخابراتی و همچنین جابه‌جایی به نمایه متعلق به شرکت مخابراتی می‌شود.

EuiccManager

‫EuiccManager نقطه ورود اصلی برنامه‌ها برای تعامل با LPA است. این شامل برنامه‌های شرکت مخابراتی می‌شود که به اشتراک‌های متعلق به شرکت مخابراتی بارگیری، حذف، و تغییر می‌کنند. این شامل برنامه سیستم LUI نیز می‌شود که مکان/رابط کاربری مرکزی برای مدیریت همه اشتراک‌های جاسازی‌شده ارائه می‌دهد و می‌تواند برنامه‌ای جدا از برنامه‌ای باشد که EuiccService را ارائه می‌دهد.

برای استفاده از میاناهای برنامه‌سازی کاربردی عمومی، برنامه شرکت مخابراتی ابتدا باید نمونه EuiccManager را ازطریق Context#getSystemService دریافت کند:

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

قبل‌از انجام هرگونه عملیات مربوط به سیم‌کارت داخلی، باید بررسی کنید که آیا سیم‌کارت داخلی در دستگاه پشتیبانی می‌شود یا نه. EuiccManager#isEnabled() معمولاً true را برمی‌گرداند اگر ویژگی android.hardware.telephony.euicc تعریف شده باشد و بسته LPA وجود داشته باشد.

if (mgr == null || !mgr.isEnabled()) {
    return;
}

برای دریافت اطلاعات درباره سخت‌افزار eUICC و نسخه سیستم‌عامل سیم‌کارت داخلی:

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

بسیاری از «میاناهای برنامه‌سازی کاربردی» مانند downloadSubscription() و switchToSubscription() از PendingIntent برگشتی استفاده می‌کنند زیرا ممکن است تکمیل آن‌ها چند ثانیه یا حتی چند دقیقه طول بکشد. ‫PendingIntent با کد نتیجه در فضای EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ ارسال می‌شود که کدهای خطای تعریف‌شده در چارچوب و همچنین کد نتیجه دقیق دلخواه را که از LPA به‌عنوان EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE منتشر شده است ارائه می‌دهد و به برنامه شرکت مخابراتی اجازه می‌دهد تا برای اهداف ثبت/اشکال‌زدایی ردیابی کند. ‫PendingIntent ‫callback باید BroadcastReceiver باشد.

برای بارگیری اشتراک قابل‌بارگیری معینی (ایجادشده از کد فعال‌سازی یا رمزینه پاسخ‌سریع):

// Register receiver.
static final String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
static final String LPA_DECLARED_PERMISSION
    = "com.your.company.lpa.permission.BROADCAST";
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*/);

                // If the result code is a resolvable error, call startResolutionActivity
                if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR) {
                    PendingIntent callbackIntent = PendingIntent.getBroadcast(
                        getContext(), 0 /* requestCode */, intent,
                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
                    mgr.startResolutionActivity(
                        activity,
                        0 /* requestCode */,
                        intent,
                        callbackIntent);
                }

                resultIntent = intent;
            }
        };
context.registerReceiver(receiver,
        new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
        LPA_DECLARED_PERMISSION /* broadcastPermission*/,
        null /* handler */);

// Download subscription asynchronously.
DownloadableSubscription sub = DownloadableSubscription
        .forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
        callbackIntent);

اجازه را در AndroidManifest.xml تعریف و استفاده کنید:

    <permission android:protectionLevel="signature" android:name="com.your.company.lpa.permission.BROADCAST" />
    <uses-permission android:name="com.your.company.lpa.permission.BROADCAST"/>

برای تغییر به اشتراک با شناسه اشتراک:

// Register receiver.
static final String ACTION_SWITCH_TO_SUBSCRIPTION = "switch_to_subscription";
static final String LPA_DECLARED_PERMISSION
    = "com.your.company.lpa.permission.BROADCAST";
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_SWITCH_TO_SUBSCRIPTION),
        LPA_DECLARED_PERMISSION /* broadcastPermission*/,
        null /* handler */);

// Switch to a subscription asynchronously.
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

برای فهرست کامل EuiccManager API و نمونه‌های کد، به eUICC APIs مراجعه کنید.

خطاهای قابل‌حل

در برخی موارد، سیستم نمی‌تواند عملیات سیم‌کارت داخلی را تکمیل کند اما کاربر می‌تواند خطا را برطرف کند. برای مثال، اگر فراداده نمایه نشان دهد که کد تأیید شرکت مخابراتی الزامی است، ممکن است downloadSubscription ناموفق باشد. یا اگر برنامه شرکت مخابراتی دارای امتیازهای شرکت مخابراتی برای نمایه مقصد باشد (یعنی شرکت مخابراتی مالک نمایه باشد) اما برای نمایه فعال فعلی امتیازهای شرکت مخابراتی نداشته باشد، switchToSubscription ممکن است ناموفق باشد و درنتیجه رضایت کاربر لازم باشد.

برای این موارد، با EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR با تماس‌گیرنده تماس گرفته می‌شود. بازخوان Intent حاوی موارد اضافی داخلی است به‌طوری‌که وقتی تماس‌گیرنده آن را به EuiccManager#startResolutionActivity منتقل می‌کند، می‌توان ازطریق LUI درخواست وضوح کرد. استفاده از کد تأیید برای مثال دوباره، EuiccManager#startResolutionActivity باعث راه‌اندازی صفحه LUI می‌شود که به کاربر امکان می‌دهد کد تأیید را وارد کند؛ پس‌از وارد شدن کد، عملیات بارگیری ازسر گرفته می‌شود. این رویکرد به برنامه شرکت مخابراتی امکان می‌دهد کنترل کامل بر زمان نمایش واسط کاربر داشته باشد، اما به LPA/LUI روشی توسعه‌پذیر برای افزودن مدیریت جدید مشکلات قابل‌بازیابی توسط کاربر در آینده می‌دهد بدون اینکه نیاز باشد برنامه‌های مشتری تغییر کنند.

‫Android 9 این خطاهای قابل‌حل را در EuiccService تعریف می‌کند که «واسط کاربر سطح پایین» باید آن‌ها را مدیریت کند:

/**
 * Alert the user that this action will result in an active SIM being
 * deactivated. To implement the LUI triggered by the system, you need to define
 * this in AndroidManifest.xml.
 */
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
        "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
 * Alert the user about a download/switch being done for an app that doesn't
 * currently have carrier privileges.
 */
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
        "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";

/** Ask the user to resolve all the resolvable errors. */
public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
        "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";

امتیازات شرکت مخابراتی

اگر شرکت مخابراتی هستید که برنامه شرکت مخابراتی خودتان را توسعه می‌دهید و برای بارگیری نمایه‌ها در دستگاه EuiccManager تماس می‌گیرد، نمایه شما باید شامل قوانین امتیاز شرکت مخابراتی متناظر با برنامه شرکت مخابراتی شما در فراداده باشد. دلیل این امر این است که نمایه‌های اشتراک متعلق به شرکت‌های مخابراتی مختلف می‌توانند در eUICC دستگاه هم‌زیستی داشته باشند و هر برنامه شرکت مخابراتی فقط باید اجازه دسترسی به نمایه‌های متعلق به آن شرکت مخابراتی را داشته باشد. برای مثال، شرکت مخابراتی A نباید بتواند نمایه متعلق به شرکت مخابراتی B را بارگیری، فعال، یا غیرفعال کند.

برای اطمینان از اینکه نمایه فقط برای مالک آن دردسترس است، Android از سازوکاری برای اعطای امتیازات ویژه به برنامه مالک نمایه (یعنی برنامه شرکت مخابراتی) استفاده می‌کند. پلاتفرم Android گواهینامه‌های ذخیره‌شده در فایل قانون دسترسی نمایه (ARF) را بار می‌کند و به برنامه‌هایی که با این گواهینامه‌ها امضا شده‌اند اجازه می‌دهد با میاناهای برنامه‌سازی کاربردی EuiccManager تماس بگیرند. فرایند سطح بالا در زیر شرح داده شده است:

  1. شرکت مخابراتی فایل APK برنامه شرکت مخابراتی را امضا می‌کند؛ ابزار apksigner گواهینامه کلید عمومی را به فایل APK پیوست می‌کند.
  2. شرکت مخابراتی/SM-DP+‎ نمایه و فراداده آن را آماده می‌کند که شامل ARF است که حاوی موارد زیر است:

    1. امضا (SHA-1 یا SHA-256) گواهینامه کلید عمومی برنامه شرکت مخابراتی (الزامی)
    2. نام بسته برنامه شرکت مخابراتی (به‌شدت توصیه می‌شود)
  3. برنامه شرکت مخابراتی سعی می‌کند عملیات eUICC را با EuiccManager API انجام دهد.

  4. پلاتفرم Android بررسی می‌کند که مقدار درهم‌سازی SHA-1 یا SHA-256 گواهینامه برنامه تماس‌گیرنده با امضای گواهینامه دریافت‌شده از ARF نمایه مقصد مطابقت داشته باشد. اگر نام بسته برنامه شرکت مخابراتی در ARF گنجانده شده است، باید با نام بسته برنامه تماس‌گیرنده نیز مطابقت داشته باشد.

  5. پس‌از درستی‌سنجی امضا و نام بسته (درصورت وجود)، امتیاز شرکت مخابراتی به برنامه تماس‌گیرنده در نمایه هدف اعطا می‌شود.

ازآنجایی‌که فراداده نمایه می‌تواند خارج از خود نمایه دردسترس باشد (به‌طوری‌که LPA می‌تواند فراداده نمایه را از SM-DP+ قبل‌از بارگیری نمایه، یا از ISD-R وقتی نمایه غیرفعال است بازیابی کند)، باید حاوی همان قوانین امتیاز شرکت مخابراتی موجود در نمایه باشد.

سیستم‌عامل eUICC و SM-DP+ باید از برچسب اختصاصی BF76 در فراداده نمایه پشتیبانی کنند. محتوای برچسب باید همان قوانین امتیاز شرکت مخابراتی باشد که توسط برنامه کوچک قانون دسترسی (ARA) تعریف‌شده در امتیازات شرکت مخابراتی UICC برگردانده شده است:

RefArDo ::= [PRIVATE 2] SEQUENCE {  -- Tag E2
    refDo [PRIVATE 1] SEQUENCE {  -- Tag E1
        deviceAppIdRefDo [PRIVATE 1] OCTET STRING (SIZE(20|32)),  -- Tag C1
        pkgRefDo [PRIVATE 10] OCTET STRING (SIZE(0..127)) OPTIONAL  -- Tag CA
    },
    arDo [PRIVATE 3] SEQUENCE {  -- Tag E3
        permArDo [PRIVATE 27] OCTET STRING (SIZE(8))  -- Tag DB
    }
}

برای جزئیات بیشتر درباره امضای برنامه، به امضای برنامه مراجعه کنید. برای جزئیات بیشتر درباره امتیازات شرکت مخابراتی، به امتیازات شرکت مخابراتی UICC مراجعه کنید.

ساختن برنامه همیار نمایه محلی

تولیدکنندگان دستگاه می‌توانند دستیار نمایه محلی (LPA) خودشان را پیاده‌سازی کنند که باید با واسط برنامه‌نویسی کاربردی Android Euicc مرتبط شود. بخش‌های زیر نمای کلی مختصری از ساختن برنامه LPA و ادغام آن با سیستم Android ارائه می‌دهد.

الزامات سخت‌افزار/مودم

LPA و سیستم‌عامل eSIM در تراشه eUICC باید حداقل از GSMA RSP (Remote SIM Provisioning) نسخه ۲.۰ یا ۲.۲ پشتیبانی کنند. همچنین باید برنامه‌ریزی کنید که از سرورهای SM-DP+ و SM-DS که نسخه RSP منطبق دارند استفاده کنید. برای جزئیات معماری RSP، به مشخصات معماری GSMA SGP.21 RSP مراجعه کنید.

علاوه‌براین، برای ادغام با میاناهای برنامه‌سازی کاربردی eUICC در Android 9، مودم دستگاه باید قابلیت‌های پایانه را با پشتیبانی از قابلیت‌های eUICC کدبندی‌شده (مدیریت نمایه محلی و بارگیری نمایه) ارسال کند. همچنین باید روش‌های زیر را پیاده‌سازی کند:

  • IRadio HAL v1.1: setSimPower
  • IRadio HAL v1.2: getIccCardStatus

  • IRadioConfig HAL v1.0: getSimSlotsStatus

  • IRadioConfig AIDL v1.0: getAllowedCarriers

    «برنامه مجوز Google» باید از وضعیت قفل شرکت مخابراتی مطلع باشد تا بتواند بارگیری یا انتقال سیم‌کارت داخلی را فقط برای شرکت مخابراتی مجاز امکان‌پذیر کند. درغیراین‌صورت، کاربران ممکن است سیم‌کارتی را بارگیری و انتقال دهند و بعداً متوجه شوند که دستگاه به شرکت مخابراتی دیگری قفل شده است.

    • فروشندگان یا سازندگان اصلی محصول باید IRadioSim.getAllowedCarriers()HAL API را پیاده‌سازی کنند.

    • «فروشنده RIL / مودم» باید وضعیت قفل و carrierId اپراتوری را که دستگاه به آن قفل شده است به‌عنوان بخشی از IRadioSimResponse.getAllowedCarriersResponse()HAL API تکمیل کند.

مودم باید سیم‌کارت داخلی را با نمایه راه‌اندازی پیش‌فرض فعال به‌عنوان سیم‌کارت معتبر تشخیص دهد و برق سیم‌کارت را روشن نگه دارد.

برای دستگاه‌های دارای Android 10، آرایه شناسه جایگاه eUICC غیرقابل‌حذف باید تعریف شود. برای مثال، به arrays.xml مراجعه کنید.

<resources>
   <!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
        e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
        eUICC, then the value of this array should be:
            <integer-array name="non_removable_euicc_slots">
                <item>1</item>
            </integer-array>
        If a device has three physical slots and slot 1 and 2 are eUICCs, then the value of
        this array should be:
            <integer-array name="non_removable_euicc_slots">
               <item>1</item>
               <item>2</item>
            </integer-array>
        This is used to differentiate between removable eUICCs and built in eUICCs, and should
        be set by OEMs for devices which use eUICCs. -->

   <integer-array name="non_removable_euicc_slots">
       <item>1</item>
   </integer-array>
</resources>

برای فهرست کامل الزامات مودم، به الزامات مودم برای پشتیبانی از سیم‌کارت داخلی مراجعه کنید.

EuiccService

«دستیار پرداخت مجاز» از دو جزء جداگانه تشکیل شده است (هر دو ممکن است در یک APK پیاده‌سازی شوند): زیرینه «دستیار پرداخت مجاز» و میانای کاربری «دستیار پرداخت مجاز» یا LUI.

برای پیاده‌سازی زیرینه LPA، باید EuiccService را گسترش دهید و این سرویس را در فایل مانیفست خود اعلام کنید. سرویس باید به اجازه سیستم android.permission.BIND_EUICC_SERVICE نیاز داشته باشد تا اطمینان حاصل شود که فقط سیستم می‌تواند به آن متصل شود. این سرویس باید فیلتر هدفی با کنش android.service.euicc.EuiccService نیز داشته باشد. اولویت فیلتر قصد باید روی مقدار غیرصفر تنظیم شود تا درصورت وجود چندین پیاده‌سازی در دستگاه، اولویت مشخص باشد. برای مثال:

<service
    android:name=".EuiccServiceImpl"
    android:permission="android.permission.BIND_EUICC_SERVICE">
    <intent-filter android:priority="100">
        <action android:name="android.service.euicc.EuiccService" />
    </intent-filter>
</service>

درون‌برنامه‌ای، چارچوب Android «میانای برنامه‌سازی کاربردی» فعال را تعیین می‌کند و درصورت نیاز برای پشتیبانی از «میاناهای برنامه‌سازی کاربردی» Android eUICC با آن تعامل برقرار می‌کند. PackageManager برای همه برنامه‌های دارای اجازه android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS که سرویسی را برای کنش android.service.euicc.EuiccService مشخص می‌کند، پرسمان می‌شود. سرویس با بالاترین اولویت انتخاب می‌شود. اگر سرویسی پیدا نشد، پشتیبانی LPA غیرفعال می‌شود.

برای پیاده‌سازی LUI، باید فعالیتی برای کنش‌های زیر ارائه دهید:

  • android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
  • android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION

همانند سرویس، هر فعالیت باید به اجازه سیستم android.permission.BIND_EUICC_SERVICE نیاز داشته باشد. هرکدام باید فیلتر هدفی با کنش مناسب، دسته android.service.euicc.category.EUICC_UI، و اولویت غیرصفر داشته باشد. از منطق مشابهی برای انتخاب پیاده‌سازی‌های این فعالیت‌ها مانند انتخاب پیاده‌سازی EuiccService استفاده می‌شود. برای مثال:

<activity android:name=".MyLuiActivity"
          android:exported="true"
          android:permission="android.permission.BIND_EUICC_SERVICE">
    <intent-filter android:priority="100">
        <action android:name="android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
        <action android:name="android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.service.euicc.category.EUICC_UI" />
    </intent-filter>
</activity>

این یعنی میانای کاربری که این صفحه‌ها را پیاده‌سازی می‌کند می‌تواند از APK دیگری نسبت‌به APK پیاده‌سازی‌کننده EuiccService باشد. داشتن یک فایل APK یا چند فایل APK (برای مثال، یکی که EuiccService را پیاده‌سازی می‌کند و دیگری که فعالیت‌های LUI را ارائه می‌دهد) یک انتخاب طراحی است.

EuiccCardManager

‫EuiccCardManager میانای ارتباط با تراشه سیم‌کارت داخلی است. این سرویس عملکردهای ES10 را (همان‌طور که در مشخصات GSMA RSP شرح داده شده است) ارائه می‌دهد و فرمان‌های درخواست/پاسخ APDU سطح پایین و همچنین تجزیه ASN.1 را مدیریت می‌کند. ‫EuiccCardManager یک میانای برنامه‌سازی کاربردی سیستم است و فقط برنامه‌های دارای امتیاز سیستم می‌توانند آن را فرابخوانند.

برنامه‌های شرکت مخابراتی، LPA، و Euicc APIs

شکل ۲. هم برنامه شرکت مخابراتی و هم LPA از Euicc APIs استفاده می‌کنند

میاناهای برنامه‌سازی کاربردی عملیات نمایه ازطریق EuiccCardManager نیاز دارد که تماس‌گیرنده یک LPA باشد. این مورد توسط چارچوب Android اعمال می‌شود. این یعنی تماس‌گیرنده باید EuiccService را گسترش دهد و همان‌طور که در بخش‌های قبلی توضیح داده شده است در فایل مانیفست شما اعلام شود.

مشابه با EuiccManager، برای استفاده از EuiccCardManager API، «برنامه مجوزدار شما» باید ابتدا نمونه EuiccCardManager را ازطریق Context#getSystemService دریافت کند:

EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);

سپس، برای دریافت همه نمایه‌ها در eUICC:

ResultCallback<EuiccProfileInfo[]> callback =
       new ResultCallback<EuiccProfileInfo[]>() {
           @Override
           public void onComplete(int resultCode,
                   EuiccProfileInfo[] result) {
               if (resultCode == EuiccCardManagerReflector.RESULT_OK) {
                   // handle result
               } else {
                   // handle error
               }
           }
       };

cardMgr.requestAllProfiles(eid, AsyncTask.THREAD_POOL_EXECUTOR, callback);

در داخل، EuiccCardManager ازطریق میانای AIDL به EuiccCardController (که در فرایند تلفن اجرا می‌شود) متصل می‌شود و هر روش EuiccCardManager فراخوان برگشتی خود را از فرایند تلفن ازطریق میانای AIDL اختصاصی و متفاوت دریافت می‌کند. هنگام استفاده از میاناهای برنامه‌سازی کاربردی EuiccCardManager، تماس‌گیرنده (LPA) باید یک شیء Executor ارائه دهد که ازطریق آن فراخوانی برگشتی فراخوانده شود. این شیء Executor ممکن است در یک رشته یا در استخر رشته‌ای که انتخاب می‌کنید اجرا شود.

اکثر میاناهای برنامه‌سازی کاربردی EuiccCardManager الگوی استفاده یکسانی دارند. برای مثال، برای بار کردن بسته نمایه محدودشده روی eUICC:

...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

برای رفتن به نمایه دیگری با ICCID داده‌شده:

...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

برای دریافت نشانی پیش‌فرض SM-DP+ از تراشه eUICC:

...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
        callback);

برای بازیابی فهرست اعلان‌های رویدادهای اعلان ارائه‌شده:

...
cardMgr.listNotifications(eid,
        EuiccNotification.Event.INSTALL
              | EuiccNotification.Event.DELETE /* events */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

فعال کردن نمایه سیم‌کارت داخلی ازطریق برنامه شرکت مخابراتی

در دستگاه‌هایی که از Android 9 یا بالاتر استفاده می‌کنند، می‌توانید از برنامه شرکت مخابراتی برای فعال کردن سیم‌کارت داخلی و بارگیری کردن نمایه‌ها استفاده کنید. برنامه شرکت مخابراتی می‌تواند با تماس downloadSubscription مستقیم یا با ارائه کد فعال‌سازی به LPA، نمایه‌ها را بارگیری کند.

وقتی برنامه شرکت مخابراتی نمایه‌ای را با فراخوانی downloadSubscription بارگیری می‌کند، این فراخوانی الزام می‌کند که برنامه بتواند نمایه را ازطریق BF76 برچسب فراداده که قوانین امتیاز شرکت مخابراتی را برای نمایه کدگذاری می‌کند، مدیریت کند. اگر نمایه‌ای برچسب BF76 نداشته باشد یا اگر برچسب BF76 آن با امضای برنامه شرکت مخابراتی تماس‌گیرنده مطابقت نداشته باشد، بارگیری رد می‌شود.

بخش زیر نحوه فعال کردن سیم‌کارت داخلی ازطریق برنامه شرکت مخابراتی بااستفاده از کد فعال‌سازی را شرح می‌دهد.

فعال‌سازی سیم‌کارت داخلی بااستفاده از کد فعال‌سازی

وقتی از کد فعال‌سازی برای فعال کردن نمایه سیم‌کارت داخلی استفاده می‌کنید، LPA کد فعال‌سازی را از برنامه شرکت مخابراتی واکشی می‌کند و نمایه را بارگیری می‌کند. این جریان می‌تواند توسط LPA شروع شود و LPA می‌تواند کل جریان واسط کاربر را کنترل کند، یعنی واسط کاربر برنامه حامل نشان داده نمی‌شود. این رویکرد بررسی برچسب BF76 را دور می‌زند و اپراتورهای شبکه نیازی به پیاده‌سازی کل جریان واسط کاربر فعال‌سازی سیم‌کارت داخلی، ازجمله بارگیری نمایه سیم‌کارت داخلی و رسیدگی به خطا، ندارند.

تعریف کردن سرویس تدارک eUICC شرکت مخابراتی

‫LPA و برنامه شرکت مخابراتی ازطریق دو میانای AIDL با هم ارتباط برقرار می‌کنند: ICarrierEuiccProvisioningService و IGetActivationCodeCallback. برنامه شرکت مخابراتی باید میانای ICarrierEuiccProvisioningService را پیاده‌سازی کند و آن را در اعلامیه مانیفست خود نشان دهد. LPA باید به ICarrierEuiccProvisioningService متصل شود و IGetActivationCodeCallback را پیاده‌سازی کند. برای کسب اطلاعات بیشتر درباره نحوه پیاده‌سازی و نمایان کردن میانای AIDL، به تعریف میانای AIDL مراجعه کنید.

برای تعریف کردن میاناهای AIDL، فایل‌های AIDL زیر را برای هر دو برنامه LPA و شرکت مخابراتی ایجاد کنید.

  • ICarrierEuiccProvisioningService.aidl

    package android.service.euicc;
    
    import android.service.euicc.IGetActivationCodeCallback;
    
    oneway interface ICarrierEuiccProvisioningService {
        // The method to get the activation code from the carrier app. The caller needs to pass in
        // the implementation of IGetActivationCodeCallback as the parameter.
        void getActivationCode(in IGetActivationCodeCallback callback);
    
        // The method to get the activation code from the carrier app. The caller needs to pass in
        // the activation code string as the first parameter and the implementation of
        // IGetActivationCodeCallback as the second parameter. This method provides the carrier
        // app the device EID which allows a carrier to pre-bind a profile to the device's EID before
        // the download process begins.
        void getActivationCodeForEid(in String eid, in IGetActivationCodeCallback callback);
    }
    
    
  • IGetActivationCodeCallback.aidl

    package android.service.euicc;
    
    oneway interface IGetActivationCodeCallback {
        // The call back method needs to be called when the carrier app gets the activation
        // code successfully. The caller needs to pass in the activation code string as the
        // parameter.
        void onSuccess(String activationCode);
    
        // The call back method needs to be called when the carrier app failed to get the
        // activation code.
        void onFailure();
    }
    

مثال پیاده‌سازی LPA

برای اتصال به پیاده‌سازی ICarrierEuiccProvisioningService برنامه شرکت مخابراتی، LPA باید هم ICarrierEuiccProvisioningService.aidl و هم IGetActivationCodeCallback.aidl را در پروژه شما کپی کند و ServiceConnection را پیاده‌سازی کند.

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}

پس‌از اتصال به پیاده‌سازی ICarrierEuiccProvisioningService برنامه شرکت مخابراتی، LPA با ارسال پیاده‌سازی کلاس تهی‌نمونه IGetActivationCodeCallback، getActivationCode یا getActivationCodeForEid را فراخوانی می‌کند تا کد فعال‌سازی را از برنامه شرکت مخابراتی دریافت کند.

تفاوت بین getActivationCode و getActivationCodeForEid این است که getActivationCodeForEid به شرکت مخابراتی اجازه می‌دهد قبل‌از شروع فرایند بارگیری، نمایه‌ای را ازقبل به EID دستگاه پیوند دهد.

void getActivationCodeFromCarrierApp() {
    IGetActivationCodeCallback.Stub callback =
            new IGetActivationCodeCallback.Stub() {
                @Override
                public void onSuccess(String activationCode) throws RemoteException {
                    // Handle the case LPA success to get activation code from a carrier app.
                }

                @Override
                public void onFailure() throws RemoteException {
                    // Handle the case LPA failed to get activation code from a carrier app.
                }
            };
    
    try {
        mCarrierProvisioningService.getActivationCode(callback);
    } catch (RemoteException e) {
        // Handle Remote Exception
    }
}

نمونه پیاده‌سازی برای برنامه شرکت مخابراتی

برای اینکه LPA به برنامه شرکت مخابراتی ملحق شود، برنامه شرکت مخابراتی باید هر دو ICarrierEuiccProvisioningService.aidl و IGetActivationCodeCallback.aidl را در پروژه‌تان کپی کند و سرویس ICarrierEuiccProvisioningService را در فایل AndroidManifest.xml تعریف کند. این سرویس باید اجازه سیستم android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS را برای اطمینان از اینکه فقط LPA، یک برنامه دارای امتیاز سیستم، می‌تواند به آن متصل شود، درخواست کند. این سرویس باید فیلتر هدفی با کنش android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE نیز داشته باشد.

  • AndroidManifest.xml

    <application>
      ...
      <service
          android:name=".CarrierEuiccProvisioningService"
          android:exported="true"
          android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS">
        <intent-filter>
          <action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/>
        </intent-filter>
      </service>
      ...
    </application>
    

برای پیاده‌سازی سرویس برنامه شرکت مخابراتی AIDL، سرویسی ایجاد کنید، کلاس Stub را گسترش دهید، و روش‌های getActivationCode و getActivationCodeForEid را پیاده‌سازی کنید. سپس LPA می‌تواند هریک از این روش‌ها را برای واکشی کد فعال‌سازی نمایه فراخوانی کند. اگر کد با موفقیت از سرور شرکت مخابراتی واکشی شده باشد، برنامه شرکت مخابراتی باید با تماس با IGetActivationCodeCallback#onSuccess و ارائه کد فعال‌سازی پاسخ دهد. اگر ناموفق بود، برنامه شرکت مخابراتی باید با IGetActivationCodeCallback#onFailure پاسخ دهد.

  • CarrierEuiccProvisioningService.java

    import android.service.euicc.ICarrierEuiccProvisioningService;
    import android.service.euicc.ICarrierEuiccProvisioningService.Stub;
    import android.service.euicc.IGetActivationCodeCallback;
    
    public class CarrierEuiccProvisioningService extends Service {
        private final ICarrierEuiccProvisioningService.Stub binder =
            new Stub() {
              @Override
              public void getActivationCode(IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary to get an activation code (HTTP requests to carrier server, fetch from storage, etc.)
                callback.onSuccess(activationCode);
              }
    
              @Override
              public void getActivationCodeForEid(String eid, IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary (HTTP requests, fetch from storage, etc.)
                callback.onSuccess(activationCode);
              }
          }
    }
    

شروع کردن میانای کاربر برنامه شرکت مخابراتی در جریان فعال‌سازی LPA

در دستگاه‌های دارای Android 11 و نسخه‌های بالاتر، «عامل آماده‌سازی سیم‌کارت» می‌تواند میانای کاربر برنامه شرکت مخابراتی را راه‌اندازی کند. این ویژگی مفید است زیرا برنامه شرکت مخابراتی ممکن است قبل‌از ارائه کد فعال‌سازی به LPA، به اطلاعات بیشتری از کاربر نیاز داشته باشد. برای مثال، شرکت‌های مخابراتی ممکن است از کاربران بخواهند برای فعال کردن شماره تلفن‌هایشان یا انجام خدمات انتقال شماره، به سیستم وارد شوند.

این فرایند برای شروع کردن واسط کاربر برنامه شرکت مخابراتی در LPA است:

  1. «عامل آماده‌سازی نمایه» با ارسال android.service.euicc.action.START_CARRIER_ACTIVATION قصد به بسته برنامه شرکت مخابراتی حاوی کنش، جریان فعال‌سازی برنامه شرکت مخابراتی را راه‌اندازی می‌کند. (گیرنده برنامه شرکت مخابراتی باید در اعلامیه مانیفست با android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" محافظت شود تا از برنامه‌های غیر LPA هدف دریافت نکند.)

    String packageName = // The carrier app's package name
    
    Intent carrierAppIntent =
        new Intent(“android.service.euicc.action.START_CARRIER_ACTIVATION”)
            .setPackage(packageName);
    
    ResolveInfo activity =
        context.getPackageManager().resolveActivity(carrierAppIntent, 0);
    
    carrierAppIntent
        .setClassName(activity.activityInfo.packageName, activity.activityInfo.name);
    
    startActivityForResult(carrierAppIntent, requestCode);
    
  2. برنامه شرکت مخابراتی کارش را بااستفاده از واسط کاربر خودش انجام می‌دهد. برای مثال، ورود به سیستم کاربر یا ارسال درخواست‌های HTTP به زیرساخت شرکت مخابراتی.

  3. برنامه شرکت مخابراتی با تماس گرفتن با setResult(int, Intent) و finish() به LPA پاسخ می‌دهد.

    1. اگر برنامه شرکت مخابراتی با RESULT_OK پاسخ دهد، LPA جریان فعال‌سازی را ادامه می‌دهد. اگر برنامه شرکت مخابراتی تشخیص دهد که کاربر باید به‌جای اینکه «عامل آماده‌سازی محلی» سرویس برنامه شرکت مخابراتی را ملزم کند، رمزینه پاسخ‌سریع را اسکن کند، برنامه شرکت مخابراتی بااستفاده از setResult(int, Intent) با RESULT_OK و نمونه Intent حاوی افزونه منطقی android.telephony.euicc.extra.USE_QR_SCANNER که روی true تنظیم شده است به «عامل آماده‌سازی محلی» پاسخ می‌دهد. سپس LPA افزوده‌ها را بررسی می‌کند و به‌جای پیوند دادن پیاده‌سازی ICarrierEuiccProvisioningService برنامه شرکت مخابراتی، کدخوان پاسخ‌سریع را راه‌اندازی می‌کند.
    2. اگر برنامه شرکت مخابراتی ازکار بیفتد یا با RESULT_CANCELED پاسخ دهد (این کد پاسخ پیش‌فرض است)، LPA جریان فعال‌سازی سیم‌کارت داخلی را لغو می‌کند.
    3. اگر برنامه شرکت مخابراتی با چیزی غیراز RESULT_OK یا RESULT_CANCELED پاسخ دهد، LPA آن را به‌عنوان خطا درنظر می‌گیرد.

    به‌دلایل امنیتی، «برنامه مجاز سیم‌کارت» نباید مستقیماً کد فعال‌سازی ارائه‌شده در هدف نتیجه را بپذیرد تا مطمئن شود که تماس‌گیرندگان غیر «برنامه مجاز سیم‌کارت» نمی‌توانند کد فعال‌سازی را از برنامه شرکت مخابراتی دریافت کنند.

جاری‌سازی فعال‌سازی LPA را در برنامه حامل راه‌اندازی کنید

از Android 11، برنامه‌های شرکت مخابراتی می‌توانند از «میاناهای برنامه‌سازی کاربردی eUICC» برای شروع «واسط کاربر محلی» برای فعال‌سازی سیم‌کارت داخلی استفاده کنند. این روش واسط کاربر جریان فعال‌سازی سیم‌کارت داخلی LPA را برای فعال کردن نمایه سیم‌کارت داخلی نمایان می‌کند. سپس وقتی فعال‌سازی نمایه سیم‌کارت داخلی تمام شد، LPA همه‌فرستی ارسال می‌کند.

  1. «برنامه پشتیبانی از مکان» باید فعالیتی شامل فیلتر هدف با کنش android.service.euicc.action.START_EUICC_ACTIVATION اعلام کند. درصورتی‌که چندین پیاده‌سازی در دستگاه وجود داشته باشد، اولویت فیلتر هدف باید روی مقدار غیرصفر تنظیم شود. برای مثال:

    <application>
      ...
    <activity
        android:name=".CarrierAppInitActivity"
        android:exported="true">
    
        <intent-filter android:priority="100">
            <action android:name="android.service.euicc.action.START_EUICC_ACTIVATION" />
        </intent-filter>
    </activity>
      ...
    </application>
    
  2. برنامه شرکت مخابراتی کارش را بااستفاده از واسط کاربر خودش انجام می‌دهد. برای مثال، ورود به سیستم کاربر یا ارسال درخواست‌های HTTP به زیرساخت شرکت مخابراتی.

  3. در این مرحله، برنامه شرکت مخابراتی باید آماده ارائه کد فعال‌سازی ازطریق پیاده‌سازی ICarrierEuiccProvisioningService خود باشد. برنامه شرکت مخابراتی با فراخوانی startActivityForResult(Intent, int) با کنش android.telephony.euicc.action.START_EUICC_ACTIVATION، «دستیار نمایه محلی» را راه‌اندازی می‌کند. «دستیار برنامه‌ریز آگهی» همچنین مقدار بولی اضافی android.telephony.euicc.extra.USE_QR_SCANNER را بررسی می‌کند. اگر مقدار true باشد، LPA اسکنر QR را راه‌اندازی می‌کند تا کاربر بتواند رمزینه پاسخ‌سریع نمایه را اسکن کند.

  4. در سمت LPA،‏ LPA به پیاده‌سازی ICarrierEuiccProvisioningService برنامه شرکت مخابراتی متصل می‌شود تا کد فعال‌سازی را واکشی کند و نمایه مربوطه را بارگیری کند. «دستیار نصب برنامه» همه عناصر واسط کاربر ضروری را درطول بارگیری نمایش می‌دهد، مثلاً صفحه بارگیری.

  5. وقتی جریان فعال‌سازی LPA تکمیل می‌شود، LPA با کد نتیجه‌ای به برنامه شرکت مخابراتی پاسخ می‌دهد که برنامه شرکت مخابراتی آن را در onActivityResult(int, int, Intent) مدیریت می‌کند.

    1. اگر LPA در بارگیری نمایه سیم‌کارت داخلی جدید موفق شود، با RESULT_OK پاسخ می‌دهد.
    2. اگر کاربر فعال‌سازی نمایه سیم‌کارت داخلی را در LPA لغو کند، با RESULT_CANCELED پاسخ می‌دهد.
    3. اگر LPA با چیزی غیر از RESULT_OK یا RESULT_CANCELED پاسخ دهد، برنامه شرکت مخابراتی این را به‌عنوان خطا درنظر می‌گیرد.

    به‌دلایل امنیتی، «عامل آماده‌سازی نمایه» کد فعال‌سازی را مستقیماً در هدف ارائه‌شده نمی‌پذیرد تا مطمئن شود تماس‌گیرندگان غیر«عامل آماده‌سازی نمایه» نمی‌توانند کد فعال‌سازی را از برنامه شرکت مخابراتی دریافت کنند.

پشتیبانی از چند سیم‌کارت داخلی

برای دستگاه‌های دارای Android 10 یا بالاتر، کلاس EuiccManager از دستگاه‌های دارای چندین سیم‌کارت داخلی پشتیبانی می‌کند. دستگاه‌های دارای یک سیم‌کارت داخلی که به Android 10 ارتقا می‌یابند به هیچ تغییری در پیاده‌سازی LPA نیاز ندارند زیرا پلاتفرم به‌طور خودکار نمونه EuiccManager را با eUICC پیش‌فرض مرتبط می‌کند. eUICC پیش‌فرض توسط پلاتفرم برای دستگاه‌های دارای HAL رادیویی نسخه ۱.۲ یا بالاتر و توسط LPA برای دستگاه‌های دارای HAL رادیویی نسخه‌های پایین‌تر از ۱.۲ تعیین می‌شود.

الزامات

برای پشتیبانی از چند سیم‌کارت داخلی، دستگاه باید بیش‌از یک eUICC داشته باشد که می‌تواند eUICC داخلی یا جای سیم‌کارت فیزیکی باشد که در آن می‌توان eUICC قابل‌جدا شدن قرار داد.

برای پشتیبانی از چند سیم‌کارت داخلی، به نسخه ۱.۲ یا بالاتر از Radio HAL نیاز است. نسخه ۱.۴ از Radio HAL و نسخه ۱.۲ از RadioConfig HAL توصیه می‌شود.

پیاده‌سازی

برای پشتیبانی از چند سیم‌کارت داخلی (ازجمله eUICC قابل‌جابه‌جایی یا سیم‌کارت‌های برنامه‌پذیر)، «عامل آماده‌سازی محلی» باید EuiccService را پیاده‌سازی کند، که شناسه جایگاه مربوط به شناسه کارت ارائه‌شده توسط تماس‌گیرنده را دریافت می‌کند.

منبع non_removable_euicc_slots مشخص‌شده در arrays.xml آرایه‌ای از اعداد صحیح است که شناسه‌های شکاف eUICC داخلی دستگاه را نشان می‌دهد. باید این منبع را مشخص کنید تا به پلاتفرم اجازه دهید تعیین کند آیا سیم‌کارت داخلی درج‌شده قابل‌جدا شدن است یا نه.

برنامه شرکت مخابراتی برای دستگاه دارای چند سیم‌کارت داخلی

هنگام ساختن برنامه شرکت مخابراتی برای دستگاهی با چند سیم‌کارت داخلی، از روش createForCardId در EuiccManager برای ایجاد شیء EuiccManager که به شناسه کارت داده‌شده سنجاق شده است استفاده کنید. شناسه کارت مقدار عددی صحیحی است که UICC یا eUICC را در دستگاه به‌صورت یکتا شناسایی می‌کند.

برای دریافت شناسه کارت eUICC پیش‌فرض دستگاه، از روش getCardIdForDefaultEuicc در TelephonyManager استفاده کنید. اگر نسخه HAL رادیو پایین‌تر از ۱.۲ باشد، این روش UNSUPPORTED_CARD_ID را برمی‌گرداند و اگر دستگاه eUICC را نخوانده باشد، UNINITIALIZED_CARD_ID را برمی‌گرداند.

همچنین می‌توانید شناسه‌های کارت را از getUiccCardsInfo و getUiccSlotsInfo (میانای برنامه‌سازی کاربردی سیستم) در TelephonyManager، و getCardId در SubscriptionInfo دریافت کنید.

وقتی یک شیء EuiccManager با شناسه کارت خاصی نمونه‌سازی شده باشد، همه عملکردها به eUICC با آن شناسه کارت هدایت می‌شوند. اگر eUICC غیرقابل‌دسترس شود (برای مثال، وقتی خاموش یا برداشته شود)، EuiccManager دیگر کار نمی‌کند.

می‌توانید از نمونه کدهای زیر برای ایجاد برنامه شرکت مخابراتی استفاده کنید.

مثال ۱: دریافت اشتراک فعال و نمونه‌سازی EuiccManager

// Get the active subscription and instantiate an EuiccManager for the eUICC which holds
// that subscription
SubscriptionManager subMan = (SubscriptionManager)
        mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int cardId = subMan.getActiveSubscriptionInfo().getCardId();
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
            .createForCardId(cardId);

مثال ۲: تکرار UICCها و نمونه‌سازی EuiccManager برای eUICC جداشدنی

// On a device with a built-in eUICC and a removable eUICC, iterate through the UICC cards
// to instantiate an EuiccManager associated with a removable eUICC
TelephonyManager telMan = (TelephonyManager)
        mContext.getSystemService(Context.TELEPHONY_SERVICE);
List<UiccCardInfo> infos = telMan.getUiccCardsInfo();
int removableCardId = -1; // valid cardIds are 0 or greater
for (UiccCardInfo info : infos) {
    if (info.isRemovable()) {
        removableCardId = info.getCardId();
        break;
    }
}
if (removableCardId != -1) {
    EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
            .createForCardId(removableCardId);
}

اعتبارسنجی

AOSP با پیاده‌سازی LPA ارائه نمی‌شود و انتظار نمی‌رود که LPA در همه نسخه‌های Android دردسترس باشد (همه تلفن‌ها از سیم‌کارت داخلی پشتیبانی نمی‌کنند). به‌همین دلیل، هیچ مورد آزمایشی CTS سرتاسری وجود ندارد. بااین‌حال، چارچوب‌های تست پایه در «پروژه منبع باز Android» دردسترس است تا اطمینان حاصل شود که میاناهای برنامه‌سازی کاربردی eUICC نمایان‌شده در ساخت‌های Android معتبر هستند.

باید مطمئن شوید ساخت‌ها موارد آزمون «مجموعه آزمون سازگاری» زیر را بگذرانند (برای میاناهای برنامه‌سازی کاربردی عمومی): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts.

شرکت‌های مخابراتی که برنامه شرکت مخابراتی را پیاده‌سازی می‌کنند باید چرخه‌های عادی درون‌سازمانی تضمین کیفیت را طی کنند تا مطمئن شوند همه ویژگی‌های پیاده‌سازی‌شده طبق انتظار کار می‌کنند. حداقل، برنامه شرکت مخابراتی باید بتواند همه نمایه‌های اشتراک متعلق به همان شرکت مخابراتی را فهرست کند، نمایه‌ای را بارگیری و نصب کند، خدماتی را در نمایه فعال کند، بین نمایه‌ها جابه‌جا شود، و نمایه‌ها را حذف کند.

اگر خودتان درحال ساختن LPA هستید، باید آزمایش‌های بسیار دقیق‌تری انجام دهید. باید با فروشنده مودم، فروشنده تراشه eUICC یا سیستم‌عامل سیم‌کارت داخلی، فروشندگان SM-DP+‎، و شرکت‌های مخابراتی همکاری کنید تا مشکلات را برطرف کنید و از هم‌کنش‌پذیری LPA خود در معماری RSP مطمئن شوید. مقدار مناسبی از آزمایش دستی اجتناب‌ناپذیر است. برای داشتن بهترین پوشش آزمایشی، باید طرح آزمایشی GSMA SGP.23 RSP را دنبال کنید.