[kotlin] 스마트폰 정보 가져오는 방법

ywown·2021년 11월 14일
0

코틀린 개념

목록 보기
5/8

『Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린』 교재를 바탕으로 정리한 내용입니다.

스마트폰 정보 구하기

전화 정보

  • PhoneStateListener 상속받은 후, 그 객체를 TelephonyManager에 등록해 사용 ❗API 버전 31부터는 deprecated → TelephonyCallBack 클래스 사용
  • 스마트폰의 전화 관련 상태가 바뀔 때마다 PhoneStateListener의 함수들이 자동으로 호출됨
    • onServiceStateChanged() : 단말기의 서비스 상태 변경
    • onCallStateChanged() : 통화 상태 변경
  • 필요한 함수만 재정의해서 전화 상태 변화를 감지해 사용
    val phoneStateListener = object : PhoneStateListener() {
    	// 단말기의 서비스 상태 변경 함수
    	override fun onServiceStateChanged(serviceState: ServiceState?) {
    		super.onServiceStateChanged(serviceState)
    		(... 생략 ...)
    	}
    }
  • TelephonyManager 객체 얻어 listen()함수에 객체 등록
    • listen() 함수의 두 번째 매개변수에는 감지할 상태를 의미하는 상수 지정
    • 상태 여러 개를 동시에 감지하려면 or 연산자로 상수 나열
    • 상태 감지 해제할 때는 LISTEN_NONE 상수 지정
    val manager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    manager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE)
    
    //상수 여러개 지정
    manager.listen(phoneStateListener, 
                PhoneStateListener.LISTEN_SERVICE_STATE or PhoneStateListener.LISTEN_CALL_STATE)
    //상태 감지 해제
    manager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
  • 서비스 상태 감지
    • onServiceStateChanged() 함수는 비행 모드나 긴급 통화 등 스마트폰의 서비스 상태가 바뀌는 순간에 호출됨
    val phoneStateListener = object : PhoneStateListener() {
    	override fun onServiceStateChanged(serviceState: ServiceState?) {
    		when (serviceState?.state) {
    			ServiceState.STATE_EMERGENCY_ONLY -> Log.d("kkang", "긴급 통화만 가능한 상태...")
    			ServiceState.STATE_OUT_OF_SERVICE -> Log.d("kkang", "서비스 불가 상태...")
    			ServiceState.STATE_POWER_OFF -> Log.d("kkang", "전화 기능을 꺼 놓은 상태...")
    			ServiceState.STATE_IN_SERVICE -> Log.d("kkang", "서비스 가능 상태...")
    		}
    	}
    }
  • 전화 걸려오는 상태 감지
    • onCallStateChanged() 함수 사용

      → 앱에서 전화번호 받아오기 위한 퍼미션 등록

    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    override fun onCallStateChanged(state: Int, phoneNumber: String?) {
    	when (state) {
    		TelephonyManager.CALL_STATE_IDLE -> Log.d("kkang", "통화 대기 상태..")
    		TelephonyManager.CALL_STATE_RINGING -> Log.d("kkang", "벨이 울리는 상태..$phoneNumber")
    		TelephonyManager.CALL_STATE_OFFHOOK -> Log.d("kkang", "통화 중인 상태..$phoneNumber")
    	}
    }
  • 네트워크 제공 국가, 사업자, 전화번호 얻기
    • getNetworkCountryIso() : 네트워크 제공 국가

    • getNetworkOperatorName() : 네트워크 제공 사업자

    • getLine1Number() : 스마트폰의 전화번호

      → getLine1Number() 함수 이용해 스마트폰 전화번호 추출하기 위한 퍼미션 등록

    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    // manager -> TelephonyManager 객체
    val countryIso = manager.networkCountryIso()
    val operatorName = manager.networkOperatorName()
    val phoneNumber = manager.line1Number()

네트워크 접속 정보

  • 스마트폰이 네트워크 가능한 상태인지 파악하기 위해 ConnectivityManager 이용
  • 네트워크 가능 여부 또는 어떤 네트워크에 접속되었지 알기 위해 getActiveNetwork() 함수로 Network 객체 얻어서 이용 ❗ API 레벨 23 하위 버전에서도 실행되는 앱 개발한다면 getActiveNetWorkInfo() 함수 이용

→ 네트워크 상태 접근 퍼미션

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • activityNetwork로 얻은 Network 객체를 다시 getNetworkCapabilities() 함수의 매개변수로 지정하면 현재 접속된 네트워크 정보 얻을 수 있음
  • hasTransport()함수를 이용해 어떤 통신망에 접속된 상태인지 확인 가능
private fun isNetworkAvailable(): Boolean {
	val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
	val nw = connectivityManager.activeNetwork ?: return false
	val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
		return when {
			actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
				Log.d("kkang", "wifi available")
				true
			}
			actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
				Log.d("kkang", "cellular available")
				true
			}
			else -> false
		}
	} else {
			return connectivityManager.activeNetworkInfo?.isConnected ?: false
	}
}

requestNetwork() 함수 이용하는 방법

  • 네트워크 접속 정보 파악 시 getActiveNetwork()함수 말고 ConnectivityManager 클래스의 requestNetwork() 함수 이용할 수도 있음
  • NetworkRequest 객체를 지정하고, addCapability()함수와 addTransportType() 함수를 이용해 네트워크 타입 지정 가능
  • NetworkRequest 객체에 네트워크 타입 지정한 후에는 requestNetwork() 함수의 매개변수로 지정하여 해당 네트워크 이용 가능 여부를 반환

→ 퍼미션 선언

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
// 네트워크 타입 지정
val networkReq: NetworkRequest = NetworkRequest.Builder()
	.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
	.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
	.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
	.build()

// 네트워크 접속 가능 여부 반환
// 가능하면 onAvailable()함수 호출되고, 불가능하면 onUnavailable()함수 호출됨
connectivityManager.requestNetwork(networkReq, object : ConnectivityManager.NetworkCallback() {
	override fun onAvailable(network: Network) {
		super.onAvailable(network)
		Log.d("kkang", "NetworkCallback...onAvailable...")
	}

	override fun onUnavailable() {
		super.onUnavailable()
		Log.d("kkang", "NetworkCallback...onUnavailable...")
	}
})
profile
기록

0개의 댓글