IT_Programming/Android_Java

[Android] Telephony

JJun ™ 2013. 1. 16. 19:07



 출처: http://jasperslab.blogspot.kr/2013/01/android-telephony.html



[1] TelephonyManager 얻기



 TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);



[2] 기본 정보 얻기


어떤 메소드는 정보들을 조회하기 위해서는 permission이 필요로 한다.
메소드 뒤쪽에 주석으로 필요로 하는 permission을 추가해 두었다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
String deviceId = manager.getDeviceId();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, deviceId);//result: 358697045364974
 
String deviceSoftwareVersion = manager.getDeviceSoftwareVersion();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, deviceSoftwareVersion);//result: 01
 
String line1Number = manager.getLine1Number();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, line1Number == null ? "null" : line1Number);//result: null
 
String subscriberId = manager.getSubscriberId();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, subscriberId == null ? "null" : subscriberId);//result: 450084910074771
 
String voiceMailNumber = manager.getVoiceMailNumber();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, voiceMailNumber == null ? "null" : voiceMailNumber);//result: *88
 
String voiceMailAlphaTag = manager.getVoiceMailAlphaTag();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, voiceMailAlphaTag);//result: 음성메일
 
int phoneType = manager.getPhoneType();
switch (phoneType) {
case TelephonyManager.PHONE_TYPE_NONE:
 Log.d(TAG, "PHONE_TYPE_NONE");
 break;
case TelephonyManager.PHONE_TYPE_GSM:
 Log.d(TAG, "PHONE_TYPE_GSM");
 break;
case TelephonyManager.PHONE_TYPE_CDMA:
 Log.d(TAG, "PHONE_TYPE_CDMA");
 break;
case TelephonyManager.PHONE_TYPE_SIP:
 Log.d(TAG, "PHONE_TYPE_SIP");
 break;
}//result: PHONE_TYPE_GSM



[3] Network 정보 얻기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//start
String networkCountryIso = manager.getNetworkCountryIso();
Log.d(TAG, "networkCountryIso: " + networkCountryIso);//result: kr
 
String networkOperator = manager.getNetworkOperator();
Log.d(TAG, "networkOperator: " + networkOperator);//result: 45008
 
String networkOperatorName = manager.getNetworkOperatorName();
Log.d(TAG, "networkOperatorName: " + networkOperatorName);//result: olleh
 
int networkType = manager.getNetworkType();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
 Log.d(TAG, "NETWORK_TYPE_UNKNOWN");
 break;
case TelephonyManager.NETWORK_TYPE_GPRS:
 Log.d(TAG, "NETWORK_TYPE_GPRS");
 break;
case TelephonyManager.NETWORK_TYPE_EDGE:
 Log.d(TAG, "NETWORK_TYPE_EDGE");
 break;
case TelephonyManager.NETWORK_TYPE_UMTS:
 Log.d(TAG, "NETWORK_TYPE_UMTS");
 break;
case TelephonyManager.NETWORK_TYPE_HSDPA:
 Log.d(TAG, "NETWORK_TYPE_HSDPA");
 break;
case TelephonyManager.NETWORK_TYPE_HSUPA:
 Log.d(TAG, "NETWORK_TYPE_HSUPA");
 break;
case TelephonyManager.NETWORK_TYPE_CDMA:
 Log.d(TAG, "NETWORK_TYPE_CDMA");
 break;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
 Log.d(TAG, "NETWORK_TYPE_EVDO_0");
 break;
case TelephonyManager.NETWORK_TYPE_EVDO_A:
 Log.d(TAG, "NETWORK_TYPE_EVDO_A");
 break;
case TelephonyManager.NETWORK_TYPE_EVDO_B:
 Log.d(TAG, "NETWORK_TYPE_EVDO_B");
 break;
case TelephonyManager.NETWORK_TYPE_1xRTT:
 Log.d(TAG, "NETWORK_TYPE_1xRTT");
 break;
