Для этого я создал EsimHandler. Здесь вы можете увидеть:
Код: Выделить всё
import android.app.Activity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.telephony.TelephonyManager
import android.telephony.euicc.DownloadableSubscription
import android.telephony.euicc.EuiccManager
import android.util.Log
import androidx.annotation.RequiresApi
import kotlinx.coroutines.*
private const val ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription"
private const val TAG_ESIM = "TAG_ESIM"
class EsimHandler {
private lateinit var onEsimDownloadListener: OnEsimDownloadListener
private val receiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.P)
override fun onReceive(context: Context?, intent: Intent?) {
val resultCode = resultCode
when (resultCode) {
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK -> {
/*Download profile was successful*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// eSim is active
onEsimDownloadListener.onResultOK()
} else {
// eSim is inactive due to the SDK does not support this API level
onEsimDownloadListener.onResultError()
}
}
EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR -> {
/*Download profile was not successful but resolvable*/
onEsimDownloadListener.onResultResolvableError()
val mgr = context?.getSystemService(Context.EUICC_SERVICE) as EuiccManager
handleResolvableError(context, intent!!, mgr)
}
else -> { /*Download profile was not successful*/
onEsimDownloadListener.onResultError()
}
}
}
}
fun init(param: OnEsimDownloadListener) {
this.onEsimDownloadListener = param
}
@OptIn(DelicateCoroutinesApi::class)
@RequiresApi(Build.VERSION_CODES.P)
fun downloadEsim(context: Context, code: String) {
/*
if (!checkCarrierPrivileges(context)) {
onEsimDownloadListener.onCheckCarrierPrivilegesFailure()
return
}
*/
val mgr = context.getSystemService(Context.EUICC_SERVICE) as EuiccManager
if (!mgr.isEnabled) {
onEsimDownloadListener.onMgrIsEnabledFailure()
return
}
// Download subscription asynchronously
val sub = DownloadableSubscription.forActivationCode(code)
val intent = Intent(ACTION_DOWNLOAD_SUBSCRIPTION)
val callbackIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT)
} else {
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_MUTABLE)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.registerReceiver(receiver, IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION), Context.RECEIVER_NOT_EXPORTED)
} else {
context.registerReceiver(
receiver, IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
null, null
)
}
GlobalScope.launch {
withContext(Dispatchers.Main) {
try {
mgr.downloadSubscription(sub, true, callbackIntent)
} catch (e: Exception) {
onEsimDownloadListener.onResultError()
}
}
}
}
// Checks for carrier privileges on the device
private fun checkCarrierPrivileges(context: Context): Boolean {
val telephonyManager =
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val isCarrier = telephonyManager.hasCarrierPrivileges()
return if (isCarrier) {
Log.i(TAG_ESIM, "Ready with carrier privileges")
true
} else {
Log.i(TAG_ESIM, "No carrier privileges detected")
false
}
}
@RequiresApi(api = Build.VERSION_CODES.P)
private fun handleResolvableError(context: Context, intent: Intent, mgr: EuiccManager) {
try {
// Resolvable error, attempt to resolve it by a user action
val resolutionRequestCode = 3
val callbackIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
PendingIntent.getBroadcast(context, resolutionRequestCode, Intent(ACTION_DOWNLOAD_SUBSCRIPTION), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT)
} else {
PendingIntent.getBroadcast(context, resolutionRequestCode, Intent(ACTION_DOWNLOAD_SUBSCRIPTION), PendingIntent.FLAG_MUTABLE)
}
mgr.startResolutionActivity(
context.activity(),
resolutionRequestCode,
intent,
callbackIntent
)
} catch (e: Exception) {
onEsimDownloadListener.onResultError()
Log.d(TAG_ESIM,
"EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR - Can't setup eSim due to Activity error "
+ e.localizedMessage
)
}
}
private fun Context.activity(): Activity? = when {
this is Activity -> this
else -> (this as? ContextWrapper)?.baseContext?.activity()
}
}
Я на 100% уверен, что мой профиль eSIM имеет привилегии оператора связи, потому что я могу установить eSIM на свой Google Pixel 7а аппарат с Андроид 13 отлично. Но проблема в том, что я не могу установить тот же профиль eSIM на свой Samsung Galaxy S23 с Android 14.
Пока я пытаюсь установить Профиль eSIM на устройстве Google Pixel 7a с Android 13. После запуска метода downloadEsim он присоединяется к устранимой ошибке. Затем я вижу эти журналы:
Код: Выделить всё
EuiccController com.android.phone I isCompatChangeEnabled changeId: SOME_ID_HERE_BLABLA changeEnabled: true
EuiccController com.android.phone D downloadSubscription cardId: 0 switchAfterDownload: true portIndex: 0 forceDeactivateSim: false callingPackage: com.myapp.myapp isConsentNeededToResolvePortIndex: false shouldResolvePortIndex:true
EuiccController com.android.phone I Caller can't manage subscription on target SIM or User consent is required for resolving port index. Ask user's consent first
[img]https://i.sstatic .net/ToMlDAJj.png[/img]
Я нажимаю "Да" и вижу эти журналы:
Код: Выделить всё
EuiccController com.android.phone I continueOperation portIndex: 0 usePortIndex: true
EuiccController com.android.phone D downloadSubscriptionPrivilegedCheckMetadata cardId: 0 switchAfterDownload: true portIndex: 0 forceDeactivateSim: true
Код: Выделить всё
EuiccController com.android.phone I Calling package has carrier privilege to this profile
Когда я пытаюсь установить профиль eSIM на Samsung Galaxy S23 с Android 14, после запуска метода downloadEsim я вижу следующие журналы:
Код: Выделить всё
EuiccController com.android.phone I isCompatChangeEnabled changeId: SOME_ID_HERE_BLABLA changeEnabled: true
EuiccController com.android.phone I No UiccSlotInfo found for cardId: 0
EuiccController com.android.phone D Switch to inactive slot, return default port index. slotIndex: -1
EuiccController com.android.phone D downloadSubscription cardId: 0 switchAfterDownload: true portIndex: 0 forceDeactivateSim: false callingPackage: com.myapp.myapp isConsentNeededToResolvePortIndex: false shouldResolvePortIndex:true
EuiccController com.android.phone D euiccController phoneId: 1
EuiccController com.android.phone E Calling package doesn't have carrier privilege to this profile
EuiccController com.android.phone I The target SIM is not an eUICC.
EuiccController com.android.phone I Caller can't manage subscription on target SIM or User consent is required for resolving port index. Ask user's consent first
EuiccController com.android.phone I The target SIM is not an eUICC.
EuiccController com.android.phone I euiccController add EuiccService.NO_PRIVILEGED
Я попробовал использовать эту официальную ссылку, но ничего не происходит.
Эти строки уже добавлено в мой файл манифеста:
Код: Выделить всё
Подробнее здесь: https://stackoverflow.com/questions/787 ... nt-devices