반응형
시작
Android 11 버전 이상에서 TelephonyManager를 이용해 안드로이드 단말기의 정보를 가져오는 방법에 대해 정리해보려 한다. 가져오는 정보들을 통해 특정 기능들의 활성화 또는 비활성화 처리를 구분 할 수 있으니 응용할 곳이 많다고 할 수 있다.
권한 부여
단말기 정보를 가져오기 위해선 권한을 요청해야 하는데, 전화번호를 가져오는 권한은 아래처럼 변경되었다.
Android 11에서는 앱에서 전화번호를 읽을 때 사용하는 전화 관련 권한이 변경됩니다. 앱이 Android 11 이상을 타겟팅하고 다음 목록에 표시된 전화번호 API에 액세스해야 한다면 READ_PHONE_STATE 권한 대신 READ_PHONE_NUMBERS 권한을 요청해야 합니다.
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
클래스 파일에서 권한을 요청하는 부분에 안드로이드 버전에 따른 분기 처리를 해주도록 한다.
public boolean chkPermission() {
// 위험 권한을 모두 승인했는지 여부
boolean mPermissionsGranted = false;
String[] mRequiredPermissions;
// 사용자의 안드로이드 버전에 따라 권한을 다르게 요청합니다
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// 11 이상인 경우
mRequiredPermissions = new String[2];
mRequiredPermissions[0] = Manifest.permission.READ_PHONE_NUMBERS;
mRequiredPermissions[1] = Manifest.permission.READ_PHONE_STATE;
}else{
// 10 이하인 경우
mRequiredPermissions = new String[1];
mRequiredPermissions[0] = Manifest.permission.READ_PHONE_STATE;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 필수 권한을 가지고 있는지 확인한다.
mPermissionsGranted = hasPermissions(mRequiredPermissions);
// 필수 권한 중에 한 개라도 없는 경우
if (!mPermissionsGranted) {
// 권한을 요청한다.
ActivityCompat.requestPermissions(MainActivity.this, mRequiredPermissions, PERMISSIONS_REQUEST_CODE);
}
} else {
mPermissionsGranted = true;
}
return mPermissionsGranted;
}
public boolean hasPermissions(String[] permissions) {
// 필수 권한을 가지고 있는지 확인한다.
for (String permission : permissions) {
Log.d(TAG, "permission Name: " + permission + ", checkCallingOrSelfPermission: " + checkCallingOrSelfPermission(permission) + ", PERMISSION_GRANTED: " + PackageManager.PERMISSION_GRANTED);
if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
Build.VERSION_CODES.R 이상인 경우 READ_PHONE_NUMBERS와 READ_PHONE_STATE 권한을 요청하고 아닌 경우는 READ_PHONE_STATE 하나만 요청하는 방식으로 구현한다.
단말기 정보 가져오기
단말기 정보는 TelephonyManager 를 통해 가져올 예정이며 IMEI 같은 priv 권한이 필요한 데이터는 제외 했다.
public void getDeviceInfo(){
// READ_PHONE_NUMBERS 또는 READ_PHONE_STATE 권한을 허가 받았는지 확인
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
// 유니크한 단말 번호 >>> Android ID 사용
@SuppressLint("HardwareIds") String android_id = Settings.Secure.getString(this.getContentResolver(),Settings.Secure.ANDROID_ID);
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("HardwareIds")
String text = "음성통화 상태 : [ getCallState ] >>> " + tm.getCallState() + "\\n"
+ "음성통화 상태 : [ getCallState ] >>> " + tm.getCallState() + "\\n"
+ "데이터통신 상태 : [ getDataState ] >>> " + tm.getDataState() + "\\n"
+ "전화번호 : [ getLine1Number ] >>> " + tm.getLine1Number() + "\\n"
+ "통신사 ISO 국가코드 : [ getNetworkCountryIso ] >>> "+tm.getNetworkCountryIso() + "\\n"
+ "통신사 ISO 국가코드 : [ getSimCountryIso ] >>> "+tm.getSimCountryIso() + "\\n"
+ "망사업자 MCC+MNC : [ getNetworkOperator ] >>> "+tm.getNetworkOperator() + "\\n"
+ "망사업자 MCC+MNC : [ getSimOperator ] >>> "+tm.getSimOperator() + "\\n"
+ "망사업자명 : [ getNetworkOperatorName ] >>> "+tm.getNetworkOperatorName() + "\\n"
+ "망사업자명 : [ getSimOperatorName ] >>> "+tm.getSimOperatorName() + "\\n"
+ "SIM 카드 상태 : [ getSimState ] >>> "+tm.getSimState() + "\\n"
+ "데이터 네트워크 상태 : [ getDataNetworkType ] >>> "+tm.getDataNetworkType() + "\\n"
+ "네트워크 상태 : [ getNetworkType ] >>> "+tm.getNetworkType() + "\\n"
+ "음성 네트워크 상태 : [ getVoiceNetworkType ] >>> "+tm.getVoiceNetworkType() + "\\n"
+ "TelephonyManager.NETWORK_TYPE_LTE: " + TelephonyManager.NETWORK_TYPE_LTE + "\\n"
+ "Android_ID >>> "+android_id;
tv.setText(text);
}
전체 코드
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_CODE = 22;
private static final String TAG = "확인";
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
if (chkPermission()) {
// 휴대폰 정보는 TelephonyManager 를 이용
getDeviceInfo();
}
}
public void getDeviceInfo(){
// READ_PHONE_NUMBERS 또는 READ_PHONE_STATE 권한을 허가 받았는지 확인
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
// 유니크한 단말 번호 >>> Android ID 사용
@SuppressLint("HardwareIds") String android_id = Settings.Secure.getString(this.getContentResolver(),Settings.Secure.ANDROID_ID);
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("HardwareIds")
String text = "음성통화 상태 : [ getCallState ] >>> " + tm.getCallState() + "\\n"
+ "음성통화 상태 : [ getCallState ] >>> " + tm.getCallState() + "\\n"
+ "데이터통신 상태 : [ getDataState ] >>> " + tm.getDataState() + "\\n"
+ "전화번호 : [ getLine1Number ] >>> " + tm.getLine1Number() + "\\n"
+ "통신사 ISO 국가코드 : [ getNetworkCountryIso ] >>> "+tm.getNetworkCountryIso() + "\\n"
+ "통신사 ISO 국가코드 : [ getSimCountryIso ] >>> "+tm.getSimCountryIso() + "\\n"
+ "망사업자 MCC+MNC : [ getNetworkOperator ] >>> "+tm.getNetworkOperator() + "\\n"
+ "망사업자 MCC+MNC : [ getSimOperator ] >>> "+tm.getSimOperator() + "\\n"
+ "망사업자명 : [ getNetworkOperatorName ] >>> "+tm.getNetworkOperatorName() + "\\n"
+ "망사업자명 : [ getSimOperatorName ] >>> "+tm.getSimOperatorName() + "\\n"
+ "SIM 카드 상태 : [ getSimState ] >>> "+tm.getSimState() + "\\n"
+ "데이터 네트워크 상태 : [ getDataNetworkType ] >>> "+tm.getDataNetworkType() + "\\n"
+ "네트워크 상태 : [ getNetworkType ] >>> "+tm.getNetworkType() + "\\n"
+ "음성 네트워크 상태 : [ getVoiceNetworkType ] >>> "+tm.getVoiceNetworkType() + "\\n"
+ "TelephonyManager.NETWORK_TYPE_LTE: " + TelephonyManager.NETWORK_TYPE_LTE + "\\n"
+ "Android_ID >>> "+android_id;
tv.setText(text);
}
public boolean chkPermission() {
Log.d(TAG, "SDK version: " + Build.VERSION.SDK_INT);
// 위험 권한을 모두 승인했는지 여부
boolean mPermissionsGranted = false;
String[] mRequiredPermissions;
// 사용자의 안드로이드 버전에 따라 권한을 다르게 요청합니다
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// 11 이상인 경우
mRequiredPermissions = new String[2];
mRequiredPermissions[0] = Manifest.permission.READ_PHONE_NUMBERS;
mRequiredPermissions[1] = Manifest.permission.READ_PHONE_STATE;
}else{
// 10 이하인 경우
mRequiredPermissions = new String[1];
mRequiredPermissions[0] = Manifest.permission.READ_PHONE_STATE;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 필수 권한을 가지고 있는지 확인한다.
mPermissionsGranted = hasPermissions(mRequiredPermissions);
// 필수 권한 중에 한 개라도 없는 경우
if (!mPermissionsGranted) {
// 권한을 요청한다.
ActivityCompat.requestPermissions(MainActivity.this, mRequiredPermissions, PERMISSIONS_REQUEST_CODE);
}
} else {
mPermissionsGranted = true;
}
return mPermissionsGranted;
}
public boolean hasPermissions(String[] permissions) {
// 필수 권한을 가지고 있는지 확인한다.
for (String permission : permissions) {
Log.d(TAG, "permission Name: " + permission + ", checkCallingOrSelfPermission: " + checkCallingOrSelfPermission(permission) + ", PERMISSION_GRANTED: " + PackageManager.PERMISSION_GRANTED);
if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
// 권한을 모두 승인했는지 여부
boolean chkFlag = false;
// 승인한 권한은 0 값, 승인 안한 권한은 -1을 값으로 가진다.
for (int g : grantResults) {
if (g == -1) {
chkFlag = true;
break;
}
}
// 권한 중 한 개라도 승인 안 한 경우
if (chkFlag){
Toast.makeText(getApplicationContext(), "권한 실패했습니다.", Toast.LENGTH_SHORT).show();
}
else getDeviceInfo();
}
}
}
참조
'개발 > Android' 카테고리의 다른 글
[Android] [MediaMetadataRetriever]영상 데이터가 존재하는지 확인하는 법 (0) | 2023.10.20 |
---|---|
[Android] 가로 모드에서 확장형 키보드 막기 (0) | 2023.10.11 |
[Open Source] AudioTrack 소개 및 PCM 파일 재생 (0) | 2023.07.26 |
[Android] 화면 회전 시 onConfigurationChanged 호출 (0) | 2023.07.24 |
[Android] Window에서 LogFilter 사용 하기 (0) | 2023.07.20 |