case TelephonyManager.NETWORK_TYPE_IDEN:
 Log.d(TAG, "NETWORK_TYPE_IDEN");
 break;
case TelephonyManager.NETWORK_TYPE_LTE:
 Log.d(TAG, "NETWORK_TYPE_LTE");
 break;
case TelephonyManager.NETWORK_TYPE_EHRPD:
 Log.d(TAG, "NETWORK_TYPE_EHRPD");
 break;
case TelephonyManager.NETWORK_TYPE_HSPAP:
 Log.d(TAG, "NETWORK_TYPE_HSPAP");
 break;
}//result: NETWORK_TYPE_UMTS
//finish



[4] SIM 정보 얻기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//start
String simCountryIso = manager.getSimCountryIso();
Log.d(TAG, "simCountryIso: "+simCountryIso);//result: kr
 
String simSerialNumber = manager.getSimSerialNumber();//Requires Permission: READ_PHONE_STATE
Log.d(TAG, "simSerialNumber: "+simSerialNumber);//result: 89***006****2152***
 
int simState = manager.getSimState();
switch (simState) {
case TelephonyManager.SIM_STATE_UNKNOWN:
 Log.d(TAG, "SIM_STATE_UNKNOWN");
 break;
case TelephonyManager.SIM_STATE_ABSENT:
 Log.d(TAG, "SIM_STATE_ABSENT");
 break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
 Log.d(TAG, "SIM_STATE_PIN_REQUIRED");
 break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
 Log.d(TAG, "SIM_STATE_PUK_REQUIRED");
 break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
 Log.d(TAG, "SIM_STATE_NETWORK_LOCKED");
 break;
case TelephonyManager.SIM_STATE_READY:
 Log.d(TAG, "SIM_STATE_READY");
 String simOperator = manager.getSimOperator();//Availability: SIM state must be SIM_STATE_READY
 Log.d(TAG, "simOperator: "+simOperator);//result: 45008
 String simOperatorName = manager.getSimOperatorName();//Availability: SIM state must be SIM_STATE_READY
 Log.d(TAG, "simOperatorName: "+simOperatorName);//result: KT
 break;
}
//finish

SIM 카드는 가입자 식별 모듈(Subscriber Identification Module)을 구현한 IC 카드이다. GSM 단말기는 필수 요소이다.
SIM 카드는 ICCID라고 불리우는 고유한 번호가 있다. 이 번호는 89로 시작하는 19자리 숫자이다.
Android에서는 
getSimSerialNumber() 메소드로 이를 알아낼 수 있다.

사용 중인 SIM 카드에는 IMSI (International Mobile Subscriber Identity)라는 가입자 식별 번호가 들어있다.
IMSI가 등록된 SIM 카드를 꽂으면 자신의 단말기처럼 사용할 수 있다. Android에서는 
getSubscriberId() 메소드로 이를 알아낼 수 있다.

이와 유사한 번호인 IMEI (International  Mobile Equipment Identity)라는 장비 식별 번호가 있다.
Android에서는 
getDeviceId() 메소드로 이를 알아낼 수 있다.

참고로, PIN (Personal Identification Number)은 초기에는 [0000] 4자리 숫자로 되어 있고, 사용자의  필요에 따라 4~8자리로 변경할 수 있는 있다.
보통은 패스워드처럼 사용되고 있다. PIN을 3번 연속 잘못 입력하게 되면 SIM이 잠기게 된다. 재설정하기 위해서는 PUK를 입력해야 한다.
PUK (PIN Unblock Key)는 SIM 카드마다 할당된 8자리 숫자로 된 2차 보안 장치이다.
PUK를 10회 연속 잘못 입력하게 되면 SIM 카드가 폐기되어 영구적으로 사용이 불가능하다.
Android에서는 이와 관련된 
상태 정보만을 얻을 수 있다.



