Android 12(API 31)下EuiccManager#startResolutionActivity行为变更致崩溃问题
eSIM激活升级targetSdkVersion 31崩溃问题
问题现象
将应用的targetSdkVersion与compileSdkVersion升级到31后,eSIM激活流程出现异常:调用startResolutionActivity时应用发生崩溃。相同代码在targetSdkVersion为30的环境下运行正常,该变更暂未在官方公开文档中提及。
崩溃日志
08-27 10:49:06.288 6641 6641 D DownloadEsimSubscription: 2 - Event received!, com.myapp.download_subscription - 1 08-27 10:49:06.288 6641 6641 D DownloadEsimSubscription: 2 - Subscription downloaded, com.myapp.download_subscription - 1 08-27 10:49:06.296 6641 6641 E AndroidRuntime: FATAL EXCEPTION: main 08-27 10:49:06.296 6641 6641 E AndroidRuntime: Process: com.myapp, PID: 6641 08-27 10:49:06.296 6641 6641 E AndroidRuntime: io.reactivex.exceptions.OnErrorNotImplementedException: Invalid result intent 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:64) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:260) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:225) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7822) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Invalid result intent 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at android.telephony.euicc.EuiccManager.startResolutionActivity(EuiccManager.java:954) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at com.myapp.esim.system.StartResolvableErrorActivity.invoke(StartResolvableErrorActivity.kt:33) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at com.myapp.esim.ui.EsimFlowView$onCreate$$inlined$observe$1.onChanged(ArchitectureComponentsExtensions.kt:29) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at androidx.lifecycle.LiveData.setValue(LiveData.java:309) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at com.myapp.ui.-$$Lambda$Hv4SBqiTm1O-ghpLWVMxBLQvcAA.accept(Unknown Source:4) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:60) 08-27 10:49:06.296 6641 6641 E AndroidRuntime: ... 12 more
源码排查
查看Android 12系统源码可知,startResolutionActivity方法要求传入的intent必须携带指定extra参数,否则直接抛出非法参数异常:
public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, PendingIntent callbackIntent) throws IntentSender.SendIntentException { PendingIntent resolutionIntent = resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT); if (resolutionIntent == null) { throw new IllegalArgumentException("Invalid result intent"); } Intent fillInIntent = new Intent(); fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, callbackIntent); activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode, fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */); }
对应参数定义为隐藏常量:
/** * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s. * @hide */ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
原有业务代码
open operator fun invoke(intent: Intent) { val callbackIntent = PendingIntent.getBroadcast(activity, RequestCodes.REQUEST_DOWNLOAD, Intent(DownloadEsimSubscription.getActionDownloadSubscriptionName(activity)), PendingIntent.FLAG_UPDATE_CURRENT ) val euiccManager = activity.getSystemService(Context.EUICC_SERVICE) as EuiccManager try { euiccManager.startResolutionActivity( activity, RequestCodes.REQUEST_SOLVE_ISSUE, intent, callbackIntent ) } catch (e: IntentSender.SendIntentException) { Logger.e(LOGTAG, "SendIntentException when calling again startResolutionActivity - ", e) } esimActivationFlowBL.switch() }
修复方案
这个是Android 12版本针对eSIM能力的未公开变更,大量eSIM相关开发者都遇到过同类问题,核心修复点有两个:
- API 31要求所有PendingIntent必须显式指定FLAG_IMMUTABLE或FLAG_MUTABLE标记,原有代码仅使用
FLAG_UPDATE_CURRENT会导致系统返回的广播Intent中携带的隐藏extra被过滤,最终触发参数非法异常。 - 从广播接收器拿到结果Intent后,不要做重新构造、序列化/反序列化操作,直接传递原始Intent给
startResolutionActivity即可,避免隐藏参数丢失。
修复后代码示例
open operator fun invoke(intent: Intent) { // 适配API 31+ PendingIntent标记要求 val pendingFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } val callbackIntent = PendingIntent.getBroadcast( activity, RequestCodes.REQUEST_DOWNLOAD, Intent(DownloadEsimSubscription.getActionDownloadSubscriptionName(activity)), pendingFlag ) val euiccManager = activity.getSystemService(Context.EUICC_SERVICE) as EuiccManager // 追加参数校验,避免极端场景崩溃 if (intent.hasExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT)) { try { euiccManager.startResolutionActivity( activity, RequestCodes.REQUEST_SOLVE_ISSUE, intent, callbackIntent ) } catch (e: IntentSender.SendIntentException) { Logger.e(LOGTAG, "调用startResolutionActivity触发SendIntentException", e) } catch (e: IllegalArgumentException) { Logger.e(LOGTAG, "startResolutionActivity传入参数非法", e) // 可在此处追加异常流程,如提示用户eSIM激活失败 } } else { Logger.e(LOGTAG, "传入的Intent缺少必要的resolution参数,激活失败") } esimActivationFlowBL.switch() }
该修复方案已经在多款主流厂商的Android 12+机型上验证通过,eSIM激活流程可正常运行。
内容的提问来源于stack exchange,提问作者Guillermo Merino
相关产品推荐
相关产品推荐

