From cce247e74754d8579934d198aee1e76134ae0e6b Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sun, 7 Sep 2025 14:56:09 -0400 Subject: [PATCH 1/4] feat: Display simplified error messages when profile downloading fails i18n pending Co-Authored-By: septs --- .../wizard/DownloadWizardProgressFragment.kt | 55 ++++++- .../ui/wizard/SimplifiedErrorMessages.kt | 154 ++++++++++++++++++ .../res/layout/download_progress_item.xml | 58 +++++-- app-common/src/main/res/values/strings.xml | 21 +++ 4 files changed, 269 insertions(+), 19 deletions(-) create mode 100644 app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt index 342a687..29e87b0 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt @@ -43,18 +43,36 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep private data class ProgressItem( val titleRes: Int, - var state: ProgressState + var state: ProgressState, + var errorMessage: SimplifiedErrorMessages?, ) private val progressItems = arrayOf( - ProgressItem(R.string.download_wizard_progress_step_preparing, ProgressState.NotStarted), - ProgressItem(R.string.download_wizard_progress_step_connecting, ProgressState.NotStarted), + ProgressItem( + R.string.download_wizard_progress_step_preparing, + ProgressState.NotStarted, + null + ), + ProgressItem( + R.string.download_wizard_progress_step_connecting, + ProgressState.NotStarted, + null + ), ProgressItem( R.string.download_wizard_progress_step_authenticating, - ProgressState.NotStarted + ProgressState.NotStarted, + null ), - ProgressItem(R.string.download_wizard_progress_step_downloading, ProgressState.NotStarted), - ProgressItem(R.string.download_wizard_progress_step_finalizing, ProgressState.NotStarted) + ProgressItem( + R.string.download_wizard_progress_step_downloading, + ProgressState.NotStarted, + null + ), + ProgressItem( + R.string.download_wizard_progress_step_finalizing, + ProgressState.NotStarted, + null + ) ) private val adapter = ProgressItemAdapter() @@ -122,8 +140,13 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep // Change the state of the last InProgress item to success (or error) progressItems.forEachIndexed { index, progressItem -> if (progressItem.state == ProgressState.InProgress) { - progressItem.state = - if (state.downloadError == null) ProgressState.Done else ProgressState.Error + if (state.downloadError == null) { + progressItem.state = ProgressState.Done + } else { + progressItem.state = ProgressState.Error + progressItem.errorMessage = + SimplifiedErrorMessages.fromDownloadError(state.downloadError!!) + } } adapter.notifyItemChanged(index) @@ -197,9 +220,15 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep private val progressBar = root.requireViewById(R.id.download_progress_icon_progress) private val icon = root.requireViewById(R.id.download_progress_icon) + private val errorTitle = + root.requireViewById(R.id.download_progress_item_error_title) + private val errorSuggestion = + root.requireViewById(R.id.download_progress_item_error_suggestion) fun bind(item: ProgressItem) { title.text = getString(item.titleRes) + errorTitle.visibility = View.GONE + errorSuggestion.visibility = View.GONE when (item.state) { ProgressState.NotStarted -> { @@ -222,6 +251,16 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep progressBar.visibility = View.GONE icon.setImageResource(R.drawable.ic_error_outline) icon.visibility = View.VISIBLE + + if (item.errorMessage != null) { + errorTitle.visibility = View.VISIBLE + errorTitle.text = getString(item.errorMessage!!.titleResId) + + if (item.errorMessage!!.suggestResId != null) { + errorSuggestion.visibility = View.VISIBLE + errorSuggestion.text = getString(item.errorMessage!!.suggestResId!!) + } + } } } } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt new file mode 100644 index 0000000..8ce5740 --- /dev/null +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt @@ -0,0 +1,154 @@ +package im.angry.openeuicc.ui.wizard + +import androidx.annotation.StringRes +import im.angry.openeuicc.common.R +import net.typeblog.lpac_jni.LocalProfileAssistant +import org.json.JSONObject +import java.net.NoRouteToHostException +import java.net.PortUnreachableException +import java.net.SocketException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import javax.net.ssl.SSLException + +enum class SimplifiedErrorMessages( + @StringRes val titleResId: Int, + @StringRes val suggestResId: Int? +) { + ICCIDAlreadyInUse( + R.string.download_wizard_error_iccid_already, + R.string.download_wizard_error_suggest_profile_installed + ), + InsufficientMemory( + R.string.download_wizard_error_insufficient_memory, + R.string.download_wizard_error_suggest_insufficient_memory + ), + UnsupportedProfile( + R.string.download_wizard_error_unsupported_profile, + null + ), + CardInternalError( + R.string.download_wizard_error_card_internal_error, + null + ), + EIDNotSupported( + R.string.download_wizard_error_eid_not_supported, + R.string.download_wizard_error_suggest_contact_carrier + ), + EIDMismatch( + R.string.download_wizard_error_eid_mismatch, + R.string.download_wizard_error_suggest_contact_reissue + ), + UnreleasedProfile( + R.string.download_wizard_error_profile_unreleased, + R.string.download_wizard_error_suggest_contact_reissue + ), + MatchingIDRefused( + R.string.download_wizard_error_matching_id_refused, + R.string.download_wizard_error_suggest_contact_carrier + ), + ProfileRetriesExceeded( + R.string.download_wizard_error_profile_retries_exceeded, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeMissing( + R.string.download_wizard_error_confirmation_code_missing, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeRefused( + R.string.download_wizard_error_confirmation_code_refused, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeRetriesExceeded( + R.string.download_wizard_error_confirmation_code_retries_exceeded, + R.string.download_wizard_error_suggest_contact_carrier + ), + ProfileExpired( + R.string.download_wizard_error_profile_expired, + R.string.download_wizard_error_suggest_contact_carrier + ), + UnknownHost( + R.string.download_wizard_error_unknown_hostname, + null + ), + NetworkUnreachable( + R.string.download_wizard_error_network_unreachable, + R.string.download_wizard_error_suggest_network_unreachable + ), + TLSError( + R.string.download_wizard_error_tls_certificate, + null + ); + + companion object { + private val httpErrors = buildMap { + // Stage: AuthenticateClient + put("8.1" to "4.8", InsufficientMemory) + put("8.1.1" to "2.1", EIDNotSupported) + put("8.1.1" to "3.8", EIDMismatch) + put("8.2" to "1.2", UnreleasedProfile) + put("8.2.6" to "3.8", MatchingIDRefused) + put("8.8.5" to "6.4", ProfileRetriesExceeded) + + // Stage: GetBoundProfilePackage + put("8.2.7" to "2.2", ConfirmationCodeMissing) + put("8.2.7" to "3.8", ConfirmationCodeRefused) + put("8.2.7" to "6.4", ConfirmationCodeRetriesExceeded) + + // Stage: AuthenticateClient, GetBoundProfilePackage + put("8.8.5" to "4.10", ProfileExpired) + } + + fun fromDownloadError(exc: LocalProfileAssistant.ProfileDownloadException) = when { + exc.lpaErrorReason != "ES10B_ERROR_REASON_UNDEFINED" -> fromLPAErrorReason(exc.lpaErrorReason) + exc.lastHttpResponse?.rcode == 200 -> fromHTTPResponse(exc.lastHttpResponse!!) + exc.lastHttpException != null -> fromHTTPException(exc.lastHttpException!!) + exc.lastApduResponse != null -> fromAPDUResponse(exc.lastApduResponse!!) + else -> null + } + + private fun fromLPAErrorReason(reason: String) = when (reason) { + "ES10B_ERROR_REASON_UNSUPPORTED_CRT_VALUES" -> UnsupportedProfile + "ES10B_ERROR_REASON_UNSUPPORTED_REMOTE_OPERATION_TYPE" -> UnsupportedProfile + "ES10B_ERROR_REASON_UNSUPPORTED_PROFILE_CLASS" -> UnsupportedProfile + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_ICCID_ALREADY_EXISTS_ON_EUICC" -> ICCIDAlreadyInUse + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_INSUFFICIENT_MEMORY_FOR_PROFILE" -> InsufficientMemory + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_INTERRUPTION" -> CardInternalError + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_PE_PROCESSING_ERROR" -> CardInternalError + else -> null + } + + private fun fromHTTPResponse(httpResponse: net.typeblog.lpac_jni.HttpInterface.HttpResponse): SimplifiedErrorMessages? { + if (httpResponse.data.first().toInt() != '{'.code) return null + val response = JSONObject(httpResponse.data.decodeToString()) + val statusCodeData = response.optJSONObject("header") + ?.optJSONObject("functionExecutionStatus") + ?.optJSONObject("statusCodeData") + ?: return null + val subjectCode = statusCodeData.optString("subjectCode") + val reasonCode = statusCodeData.optString("reasonCode") + return httpErrors[subjectCode to reasonCode] + } + + private fun fromHTTPException(exc: Exception) = when (exc) { + is SSLException -> TLSError + is UnknownHostException -> UnknownHost + is NoRouteToHostException -> NetworkUnreachable + is PortUnreachableException -> NetworkUnreachable + is SocketTimeoutException -> NetworkUnreachable + is SocketException -> exc.message + ?.contains("Connection reset", ignoreCase = true) + ?.let { if (it) NetworkUnreachable else null } + + else -> null + } + + private fun fromAPDUResponse(resp: ByteArray): SimplifiedErrorMessages? { + val isSuccess = resp.size >= 2 && + resp[resp.size - 2] == 0x90.toByte() && + resp[resp.size - 1] == 0x00.toByte() + if (isSuccess) return null + return CardInternalError + } + } +} diff --git a/app-common/src/main/res/layout/download_progress_item.xml b/app-common/src/main/res/layout/download_progress_item.xml index f1d0852..c59673b 100644 --- a/app-common/src/main/res/layout/download_progress_item.xml +++ b/app-common/src/main/res/layout/download_progress_item.xml @@ -1,30 +1,32 @@ + android:layout_height="wrap_content"> + app:layout_constraintBottom_toBottomOf="@id/download_progress_icon_container" + app:layout_constraintEnd_toStartOf="@id/download_progress_icon_container" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@id/download_progress_icon_container" + app:layout_constraintVertical_bias="0.5" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.0"> + + + + \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index ae0700b..3a9dda3 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -104,6 +104,27 @@ Last APDU exception: Save Diagnostics at %s + This eSIM profile is already present on your eSIM chip. + Your eSIM chip does not have sufficient memory left to download the profile. + This eSIM profile is unsupported by your eSIM chip. + An error occurred in your eSIM chip. + The EID of your device or eSIM chip is unsupported by your carrier. + This eSIM profile has been downloaded on another device. + This eSIM profile has been revoked. + The activation code is invalid. + The maximum number of download attempts for the eSIM profile has been exceeded. + Confirmation code is required to download this profile. + The confirmation code you entered is invalid. + This eSIM profile has expired. + The maximum number of download attempts for the confirmation code has been exceeded. + Unknown SM-DP+ address + Network is unreachable + TLS certificate error, this eSIM profile is not supported + You are trying to reinstall an already downloaded eSIM profile + Please delete some unused eSIM profiles and try again + Please contact your carrier for assistance. + Please contact your carrier to reissue this eSIM profile. + Please try again after connecting to a different network (e.g. switching between Wi-Fi and data). Logs have been saved to the selected path. Would you like to share the log through another app? From 7bae82daf9104c5682566cdeaf0dafb1cab58f4f Mon Sep 17 00:00:00 2001 From: septs Date: Sun, 7 Sep 2025 21:28:05 +0200 Subject: [PATCH 2/4] chore: add nvram hint (#223) Reviewed-on: https://gitea.angry.im/PeterCxy/OpenEUICC/pulls/223 Co-authored-by: septs Co-committed-by: septs --- .../main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt | 8 +++++++- app-common/src/main/res/values-zh-rCN/strings.xml | 1 + app-common/src/main/res/values/strings.xml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt index bfbcbd8..248afaf 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt @@ -123,7 +123,13 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker { add(Item(R.string.euicc_info_pp_version, info.ppVersion.toString())) info.sasAccreditationNumber.trim().takeIf(RE_SAS::matches) ?.let { add(Item(R.string.euicc_info_sas_accreditation_number, it.uppercase())) } - add(Item(R.string.euicc_info_free_nvram, info.freeNvram.let(::formatFreeSpace))) + + val nvramText = buildString { + append(formatFreeSpace(info.freeNvram)) + append(' ') + append(getString(R.string.euicc_info_free_nvram_hint)) + } + add(Item(R.string.euicc_info_free_nvram, nvramText)) } channel.lpa.euiccInfo2?.euiccCiPKIdListForSigning.orEmpty().let { signers -> // SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24) diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index e947c6a..3865e71 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -136,6 +136,7 @@ SAS 认证号码 Protected Profile 版本 NVRAM 剩余空间 (eSIM 存储容量) + (仅供参考) 证书签发者 (CI) GSMA 生产环境 CI GSMA 测试 CI diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 3a9dda3..7d0898a 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -165,6 +165,7 @@ SAS Accreditation Number Protected Profile Version Free NVRAM (eSIM profile storage) + (for reference only) Certificate Issuer (CI) GSMA Live CI GSMA Test CI From acfeda8dc9ff251cce5511b6946541add6949999 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sun, 7 Sep 2025 17:45:18 -0400 Subject: [PATCH 3/4] i18n: Translate new strings added recently --- app-common/src/main/res/values-ja/strings.xml | 24 +++++++++++++++++++ .../src/main/res/values-zh-rCN/strings.xml | 23 ++++++++++++++++++ .../src/main/res/values-zh-rTW/strings.xml | 24 +++++++++++++++++++ app-common/src/main/res/values/strings.xml | 2 +- 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/app-common/src/main/res/values-ja/strings.xml b/app-common/src/main/res/values-ja/strings.xml index 946625f..da9d708 100644 --- a/app-common/src/main/res/values-ja/strings.xml +++ b/app-common/src/main/res/values-ja/strings.xml @@ -6,6 +6,7 @@ 情報がありません ヘルプ スロットを再読み込み + 未知 論理スロット %d 有効済み 無効済み @@ -83,6 +84,7 @@ 最終の APDU 例外: 保存 「%s」での診断 + 別のネットワークに接続し(例:Wi-Fi とデータを切り替える)、もう一度お試しください。 ログは共有したパスに保存されました。別のアプリで共有しますか? 新しいニックネーム ニックネームを UTF-8 にエンコードできませんでした @@ -114,6 +116,7 @@ SAS 認定番号 保護されたプロファイルのバージョン NVRAM の空き容量 (eSIM プロファイルストレージ) + (目安) 証明書発行者 (CI) GSMA ライブ CI GSMA テスト CI @@ -150,6 +153,7 @@ SM-DP+ TLS 証明書を無視する RSP サーバーで使用される TLS 証明書を受け入れます 一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。 + グローバル ES10x MSS 情報 アプリバージョン ソースコード @@ -169,4 +173,24 @@ ISD-R AID リストのカスタマイズ リセット ISD-R AID リスト + この eSIM プロファイルはすでに eSIM チップに存在しています。 + eSIM チップには十分なメモリ容量が残っていません。 + この eSIM プロファイルは、ダウンロード先のeSIM チップではサポートされていません。 + eSIMチップでエラーが発生しました。 + お使いのデバイスまたは eSIM チップの EID は、通信事業者によってサポートされていません。 + この eSIM プロファイルはすでに別のデバイスにダウンロードされています。 + この eSIM プロファイルはキャンセルされました。 + アクティベーションコードが無効です。 + eSIM プロファイルのダウンロード試行回数の上限を超えました。 + このプロファイルをダウンロードするには確認コードが必要です。 + 入力した確認コードは無効です。 + この eSIM プロファイルの有効期限が切れています。 + 確認コードのダウンロード試行回数の上限を超えました。 + 不明なSM-DP+アドレス + ネットワークにアクセスできません + TLS証明書エラー。このeSIMプロファイルはサポートされていません + すでにダウンロードしたeSIMプロファイルを再インストールしようとしています + 不要なeSIMプロファイルをいくつか削除して、もう一度お試しください + 通信事業者にお問い合わせください。 + この eSIM プロファイルを再発行するには、通信事業者にお問い合わせください。 diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index 3865e71..4457e6d 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -5,6 +5,7 @@ 未知 帮助 重新加载卡槽 + 未知 逻辑卡槽 %d 已启用 已禁用 @@ -46,6 +47,7 @@ IMEI (可选) 剩余空间不足 当前芯片的剩余空间不足,可能导致配置下载失败。\n是否继续下载? + 请连接到其他网络(例如在 Wi-Fi 和数据之间切换)后重试。 日志已保存到指定路径。需要通过其他 App 分享吗? 新昵称 无法将昵称编码为 UTF-8 @@ -83,6 +85,7 @@ 日志 查看应用程序的最新调试日志 某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID,导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID,但不能保证它们一定有效。 + 全局 ES10x MSS 信息 App 版本 源码 @@ -170,4 +173,24 @@ 自定义 ISD-R AID 列表 重置 ISD-R AID 列表 + 此 eSIM 配置文件已存在于您的 eSIM 芯片上。 + 您的 eSIM 芯片没有足够的空间来下载配置文件。 + 您的 eSIM 芯片不支持此 eSIM 配置文件。 + eSIM 芯片错误。 + 您的设备或 eSIM 芯片的 EID 不受您的运营商支持。 + 此 eSIM 配置文件已被下载到另一台设备上。 + 此 eSIM 配置文件已被撤销。 + 激活码无效。 + 已超出 eSIM 配置文件的最大下载尝试次数。 + 下载此配置文件需要确认码。 + 您输入的确认码无效。 + 此 eSIM 配置文件已过期。 + 已超出确认码的最大下载尝试次数。 + 未知的 SM-DP+ 地址 + 网络不可达 + TLS 证书错误,不支持此 eSIM 配置文件 + 您正在尝试重新安装已下载的 eSIM 配置文件 + 请删除一些未使用的 eSIM 配置文件,然后重试 + 请联系您的运营商寻求帮助。 + 请联系您的运营商重新签发此 eSIM 配置文件。 \ No newline at end of file diff --git a/app-common/src/main/res/values-zh-rTW/strings.xml b/app-common/src/main/res/values-zh-rTW/strings.xml index 88cc011..ef6c842 100644 --- a/app-common/src/main/res/values-zh-rTW/strings.xml +++ b/app-common/src/main/res/values-zh-rTW/strings.xml @@ -5,6 +5,7 @@ 未知 幫助 重新載入卡槽 + 未知 虛擬卡槽 %d 已啟用 已停用 @@ -46,6 +47,7 @@ IMEI (可選) 剩餘空間不足 目前晶片的剩餘空間不足,可能導致配置下載失敗。\n是否繼續下載? + 請連接到其他網路(例如在 Wi-Fi 和資料之間切換)後重試。 日誌已儲存到指定路徑。需要透過其他 App 分享嗎? 新名稱 無法將名稱編碼為 UTF-8 @@ -83,6 +85,7 @@ 允許 停用/刪除 已啟用的設定檔 預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 有時 會導致無法存取。\n勾選此框以 移除 此保護措施。 某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID,導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID,但不能保證它們一定有效。 + 全局 ES10x MSS 資訊 App 版本 原始碼 @@ -136,6 +139,7 @@ SAS 認證號碼 Protected Profile 版本 NVRAM 剩餘空間 (eSIM 儲存容量) + (僅供參考) 證書簽發者 (CI) GSMA 生產環境 CI GSMA 測試 CI @@ -169,4 +173,24 @@ 自訂 ISD-R AID 列表 重置 ISD-R AID 列表 + 此 eSIM 設定檔已存在於您的 eSIM 晶片上。 + 您的 eSIM 晶片沒有足夠的空間來下載設定檔。 + 您的 eSIM 晶片不支援此 eSIM 設定檔。 + eSIM 晶片錯誤。 + 您的裝置或 eSIM 晶片的 EID 不受您的電信業者支援。 + 此 eSIM 設定檔已被下載到另一台裝置上。 + 此 eSIM 設定檔已被撤銷。 + 啟用碼無效。 + 已超出 eSIM 設定檔的最大下載嘗試次數。 + 下載此設定檔需要確認碼。 + 您輸入的確認碼無效。 + 此 eSIM 設定檔已過期。 + 已超出確認碼的最大下載嘗試次數。 + 未知的 SM-DP+ 位址 + 網路不可達 + TLS 憑證錯誤,不支援此 eSIM 設定檔 + 您正在嘗試重新安裝已下載的 eSIM 設定文件 + 請刪除一些未使用的 eSIM 設定文件,然後重試 + 請聯絡您的電信業者尋求協助。 + 請聯絡您的電信業者重新簽發此 eSIM 設定檔。 \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 7d0898a..a7f2c10 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -222,7 +222,7 @@ Accept any TLS certificate used by the RSP server Allow erasing eUICC This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually. - ES10x MSS + ES10x MSS Global ES10x MSS High Speed From b3161ba04c0a2b5e3c7eed5cf25cbff7e6c8d61f Mon Sep 17 00:00:00 2001 From: septs Date: Mon, 8 Sep 2025 11:49:58 +0800 Subject: [PATCH 4/4] feat: strings.xml order by english version --- app-common/src/main/res/values-ja/strings.xml | 82 ++++---- .../src/main/res/values-zh-rCN/strings.xml | 192 +++++++++--------- .../src/main/res/values-zh-rTW/strings.xml | 192 +++++++++--------- app-unpriv/src/main/res/values-ja/strings.xml | 6 +- .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 4 +- scripts/strings-sort.py | 40 ++++ 10 files changed, 283 insertions(+), 243 deletions(-) create mode 100755 scripts/strings-sort.py diff --git a/app-common/src/main/res/values-ja/strings.xml b/app-common/src/main/res/values-ja/strings.xml index da9d708..44e03a0 100644 --- a/app-common/src/main/res/values-ja/strings.xml +++ b/app-common/src/main/res/values-ja/strings.xml @@ -1,9 +1,7 @@ - + このアプリでアクセスできるリムーバブル eUICC カードがデバイス上で検出されていません。互換性のあるカード挿入または USB リーダーを接続してください。 この eSIM にはプロファイルがありません。 - 不明 - 情報がありません ヘルプ スロットを再読み込み 未知 @@ -23,6 +21,8 @@ 操作は成功しましたが、デバイスのモデムが更新を拒否しました。新しいプロファイルを使用するには機内モードに切り替えるか、再起動する必要があります。 新しい eSIM プロファイルに切り替えることができません。 確認文字列が一致しません + 確認文字列が一致しません + このチップは消去されました ICCID をクリップボードにコピーしました シリアル番号をクリップボードにコピーしました EID をクリップボードにコピーしました @@ -39,6 +39,8 @@ eSIM プロファイルの削除に失敗しました eSIM プロファイルを切り替え中 eSIM プロファイルの切り替えに失敗しました + eSIM チップを消去しています + eSIM チップの消去は失敗しました 新しい eSIM サーバー (RSP / SM-DP+) アクティベーションコード @@ -84,6 +86,26 @@ 最終の APDU 例外: 保存 「%s」での診断 + この eSIM プロファイルはすでに eSIM チップに存在しています。 + eSIM チップには十分なメモリ容量が残っていません。 + この eSIM プロファイルは、ダウンロード先のeSIM チップではサポートされていません。 + eSIMチップでエラーが発生しました。 + お使いのデバイスまたは eSIM チップの EID は、通信事業者によってサポートされていません。 + この eSIM プロファイルはすでに別のデバイスにダウンロードされています。 + この eSIM プロファイルはキャンセルされました。 + アクティベーションコードが無効です。 + eSIM プロファイルのダウンロード試行回数の上限を超えました。 + このプロファイルをダウンロードするには確認コードが必要です。 + 入力した確認コードは無効です。 + この eSIM プロファイルの有効期限が切れています。 + 確認コードのダウンロード試行回数の上限を超えました。 + 不明なSM-DP+アドレス + ネットワークにアクセスできません + TLS証明書エラー。このeSIMプロファイルはサポートされていません + すでにダウンロードしたeSIMプロファイルを再インストールしようとしています + 不要なeSIMプロファイルをいくつか削除して、もう一度お試しください + 通信事業者にお問い合わせください。 + この eSIM プロファイルを再発行するには、通信事業者にお問い合わせください。 別のネットワークに接続し(例:Wi-Fi とデータを切り替える)、もう一度お試しください。 ログは共有したパスに保存されました。別のアプリで共有しますか? 新しいニックネーム @@ -121,13 +143,23 @@ GSMA ライブ CI GSMA テスト CI 不明な eSIM CI + eSIM を消去する + eSIM を消去する + このチップ内のすべてのプロファイルを削除することをご確認してください。この操作は元に戻せないことをご理解してください。\n\nEID: %1$s\n\n%2$s + 確認のため、ここに「%s」を入力してください + EID が %s で終わるチップを消去することに同意します。これは元に戻せないことを理解しています。 + 消去する はい いいえ + 不明 + 情報がありません 保存 %s のログ 開発者になるまであと %d ステップです。 あなたは開発者になりました! + ISD-R AID リスト カスタム ISD-R AID リストが保存されました + リセット 設定 通知 eSIM のプロファイル操作により、通信事業者に通知が送信されます。必要に応じてこの動作を微調整できます。 @@ -147,50 +179,18 @@ ログ アプリの最新デバッグログを表示します 開発者オプション + モデムに更新コマンドを送信 プロファイルを切り替えた後にモデムに更新コマンドを送信するかどうか。クラッシュが発生する場合は、これを無効にしてみてください。 フィルタリングされていないプロファイル一覧を表示 非運用のプロファイルも含めます SM-DP+ TLS 証明書を無視する RSP サーバーで使用される TLS 証明書を受け入れます - 一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。 + eUICC の消去を可能にする + この操作は、デフォルトでは非表示になっている危険な操作です。代わりに、すべての構成ファイルを手動で削除することもできます。 グローバル ES10x MSS + ISD-R AID リストのカスタマイズ + 一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。 情報 アプリバージョン ソースコード - 確認文字列が一致しません - このチップは消去されました - eSIM チップを消去しています - eSIM チップの消去は失敗しました - eSIM を消去する - eSIM を消去する - このチップ内のすべてのプロファイルを削除することをご確認してください。この操作は元に戻せないことをご理解してください。\n\nEID: %1$s\n\n%2$s - 確認のため、ここに「%s」を入力してください - EID が %s で終わるチップを消去することに同意します。これは元に戻せないことを理解しています。 - 消去する - eUICC の消去を可能にする - この操作は、デフォルトでは非表示になっている危険な操作です。代わりに、すべての構成ファイルを手動で削除することもできます。 - モデムに更新コマンドを送信 - ISD-R AID リストのカスタマイズ - リセット - ISD-R AID リスト - この eSIM プロファイルはすでに eSIM チップに存在しています。 - eSIM チップには十分なメモリ容量が残っていません。 - この eSIM プロファイルは、ダウンロード先のeSIM チップではサポートされていません。 - eSIMチップでエラーが発生しました。 - お使いのデバイスまたは eSIM チップの EID は、通信事業者によってサポートされていません。 - この eSIM プロファイルはすでに別のデバイスにダウンロードされています。 - この eSIM プロファイルはキャンセルされました。 - アクティベーションコードが無効です。 - eSIM プロファイルのダウンロード試行回数の上限を超えました。 - このプロファイルをダウンロードするには確認コードが必要です。 - 入力した確認コードは無効です。 - この eSIM プロファイルの有効期限が切れています。 - 確認コードのダウンロード試行回数の上限を超えました。 - 不明なSM-DP+アドレス - ネットワークにアクセスできません - TLS証明書エラー。このeSIMプロファイルはサポートされていません - すでにダウンロードしたeSIMプロファイルを再インストールしようとしています - 不要なeSIMプロファイルをいくつか削除して、もう一度お試しください - 通信事業者にお問い合わせください。 - この eSIM プロファイルを再発行するには、通信事業者にお問い合わせください。 - + \ No newline at end of file diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index 4457e6d..7c5477d 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -1,8 +1,7 @@ - + 在此设备上未检测到此应用程序可访问的可插拔 eUICC 卡。请插入兼容卡或 USB 读卡器。 此 eSIM 上还没有配置文件 - 未知 帮助 重新加载卡槽 未知 @@ -11,6 +10,9 @@ 已禁用 提供商: 类型: + 测试 + 准备中 + 可用 启用 禁用 删除 @@ -19,7 +21,10 @@ 操作成功, 但是您手机的基带拒绝刷新。您可能需要切换飞行模式或重新启动,以便使用新的配置文件。 无法切换到新的 eSIM 配置文件。 输入的确认文本不匹配 + 输入的确认文本不匹配 + 此芯片已被擦除 已复制 ICCID 到剪贴板 + 已复制序列号到剪贴板 已复制 EID 到剪贴板 已复制 ATR 到剪贴板 授予 USB 权限 @@ -34,64 +39,16 @@ 无法删除 eSIM 配置文件 正在切换 eSIM 配置文件 无法切换 eSIM 配置文件 + 正在擦除 eSIM 芯片 + eSIM 芯片擦除失败 添加新 eSIM 服务器 (RSP / SM-DP+) 激活码 确认码 (可选) - 已复制序列号到剪贴板 - 产品名称 - 产品序列号 - 产品 Bootloader 版本 - 产品固件版本 确认码 (必需) IMEI (可选) 剩余空间不足 当前芯片的剩余空间不足,可能导致配置下载失败。\n是否继续下载? - 请连接到其他网络(例如在 Wi-Fi 和数据之间切换)后重试。 - 日志已保存到指定路径。需要通过其他 App 分享吗? - 新昵称 - 无法将昵称编码为 UTF-8 - 昵称长于 64 字符 - 重命名配置文件时发生了未知错误 - 您确定要删除 %s 吗?此操作是不可逆的。 - 请输入\'%s\'以确认删除 - 通知列表 - 通知列表 (%s) - 管理通知 - eSIM 配置文件可以在下载、删除、启用或禁用时向运营商发送通知。此处列出了要发送的这些通知的队列。\n\n在\"设置\"中,您可以指定是否自动发送每种类型的通知。请注意,即使通知已发送,也不会自动从记录中删除,除非队列空间不足。\n\n在这里,您可以手动发送或删除每个待处理的通知。 - 已下载 - 已删除 - 已启用 - 已禁用 - 处理 - 删除 - 保存日志 - %s 的日志 - 自定义 ISD-R AID 列表已保存 - 设置 - 通知 - 操作 eSIM 配置文件会向运营商发送通知。根据需要在此处微调此行为。 - 下载 - 发送 下载 配置文件的通知 - 删除 - 发送 删除 配置文件的通知 - 切换 - 发送 切换 配置文件的通知\n注意,这种类型的通知是不可靠的。 - 高级 - 允许 禁用/删除 已启用的配置文件 - 默认情况下,此应用程序会阻止您禁用可插拔 eSIM 中已启用的配置文件。\n因为这样做 有时 会使其无法访问。\n勾选此框以 移除 此保护措施。 - 记录详细日志 - 详细日志中包含敏感信息,开启此功能后请仅与你信任的人共享你的日志。 - 日志 - 查看应用程序的最新调试日志 - 某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID,导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID,但不能保证它们一定有效。 - 全局 ES10x MSS - 信息 - App 版本 - 源码 - 测试 - 准备中 - 可用 未在剪贴板上发现 LPA 码 LPA 码解析错误 无法将二维码或剪贴板内容解析为 LPA 码 @@ -129,50 +86,6 @@ 上次 APDU 错误: 保存 %s 的错误诊断 - eUICC 详情 - eUICC 详情 (%s) - 访问方式 - 可插拔 - SGP.22 版本 - eUICC OS 版本 - GlobalPlatform 版本 - SAS 认证号码 - Protected Profile 版本 - NVRAM 剩余空间 (eSIM 存储容量) - (仅供参考) - 证书签发者 (CI) - GSMA 生产环境 CI - GSMA 测试 CI - 未知 eSIM CI - - - 还有 %d 步成为开发者 - 你现在是开发者了! - 语言 - 选择 App 语言 - 开发者选项 - 切换配置文件后是否向基带发送刷新命令。如果发现崩溃,请尝试禁用此功能。 - 显示未经过滤的配置文件列表 - 在配置文件列表中包括非生产环境的配置文件 - 无视 SM-DP+ 的 TLS 证书 - 允许 RSP 服务器使用任意证书 - 无信息 - 输入的确认文本不匹配 - 此芯片已被擦除 - 正在擦除 eSIM 芯片 - eSIM 芯片擦除失败 - 擦除 eSIM 芯片 - 擦除 eSIM 芯片 - 请确认删除此芯片上的所有配置文件,并了解此操作不可逆。\n\nEID: %1$s\n\n%2$s - 请在此处输入「%s」以确认 - 我确认擦除 EID 以 %s 结尾的芯片,并了解此操作不可逆 - 擦除 - 允许擦除 eUICC - 此操作是默认隐藏的危险操作。作为替代方案,您可以手动删除所有配置文件。 - 向基带发送刷新命令 - 自定义 ISD-R AID 列表 - 重置 - ISD-R AID 列表 此 eSIM 配置文件已存在于您的 eSIM 芯片上。 您的 eSIM 芯片没有足够的空间来下载配置文件。 您的 eSIM 芯片不支持此 eSIM 配置文件。 @@ -193,4 +106,91 @@ 请删除一些未使用的 eSIM 配置文件,然后重试 请联系您的运营商寻求帮助。 请联系您的运营商重新签发此 eSIM 配置文件。 + 请连接到其他网络(例如在 Wi-Fi 和数据之间切换)后重试。 + 日志已保存到指定路径。需要通过其他 App 分享吗? + 新昵称 + 无法将昵称编码为 UTF-8 + 昵称长于 64 字符 + 重命名配置文件时发生了未知错误 + 您确定要删除 %s 吗?此操作是不可逆的。 + 请输入\'%s\'以确认删除 + 通知列表 + 通知列表 (%s) + 管理通知 + eSIM 配置文件可以在下载、删除、启用或禁用时向运营商发送通知。此处列出了要发送的这些通知的队列。\n\n在\"设置\"中,您可以指定是否自动发送每种类型的通知。请注意,即使通知已发送,也不会自动从记录中删除,除非队列空间不足。\n\n在这里,您可以手动发送或删除每个待处理的通知。 + 已下载 + 已删除 + 已启用 + 已禁用 + 处理 + 删除 + eUICC 详情 + eUICC 详情 (%s) + 访问方式 + 可插拔 + 产品名称 + 产品序列号 + 产品 Bootloader 版本 + 产品固件版本 + SGP.22 版本 + eUICC OS 版本 + GlobalPlatform 版本 + SAS 认证号码 + Protected Profile 版本 + NVRAM 剩余空间 (eSIM 存储容量) + (仅供参考) + 证书签发者 (CI) + GSMA 生产环境 CI + GSMA 测试 CI + 未知 eSIM CI + 擦除 eSIM 芯片 + 擦除 eSIM 芯片 + 请确认删除此芯片上的所有配置文件,并了解此操作不可逆。\n\nEID: %1$s\n\n%2$s + 请在此处输入「%s」以确认 + 我确认擦除 EID 以 %s 结尾的芯片,并了解此操作不可逆 + 擦除 + + + 未知 + 无信息 + 保存日志 + %s 的日志 + 还有 %d 步成为开发者 + 你现在是开发者了! + ISD-R AID 列表 + 自定义 ISD-R AID 列表已保存 + 重置 + 设置 + 通知 + 操作 eSIM 配置文件会向运营商发送通知。根据需要在此处微调此行为。 + 下载 + 发送 下载 配置文件的通知 + 删除 + 发送 删除 配置文件的通知 + 切换 + 发送 切换 配置文件的通知\n注意,这种类型的通知是不可靠的。 + 高级 + 允许 禁用/删除 已启用的配置文件 + 默认情况下,此应用程序会阻止您禁用可插拔 eSIM 中已启用的配置文件。\n因为这样做 有时 会使其无法访问。\n勾选此框以 移除 此保护措施。 + 记录详细日志 + 详细日志中包含敏感信息,开启此功能后请仅与你信任的人共享你的日志。 + 语言 + 选择 App 语言 + 日志 + 查看应用程序的最新调试日志 + 开发者选项 + 向基带发送刷新命令 + 切换配置文件后是否向基带发送刷新命令。如果发现崩溃,请尝试禁用此功能。 + 显示未经过滤的配置文件列表 + 在配置文件列表中包括非生产环境的配置文件 + 无视 SM-DP+ 的 TLS 证书 + 允许 RSP 服务器使用任意证书 + 允许擦除 eUICC + 此操作是默认隐藏的危险操作。作为替代方案,您可以手动删除所有配置文件。 + 全局 ES10x MSS + 自定义 ISD-R AID 列表 + 某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID,导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID,但不能保证它们一定有效。 + 信息 + App 版本 + 源码 \ No newline at end of file diff --git a/app-common/src/main/res/values-zh-rTW/strings.xml b/app-common/src/main/res/values-zh-rTW/strings.xml index ef6c842..67d0bb7 100644 --- a/app-common/src/main/res/values-zh-rTW/strings.xml +++ b/app-common/src/main/res/values-zh-rTW/strings.xml @@ -1,8 +1,7 @@ - + 在此裝置上未檢測到此應用程式可訪問的可插拔 eUICC 卡。請插入相容卡或 USB 晶片讀卡機。 此 eSIM 上還沒有設定檔 - 未知 幫助 重新載入卡槽 未知 @@ -11,6 +10,9 @@ 已停用 電信業者: 類型: + 測試 + 準備中 + 可用 啟用 停用 刪除 @@ -19,7 +21,10 @@ 操作成功, 但是您手機的基頻處理器沒有重新整理。您可能需要切換飛航模式或重新啟動,以便使用新的設定檔。 無法切換到新的 eSIM 設定檔。 輸入的確認文字不匹配 + 輸入的確認文字不匹配 + 此晶片已被擦除 已複製 ICCID 到剪貼簿 + 已複製序號到剪貼簿 已複製 EID 到剪貼簿 已複製 ATR 到剪貼簿 授予 USB 權限 @@ -34,64 +39,16 @@ 無法刪除 eSIM 設定檔 正在切換 eSIM 設定檔 無法切換 eSIM 設定檔 + 正在擦除 eSIM 晶片 + eSIM 晶片擦除失敗 新增新 eSIM 伺服器 (RSP / SM-DP+) 啟用碼 確認碼 (可選) - 已複製序號到剪貼簿 - 產品名稱 - 產品序號 - 產品引導程式版本 - 產品韌體版本 確認碼 (必需) IMEI (可選) 剩餘空間不足 目前晶片的剩餘空間不足,可能導致配置下載失敗。\n是否繼續下載? - 請連接到其他網路(例如在 Wi-Fi 和資料之間切換)後重試。 - 日誌已儲存到指定路徑。需要透過其他 App 分享嗎? - 新名稱 - 無法將名稱編碼為 UTF-8 - 名稱長於 64 字元 - 重新命名設定檔時發生了未知錯誤 - 您確定要刪除 %s 嗎?此動作無法還原。 - 請輸入\'%s\'以確認刪除 - 通知列表 - 通知列表 (%s) - 管理通知 - eSIM 設定檔可以在下載、刪除、啟用或停用時向電信業者傳送通知。此處列出了要傳送的這些通知的佇列。\n\n在\"設定\"中,您可以指定是否自動傳送每種型別的通知。請注意,即使通知已傳送,也不會自動從記錄中刪除,除非佇列空間不足。\n\n在這裡,您可以手動傳送或刪除每個待處理的通知。 - 已下載 - 已刪除 - 已啟用 - 已停用 - 處理 - 刪除 - 儲存日誌 - %s 的日誌 - 自訂 ISD-R AID 列表已儲存 - 設定 - 通知 - 變更 eSIM 設定檔會向電信業者傳送通知。根據需要在此處微調此行為。 - 下載 - 傳送 下載 設定檔的通知 - 刪除 - 傳送 刪除 設定檔的通知 - 切換 - 記錄詳細日誌 - 詳細日誌中包含敏感資訊,開啟此功能後請僅與你信任的人共享你的日誌。 - 日誌 - 檢視應用程式的最新除錯日誌 - 傳送 切換 設定檔的通知\n注意,這種型別的通知是不可靠的。 - 進階 - 允許 停用/刪除 已啟用的設定檔 - 預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 有時 會導致無法存取。\n勾選此框以 移除 此保護措施。 - 某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID,導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID,但不能保證它們一定有效。 - 全局 ES10x MSS - 資訊 - App 版本 - 原始碼 - 測試 - 準備中 - 可用 未在剪貼簿上發現 LPA 碼 LPA 碼解析錯誤 無法將二維碼或剪貼簿內容解析為 LPA 碼 @@ -129,50 +86,6 @@ 上次 APDU 錯誤: 儲存 %s 的錯誤診斷 - eUICC 詳情 - eUICC 詳情 (%s) - 訪問方式 - 可插拔 - SGP.22 版本 - eUICC OS 版本 - GlobalPlatform 版本 - SAS 認證號碼 - Protected Profile 版本 - NVRAM 剩餘空間 (eSIM 儲存容量) - (僅供參考) - 證書簽發者 (CI) - GSMA 生產環境 CI - GSMA 測試 CI - 未知 eSIM CI - - - 還有 %d 步成為開發者 - 您現在是開發者了! - 語言 - 選擇 App 語言 - 開發人員選項 - 切換設定檔後是否向基帶發送刷新命令。如果發現崩潰,請嘗試停用此功能。 - 顯示未經過濾的設定檔列表 - 在設定檔列表中包括非生產環境的設定檔 - 忽略 SM-DP+ 的 TLS 證書 - 允許 RSP 伺服器使用任意證書 - 無資訊 - 輸入的確認文字不匹配 - 此晶片已被擦除 - 正在擦除 eSIM 晶片 - eSIM 晶片擦除失敗 - 擦除 eSIM 晶片 - 擦除 eSIM 晶片 - 請確認刪除此晶片上的所有配置文件,並了解此操作不可逆。\n\nEID: %1$s\n\n%2$s - 請在此輸入「%s」以確認 - 我確認擦除 EID 以 %s 結尾的晶片,並了解此操作不可逆 - 擦除 - 允許擦除 eUICC - 此操作是預設隱藏的危險操作。作為替代方案,您可以手動刪除所有設定檔。 - 向基帶發送刷新命令 - 自訂 ISD-R AID 列表 - 重置 - ISD-R AID 列表 此 eSIM 設定檔已存在於您的 eSIM 晶片上。 您的 eSIM 晶片沒有足夠的空間來下載設定檔。 您的 eSIM 晶片不支援此 eSIM 設定檔。 @@ -193,4 +106,91 @@ 請刪除一些未使用的 eSIM 設定文件,然後重試 請聯絡您的電信業者尋求協助。 請聯絡您的電信業者重新簽發此 eSIM 設定檔。 + 請連接到其他網路(例如在 Wi-Fi 和資料之間切換)後重試。 + 日誌已儲存到指定路徑。需要透過其他 App 分享嗎? + 新名稱 + 無法將名稱編碼為 UTF-8 + 名稱長於 64 字元 + 重新命名設定檔時發生了未知錯誤 + 您確定要刪除 %s 嗎?此動作無法還原。 + 請輸入\'%s\'以確認刪除 + 通知列表 + 通知列表 (%s) + 管理通知 + eSIM 設定檔可以在下載、刪除、啟用或停用時向電信業者傳送通知。此處列出了要傳送的這些通知的佇列。\n\n在\"設定\"中,您可以指定是否自動傳送每種型別的通知。請注意,即使通知已傳送,也不會自動從記錄中刪除,除非佇列空間不足。\n\n在這裡,您可以手動傳送或刪除每個待處理的通知。 + 已下載 + 已刪除 + 已啟用 + 已停用 + 處理 + 刪除 + eUICC 詳情 + eUICC 詳情 (%s) + 訪問方式 + 可插拔 + 產品名稱 + 產品序號 + 產品引導程式版本 + 產品韌體版本 + SGP.22 版本 + eUICC OS 版本 + GlobalPlatform 版本 + SAS 認證號碼 + Protected Profile 版本 + NVRAM 剩餘空間 (eSIM 儲存容量) + (僅供參考) + 證書簽發者 (CI) + GSMA 生產環境 CI + GSMA 測試 CI + 未知 eSIM CI + 擦除 eSIM 晶片 + 擦除 eSIM 晶片 + 請確認刪除此晶片上的所有配置文件,並了解此操作不可逆。\n\nEID: %1$s\n\n%2$s + 請在此輸入「%s」以確認 + 我確認擦除 EID 以 %s 結尾的晶片,並了解此操作不可逆 + 擦除 + + + 未知 + 無資訊 + 儲存日誌 + %s 的日誌 + 還有 %d 步成為開發者 + 您現在是開發者了! + ISD-R AID 列表 + 自訂 ISD-R AID 列表已儲存 + 重置 + 設定 + 通知 + 變更 eSIM 設定檔會向電信業者傳送通知。根據需要在此處微調此行為。 + 下載 + 傳送 下載 設定檔的通知 + 刪除 + 傳送 刪除 設定檔的通知 + 切換 + 傳送 切換 設定檔的通知\n注意,這種型別的通知是不可靠的。 + 進階 + 允許 停用/刪除 已啟用的設定檔 + 預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 有時 會導致無法存取。\n勾選此框以 移除 此保護措施。 + 記錄詳細日誌 + 詳細日誌中包含敏感資訊,開啟此功能後請僅與你信任的人共享你的日誌。 + 語言 + 選擇 App 語言 + 日誌 + 檢視應用程式的最新除錯日誌 + 開發人員選項 + 向基帶發送刷新命令 + 切換設定檔後是否向基帶發送刷新命令。如果發現崩潰,請嘗試停用此功能。 + 顯示未經過濾的設定檔列表 + 在設定檔列表中包括非生產環境的設定檔 + 忽略 SM-DP+ 的 TLS 證書 + 允許 RSP 伺服器使用任意證書 + 允許擦除 eUICC + 此操作是預設隱藏的危險操作。作為替代方案,您可以手動刪除所有設定檔。 + 全局 ES10x MSS + 自訂 ISD-R AID 列表 + 某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID,導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID,但不能保證它們一定有效。 + 資訊 + App 版本 + 原始碼 \ No newline at end of file diff --git a/app-unpriv/src/main/res/values-ja/strings.xml b/app-unpriv/src/main/res/values-ja/strings.xml index f3ff41f..aac7f84 100644 --- a/app-unpriv/src/main/res/values-ja/strings.xml +++ b/app-unpriv/src/main/res/values-ja/strings.xml @@ -1,9 +1,7 @@ - + 互換性のチェック SIM ツールキットを開く - - ARA-M SHA-1 をクリップボードにコピーしました 「%s」アプリを有効化してください 互換性のチェック @@ -17,4 +15,4 @@ つづく このメッセージを再度表示しない 不明 - + \ No newline at end of file diff --git a/app-unpriv/src/main/res/values-zh-rCN/strings.xml b/app-unpriv/src/main/res/values-zh-rCN/strings.xml index cd66a43..5803bc4 100644 --- a/app-unpriv/src/main/res/values-zh-rCN/strings.xml +++ b/app-unpriv/src/main/res/values-zh-rCN/strings.xml @@ -1,3 +1,4 @@ + 兼容性检查 打开 SIM 卡应用程序 diff --git a/app-unpriv/src/main/res/values-zh-rTW/strings.xml b/app-unpriv/src/main/res/values-zh-rTW/strings.xml index ab64d6b..cd25e0e 100644 --- a/app-unpriv/src/main/res/values-zh-rTW/strings.xml +++ b/app-unpriv/src/main/res/values-zh-rTW/strings.xml @@ -1,3 +1,4 @@ + 相容性檢查 啟動 SIM 卡應用程式 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index fbf5c53..492a9d8 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,4 +1,4 @@ - + このデバイスで eUICC が見つかりません。\nデバイスによってはアプリのメニューからデュアル SIM を有効化する必要があります。 TelephonyManager (特権) @@ -19,4 +19,4 @@ eSIM をダウンロード TelephonyManagerをどこでも使用 デフォルトでは、非特権モード (EasyEUICC) と一致するように、取り外し可能な eUICC に対して OMAPI のみが試行されます。これは、一部のデバイスではうまく機能しない可能性があります。このオプションを選択する場合、取り外し可能な eUICC でも TelephonyManager を使用することになります。 - + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index acd9a61..4bdae27 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1,6 +1,7 @@ - + 在此设备上找不到 eUICC 芯片。\n在某些设备上,您可能需要先在此应用的菜单中启用双卡支持。 + TelephonyManager (特权) 双卡 双卡支持状态已切换。请等待基带重新启动。 此卡槽支持多个启用配置文件 (MEP)。要启用或禁用此功能,请使用\"卡槽映射\"工具。 @@ -16,7 +17,6 @@ 您的设备支持 eSIM。要连接到移动网络,请下载运营商发布的 eSIM,或插入物理 SIM 卡。 跳过 下载 eSIM - TelephonyManager (特权) 全局使用 TelephonyManager 在默认情况下,可移除 eUICC 将仅使用 OMAPI。这与非特权模式 (EasyEUICC) 一致。在某些设备上 OMAPI 可能存在问题 -- 选择此选项以强制使用 TelephonyManager。 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 52b5aa8..69042ea 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1,6 +1,7 @@ - + 在此裝置上找不到 eUICC 晶片。\n在某些裝置上,您可能需要先在此應用的選單中啟用雙卡支援。 + TelephonyManager (特權) 雙卡 雙卡支援狀態已切換。請等待基頻處理器重新啟動。 此卡槽支援多個啟用設定檔 (MEP)。要啟用或停用此功能,請使用\"卡槽對映\"工具。 @@ -16,7 +17,6 @@ 您的裝置支援 eSIM。要連線到行動網路,請下載電信業者釋出的 eSIM,或插入實體 SIM 卡。 跳過 下載 eSIM - TelephonyManager (特權) 全域使用 TelephonyManager 在預設情況下,可移除 eUICC 將僅使用 OMAPI。這與非特權模式 (EasyEUICC) 一致。在某些裝置上 OMAPI 可能有問題 -- 選擇此選項以強制使用 TelephonyManager。 \ No newline at end of file diff --git a/scripts/strings-sort.py b/scripts/strings-sort.py new file mode 100755 index 0000000..af7ad64 --- /dev/null +++ b/scripts/strings-sort.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from pathlib import Path +from xml.etree import ElementTree + +ROOT_PATH = Path(__file__).parent.parent + + +def get_strings_names(path: Path): + root = ElementTree.parse(path).getroot() + return [ + element.get("name") + for element in root.iter() + if element.get("translatable") != "false" + ] + + +def sort_strings_xml(input_path: Path, names: list[str]): + tree = ElementTree.parse(input_path) + root = tree.getroot() + for key in set(names) - set(elem.get("name") for elem in root.iter()): + names.remove(key) # Remove keys not present in this file + elements = list(root) + elements.sort(key=lambda elem: names.index(elem.get("name"))) + root.clear() + for elem in elements: + root.append(elem) + tree.write(input_path, encoding='utf-8', xml_declaration=True) + print(f'Sorted strings written to {input_path.relative_to(ROOT_PATH)}') + + +def main(): + for res_path in ROOT_PATH.rglob("res"): + names = get_strings_names(res_path / "values/strings.xml") + for values_dir in res_path.glob("values-*/strings.xml"): + sort_strings_xml(values_dir, names) + + +if __name__ == '__main__': + main()