[5] Data 정보 얻기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//start
int dataActivityType = manager.getDataActivity();
switch (dataActivityType) {
case TelephonyManager.DATA_ACTIVITY_NONE:
 Log.d(TAG, "DATA_ACTIVITY_NONE");
 break;
case TelephonyManager.DATA_ACTIVITY_IN:
 Log.d(TAG, "DATA_ACTIVITY_IN");
 break;
case TelephonyManager.DATA_ACTIVITY_OUT:
 Log.d(TAG, "DATA_ACTIVITY_OUT");
 break;
case TelephonyManager.DATA_ACTIVITY_INOUT:
 Log.d(TAG, "DATA_ACTIVITY_INOUT");
 break;
case TelephonyManager.DATA_ACTIVITY_DORMANT:
 Log.d(TAG, "DATA_ACTIVITY_DORMANT");
 break;
}//result: DATA_ACTIVITY_NONE
 
int dataState = manager.getDataState();
switch (dataState) {
case TelephonyManager.DATA_DISCONNECTED:
 Log.d(TAG, "DATA_DISCONNECTED");
 break;
case TelephonyManager.DATA_CONNECTING:
 Log.d(TAG, "DATA_CONNECTING");
 break;
case TelephonyManager.DATA_CONNECTED:
 Log.d(TAG, "DATA_CONNECTED");
 break;
case TelephonyManager.DATA_SUSPENDED:
 Log.d(TAG, "DATA_SUSPENDED");
 break;
}//result: DATA_CONNECTED
//finish



[6] CellLocation 정보 얻기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//start
//Requires Permission: ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
GsmCellLocation cellLocation = (GsmCellLocation) manager.getCellLocation();
if (cellLocation == null) {
 Log.d(TAG, "current location is not available");
} else {
 int cid = cellLocation.getCid();
 Log.d(TAG, "cid: "+cid);//result: 92373771
  
 int lac = cellLocation.getLac();
 Log.d(TAG, "lac: "+lac);//result: 45057
  
 int psc = cellLocation.getPsc();
 Log.d(TAG, "psc: "+psc);//result: -1
  
 String description = cellLocation.toString();
 Log.d(TAG, "description: "+description);//result: [45057,92373771,-1]
}
//finish

단, 위 코드로 획득한 정보는 그리 유용하지 않다고 합니다. 
[
http://www.google.com/glm/mmap] url은 아직 공개된 API는 아니지만 이를 이용한 좌표 산출 소스를 포스팅하셨네요. 

참고는 여기입니다.


[7] 상태 변화 청취하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//start [Requires Permission: READ_PHONE_STATE]
//Listener
PhoneStateListener phoneStateListener = new PhoneStateListener() {
 @Override
 public void onCallForwardingIndicatorChanged(boolean cfi) {
  Log.d(TAG, onCallForwardingIndicatorChanged: "+cfi);//result: false
 }
  
 @Override
 public void onCallStateChanged(int state, String incomingNumber) {
  String in = incomingNumber == null ? "null" : incomingNumber;
  in = in.equals("") ? "null" : in;
  Log.d(TAG, onCallStateChanged.incomingNumber: "+in);//result: null
   
  switch (state) {
  case TelephonyManager.CALL_STATE_IDLE:
   Log.d(TAG, "CALL_STATE_IDLE");
   break;
  case TelephonyManager.CALL_STATE_OFFHOOK:
   Log.d(TAG, "CALL_STATE_OFFHOOK");
   break;
  case TelephonyManager.CALL_STATE_RINGING:
   Log.d(TAG, "CALL_STATE_RINGING");
   break;
  }//result: CALL_STATE_IDLE
 }
};
 
//Listener 등록
manager.listen(phoneStateListener,
  PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | PhoneStateListener.LISTEN_CALL_STATE);
 
//Listener 해제
manager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
//finish


PhoneStateListener 클래스는 인터페이스가 아니다. 청취할 수 있는 대상에 대해서는 여기를 참고하자.