안드로이드 현재 단말기가 더블 유심일 경우 전화번호를 가져오는 메소드
와 같은 글을 예전에 업로드한 적이 있었다.
하지만, 코드를 작성하던 중 아래와 같은 문제가 있었고 이 글은 그 모든 상황에 대비한 유틸 클래스에 대한 내용이다.
1. 통신사마다 전화번호 포맷이 동일하지않다.
-> google의 libphonenumber 라이브러리를 이용하여 포맷 통일하였음.
2. 특정 장치에서 유심 체크 시 문제 발생
-> 유심 상태에 대한 모든 예외상황을 두어 NPE를 패스하였다.
총정리한 USIMUtil 클래스 내용은 아래와 같다.
Manifest
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
전화번호 포맷 통일을 위해 해당 라이브러리를 implementation한다.
implementation 'com.googlecode.libphonenumber:libphonenumber:8.2.0'
유심 관리 클래스(코틀린 object 클래스 적용)
object UsimUtil {
private const val TAG = "UsimUtil"
// 유심 상태 체크 메소드
fun USimCheck(context: Context): Boolean {
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
return when (telephonyManager.simState) {
TelephonyManager.SIM_STATE_UNKNOWN, // 유심 상태를 알 수 없는 경우
TelephonyManager.SIM_STATE_ABSENT, // 유심이 없는 경우
TelephonyManager.SIM_STATE_PERM_DISABLED, // 유심이 존재하지만, 사용중지 상태인 경우
TelephonyManager.SIM_STATE_CARD_IO_ERROR, // 유심이 존재하지만, 오류 상태인 경우
TelephonyManager.SIM_STATE_CARD_RESTRICTED // 유심이 존재하지만 통신사 제한으로 사용 불가 상태인 경우
-> {
Toast.makeText(context, "해당 단말기의 유심이 존재하지 않거나, 오류가 있습니다.", Toast.LENGTH_SHORT).show()
false
}
else -> {
true
}
}
}
// 단말기 전화번호 포맷 통일 메소드
private fun toNationalFormat(phoneNumber: String): String {
val phoneNumberUtil = PhoneNumberUtil.getInstance()
// 단말기의 해당 국가 코드를 가져온다.
val locale = Locale.getDefault().country
val toNationalNum = phoneNumberUtil.parse(phoneNumber, locale)
return phoneNumberUtil.format(toNationalNum, PhoneNumberUtil.PhoneNumberFormat.NATIONAL).replace("-", "")
}
// 단말기의 전화번호를 가져오는 메소드
@SuppressLint("HardwareIds")
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
fun getPhoneNumber(context: Context): ArrayList {
val phoneNumberArr = ArrayList()
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
// 22 레벨부터는 더블 유심 지원 제공
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
val subscriptionManager =
context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
val subInfoList = subscriptionManager.activeSubscriptionInfoList
for (subInfo in subInfoList) {
Log.d(TAG, subInfo.number)
if (!TextUtils.isEmpty(subInfo.number)) {
phoneNumberArr.add(toNationalFormat(subInfo.number))
} else {
if (!TextUtils.isEmpty(telephonyManager.line1Number)) {
Log.d(TAG, telephonyManager.line1Number)
phoneNumberArr.add(toNationalFormat(telephonyManager.line1Number))
break
}
}
}
} else {
if (telephonyManager.line1Number) {
Log.d(TAG, telephonyManager.line1Number)
phoneNumberArr.add(toNationalFormat(telephonyManager.line1Number))
}
}
return phoneNumberArr
}
// 단말기 전화번호 정규식 변환
fun hyphenFormat(number: String): String {
return number.replaceFirst("(^[0-9]{3})([0-9]{3,4})([0-9]{4})$".toRegex(), "$1-$2-$3")
}
}
2020.08.11 수정사항
minSdkVersion가 23 이상인 경우 아래와 같이 간결하게 작성 가능
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import androidx.core.content.ContextCompat
import kotlin.collections.ArrayList
class DeviceNumberUtil(private val context: Context) {
fun enabledUSIM(): Boolean {
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
return when (telephonyManager.simState) {
TelephonyManager.SIM_STATE_READY -> true
else -> false
}
}
fun getSubInfoList(): List<SubscriptionInfo>? =
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
(context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager).activeSubscriptionInfoList
else null
fun getPhoneNumberList(subInfoList: List<SubscriptionInfo>?): ArrayList<String> {
val phoneNumbers = ArrayList<String>()
if (subInfoList != null)
for (subInfo in subInfoList) {
phoneNumbers.add(subInfo.number)
}
return phoneNumbers
}
}
class TestActivity : Activity(){
private val deviceNumberUtil by lazy { DeviceNumberUtil(this) }
override fun onCreate(savedInstanceState: Bundle?) {
....
// List<String>
val phoneNumbers = deviceNumberUtil.getPhoneNumberList(phoneNumberUtil.getSubInfoList()).map { it.toNationalPhoneNumber() }
if(phoneNumbers.size > 0) ...
}
fun String.toNationalPhoneNumber(): String {
val phoneNumberUtil = PhoneNumberUtil.getInstance()
val locale = Locale.getDefault().country
val toNationalNum = phoneNumberUtil.parse(this, locale)
return phoneNumberUtil.format(toNationalNum, PhoneNumberUtil.PhoneNumberFormat.NATIONAL)
}
}
'Before 2022 > Android' 카테고리의 다른 글
EditText 비밀번호 보이기/숨기기 (0) | 2019.07.11 |
---|---|
Dialog Full Size 및 화면 하단에 위치 시키기 (0) | 2019.06.17 |
Event Bus (0) | 2019.05.20 |
FCM 푸시 구현하기 - 준비 작업 (0) | 2019.04.09 |
퍼미션 체크(권한 허용 요청) 커스텀 리스트 뷰 리팩토링 (0) | 2019.03.15 |