Incedded_subscription_result_error на установке ESIM ⇐ Android
-
Anonymous
Incedded_subscription_result_error на установке ESIM
Я столкнулся с этой проблемой, специально для телефонов Xiaomi /Redmi. Вот чего я достиг до сих пор, < /p>
Я начал с того, что плагин Flutter_esim < /code>. Он использовал метод DownloadSubscription из Euiccmanager. По какой -то причине это продолжало сбое на нашем испытательном устройстве Samsung. Это сработало хорошо, за исключением устройств Xiaomi/Redmi. [Github Repo], 1 документация < /li>
На устройствах Xiaomi она вернула «activity.result_cancell`, даже не показывая какую -либо подсказку». Приложение сбоялось на телефон Redmi после того, как попросил пользователя «добавить ESIM», но ESIM установил на телефон. Это привело к ошибке incedded_subscription_result_error , хотя ESIM устанавливается на телефон, что является тем же поведением, что и другое приложение. /> mainactivity.kt
< /blockquote>
package com.pacakage.pacakage
import android.annotation.SuppressLint
import android.app.Activity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Bundle
import android.telephony.euicc.DownloadableSubscription
import android.telephony.euicc.EuiccManager
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterFragmentActivity() {
private val CHANNEL = "samples.flutter.dev/esim"
private val TAG = "MainActivity"
private val ACTION_DOWNLOAD_SUBSCRIPTION = "com.pacakage.esim.DOWNLOAD_RESULT"
private val REQUEST_CODE_INSTALL = 9999
private var methodResult: MethodChannel.Result? = null
private lateinit var euiccManager: EuiccManager
private lateinit var downloadReceiver: BroadcastReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
euiccManager = getSystemService(EuiccManager::class.java) ?: throw IllegalStateException("EUICC not available")
// Initialize the broadcast receiver
downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (ACTION_DOWNLOAD_SUBSCRIPTION != intent.action) {
return
}
when (resultCode) {
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR -> {
Log.d(TAG, "Resolvable error encountered")
handleResolvableError(intent)
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK -> {
Log.d(TAG, "eSIM installation successful (via broadcast)")
methodResult?.success("Installation successful")
methodResult = null
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> {
Log.e(TAG, "eSIM installation failed (via broadcast)")
methodResult?.error(
"ESIM_INSTALLATION_ERROR",
"EMBEDDED_SUBSCRIPTION_RESULT_ERROR",
null
)
methodResult = null
}
else -> {
Log.e(TAG, "Unknown result code from broadcast: $resultCode")
methodResult?.error(
"UNKNOWN_ERROR",
"Unknown error occurred (result code: $resultCode)",
null
)
methodResult = null
}
}
}
}
}
@SuppressLint("UnspecifiedRegisterReceiverFlag")
override fun onResume() {
super.onResume()
// Register the receiver
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(
downloadReceiver,
IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
Context.RECEIVER_NOT_EXPORTED
)
} else {
registerReceiver(
downloadReceiver,
IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION)
)
}
}
override fun onPause() {
super.onPause()
// Unregister the receiver to avoid leaks
try {
unregisterReceiver(downloadReceiver)
} catch (e: IllegalArgumentException) {
// Receiver was not registered, ignore
}
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "launchESimSetup") {
handleEsimSetupCall(call, result)
} else {
result.notImplemented()
}
}
}
private fun handleEsimSetupCall(call: MethodCall, result: MethodChannel.Result) {
if (methodResult != null) {
result.error("ALREADY_IN_PROGRESS", "Another eSIM installation is already in progress", null)
return
}
try {
methodResult = result
val activationCode = (call.arguments as? HashMap)?.values?.first()?.toString()
?: throw IllegalArgumentException("Invalid activation code")
launchESimSetup(activationCode)
} catch (e: Exception) {
Log.e(TAG, "Error handling method call", e)
result.error("METHOD_CALL_ERROR", e.message ?: "Unknown error occurred while processing method call", null)
methodResult = null
}
}
private fun launchESimSetup(activationCode: String) {
try {
if (isXiaomiOrRedmi()) {
Log.d(TAG, "Using direct download for Xiaomi/Redmi")
downloadSubscriptionDirectly(activationCode)
} else {
Log.d(TAG, "Using standard activation flow")
startStandardActivation(activationCode)
}
} catch (e: Exception) {
Log.e(TAG, "launchESimSetup error", e)
methodResult?.error("ESIM_LAUNCH_ERROR", e.message ?: "Failed to launch eSIM installation", null)
methodResult = null
}
}
private fun isXiaomiOrRedmi(): Boolean {
return Build.MANUFACTURER.equals("xiaomi", ignoreCase = true) ||
Build.BRAND.equals("redmi", ignoreCase = true) ||
Build.BRAND.equals("xiaomi", ignoreCase = true)
}
private fun startStandardActivation(activationCode: String) {
val intent = Intent(EuiccManager.ACTION_START_EUICC_ACTIVATION).apply {
putExtra(EuiccManager.EXTRA_USE_QR_SCANNER, false)
}
EsimActivationCodeManager().setLpa(activationCode)
eSimInstallLauncher.launch(intent)
}
private fun downloadSubscriptionDirectly(activationCode: String) {
try {
val subscription = DownloadableSubscription.forActivationCode(activationCode)
val callbackIntent = createDownloadPendingIntent()
euiccManager.downloadSubscription(
subscription,
true, // switch after download
callbackIntent
)
} catch (e: Exception) {
Log.e(TAG, "Direct download failed", e)
methodResult?.error("ESIM_INSTALLATION_ERROR", "Direct download failed: ${e.message}", null)
methodResult = null
}
}
private fun createDownloadPendingIntent(): PendingIntent {
val intent = Intent(ACTION_DOWNLOAD_SUBSCRIPTION).apply {
`package` = packageName
}
return PendingIntent.getBroadcast(
this,
REQUEST_CODE_INSTALL,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
}
private fun handleResolvableError(intent: Intent) {
try {
val callbackIntent = createDownloadPendingIntent()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
euiccManager.startResolutionActivity(
this,
REQUEST_CODE_INSTALL,
intent,
callbackIntent
)
} else {
methodResult?.error(
"RESOLVABLE_ERROR_NOT_SUPPORTED",
"Resolvable errors require Android P or higher",
null
)
methodResult = null
}
} catch (e: Exception) {
Log.e(TAG, "Error handling resolvable error", e)
methodResult?.error(
"RESOLUTION_ERROR",
"Failed to handle resolvable error: ${e.message}",
null
)
methodResult = null
}
}
private val eSimInstallLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
try {
when (result.resultCode) {
Activity.RESULT_OK -> {
Log.d(TAG, "eSIM installation successful")
methodResult?.success("Installation successful")
}
Activity.RESULT_CANCELED -> {
Log.w(TAG, "eSIM installation was cancelled by user")
methodResult?.error(
"ESIM_INSTALLATION_CANCELLED",
"User cancelled the eSIM installation",
null
)
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> {
Log.e(TAG, "EMBEDDED_SUBSCRIPTION_RESULT_ERROR")
methodResult?.error(
"ESIM_INSTALLATION_ERROR",
"EMBEDDED_SUBSCRIPTION_RESULT_ERROR",
null
)
}
else -> {
Log.e(TAG, "Unknown result code: ${result.resultCode}")
methodResult?.error(
"UNKNOWN_ERROR",
"Unknown error occurred (result code: ${result.resultCode})",
null
)
}
}
} catch (e: Exception) {
Log.e(TAG, "Error handling activity result", e)
methodResult?.error(
"RESULT_HANDLING_ERROR",
e.message ?: "Error occurred while processing the result",
null
)
} finally {
methodResult = null
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.action == ACTION_DOWNLOAD_SUBSCRIPTION) {
Log.d(TAG, "Received download result intent")
}
}
}
< /code>
android manifest.xml
< /blockquote>
carriereuiccprovisioningservice < /strong> < /p>
< /code>
androidmanifest.xml
< /blockquote>
разрешения < /strong> < /p>
Подробнее здесь: https://stackoverflow.com/questions/796 ... stallation
Я столкнулся с этой проблемой, специально для телефонов Xiaomi /Redmi. Вот чего я достиг до сих пор, < /p>
Я начал с того, что плагин Flutter_esim < /code>. Он использовал метод DownloadSubscription из Euiccmanager. По какой -то причине это продолжало сбое на нашем испытательном устройстве Samsung. Это сработало хорошо, за исключением устройств Xiaomi/Redmi. [Github Repo], 1 документация < /li>
На устройствах Xiaomi она вернула «activity.result_cancell`, даже не показывая какую -либо подсказку». Приложение сбоялось на телефон Redmi после того, как попросил пользователя «добавить ESIM», но ESIM установил на телефон. Это привело к ошибке incedded_subscription_result_error , хотя ESIM устанавливается на телефон, что является тем же поведением, что и другое приложение. /> mainactivity.kt
< /blockquote>
package com.pacakage.pacakage
import android.annotation.SuppressLint
import android.app.Activity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Bundle
import android.telephony.euicc.DownloadableSubscription
import android.telephony.euicc.EuiccManager
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterFragmentActivity() {
private val CHANNEL = "samples.flutter.dev/esim"
private val TAG = "MainActivity"
private val ACTION_DOWNLOAD_SUBSCRIPTION = "com.pacakage.esim.DOWNLOAD_RESULT"
private val REQUEST_CODE_INSTALL = 9999
private var methodResult: MethodChannel.Result? = null
private lateinit var euiccManager: EuiccManager
private lateinit var downloadReceiver: BroadcastReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
euiccManager = getSystemService(EuiccManager::class.java) ?: throw IllegalStateException("EUICC not available")
// Initialize the broadcast receiver
downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (ACTION_DOWNLOAD_SUBSCRIPTION != intent.action) {
return
}
when (resultCode) {
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR -> {
Log.d(TAG, "Resolvable error encountered")
handleResolvableError(intent)
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK -> {
Log.d(TAG, "eSIM installation successful (via broadcast)")
methodResult?.success("Installation successful")
methodResult = null
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> {
Log.e(TAG, "eSIM installation failed (via broadcast)")
methodResult?.error(
"ESIM_INSTALLATION_ERROR",
"EMBEDDED_SUBSCRIPTION_RESULT_ERROR",
null
)
methodResult = null
}
else -> {
Log.e(TAG, "Unknown result code from broadcast: $resultCode")
methodResult?.error(
"UNKNOWN_ERROR",
"Unknown error occurred (result code: $resultCode)",
null
)
methodResult = null
}
}
}
}
}
@SuppressLint("UnspecifiedRegisterReceiverFlag")
override fun onResume() {
super.onResume()
// Register the receiver
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(
downloadReceiver,
IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
Context.RECEIVER_NOT_EXPORTED
)
} else {
registerReceiver(
downloadReceiver,
IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION)
)
}
}
override fun onPause() {
super.onPause()
// Unregister the receiver to avoid leaks
try {
unregisterReceiver(downloadReceiver)
} catch (e: IllegalArgumentException) {
// Receiver was not registered, ignore
}
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "launchESimSetup") {
handleEsimSetupCall(call, result)
} else {
result.notImplemented()
}
}
}
private fun handleEsimSetupCall(call: MethodCall, result: MethodChannel.Result) {
if (methodResult != null) {
result.error("ALREADY_IN_PROGRESS", "Another eSIM installation is already in progress", null)
return
}
try {
methodResult = result
val activationCode = (call.arguments as? HashMap)?.values?.first()?.toString()
?: throw IllegalArgumentException("Invalid activation code")
launchESimSetup(activationCode)
} catch (e: Exception) {
Log.e(TAG, "Error handling method call", e)
result.error("METHOD_CALL_ERROR", e.message ?: "Unknown error occurred while processing method call", null)
methodResult = null
}
}
private fun launchESimSetup(activationCode: String) {
try {
if (isXiaomiOrRedmi()) {
Log.d(TAG, "Using direct download for Xiaomi/Redmi")
downloadSubscriptionDirectly(activationCode)
} else {
Log.d(TAG, "Using standard activation flow")
startStandardActivation(activationCode)
}
} catch (e: Exception) {
Log.e(TAG, "launchESimSetup error", e)
methodResult?.error("ESIM_LAUNCH_ERROR", e.message ?: "Failed to launch eSIM installation", null)
methodResult = null
}
}
private fun isXiaomiOrRedmi(): Boolean {
return Build.MANUFACTURER.equals("xiaomi", ignoreCase = true) ||
Build.BRAND.equals("redmi", ignoreCase = true) ||
Build.BRAND.equals("xiaomi", ignoreCase = true)
}
private fun startStandardActivation(activationCode: String) {
val intent = Intent(EuiccManager.ACTION_START_EUICC_ACTIVATION).apply {
putExtra(EuiccManager.EXTRA_USE_QR_SCANNER, false)
}
EsimActivationCodeManager().setLpa(activationCode)
eSimInstallLauncher.launch(intent)
}
private fun downloadSubscriptionDirectly(activationCode: String) {
try {
val subscription = DownloadableSubscription.forActivationCode(activationCode)
val callbackIntent = createDownloadPendingIntent()
euiccManager.downloadSubscription(
subscription,
true, // switch after download
callbackIntent
)
} catch (e: Exception) {
Log.e(TAG, "Direct download failed", e)
methodResult?.error("ESIM_INSTALLATION_ERROR", "Direct download failed: ${e.message}", null)
methodResult = null
}
}
private fun createDownloadPendingIntent(): PendingIntent {
val intent = Intent(ACTION_DOWNLOAD_SUBSCRIPTION).apply {
`package` = packageName
}
return PendingIntent.getBroadcast(
this,
REQUEST_CODE_INSTALL,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
}
private fun handleResolvableError(intent: Intent) {
try {
val callbackIntent = createDownloadPendingIntent()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
euiccManager.startResolutionActivity(
this,
REQUEST_CODE_INSTALL,
intent,
callbackIntent
)
} else {
methodResult?.error(
"RESOLVABLE_ERROR_NOT_SUPPORTED",
"Resolvable errors require Android P or higher",
null
)
methodResult = null
}
} catch (e: Exception) {
Log.e(TAG, "Error handling resolvable error", e)
methodResult?.error(
"RESOLUTION_ERROR",
"Failed to handle resolvable error: ${e.message}",
null
)
methodResult = null
}
}
private val eSimInstallLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
try {
when (result.resultCode) {
Activity.RESULT_OK -> {
Log.d(TAG, "eSIM installation successful")
methodResult?.success("Installation successful")
}
Activity.RESULT_CANCELED -> {
Log.w(TAG, "eSIM installation was cancelled by user")
methodResult?.error(
"ESIM_INSTALLATION_CANCELLED",
"User cancelled the eSIM installation",
null
)
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR -> {
Log.e(TAG, "EMBEDDED_SUBSCRIPTION_RESULT_ERROR")
methodResult?.error(
"ESIM_INSTALLATION_ERROR",
"EMBEDDED_SUBSCRIPTION_RESULT_ERROR",
null
)
}
else -> {
Log.e(TAG, "Unknown result code: ${result.resultCode}")
methodResult?.error(
"UNKNOWN_ERROR",
"Unknown error occurred (result code: ${result.resultCode})",
null
)
}
}
} catch (e: Exception) {
Log.e(TAG, "Error handling activity result", e)
methodResult?.error(
"RESULT_HANDLING_ERROR",
e.message ?: "Error occurred while processing the result",
null
)
} finally {
methodResult = null
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.action == ACTION_DOWNLOAD_SUBSCRIPTION) {
Log.d(TAG, "Received download result intent")
}
}
}
< /code>
android manifest.xml
< /blockquote>
carriereuiccprovisioningservice < /strong> < /p>
< /code>
androidmanifest.xml
< /blockquote>
разрешения < /strong> < /p>
Подробнее здесь: https://stackoverflow.com/questions/796 ... stallation
Мобильная версия