앱을 개발하다 보면 IMEI처럼 기기를 고유하게 식별할 수 있는 ID가 필요한 순간이 종종 있습니다. 안드로이드에서는 TelephonyManager 클래스를 활용하면 프로그래밍 방식으로 이러한 고유 기기 ID를 손쉽게 조회할 수 있습니다. 지금부터 단계별로 자세히 살펴보겠습니다.
1단계 — 새 프로젝트 생성
Android Studio에서 File → New Project 메뉴로 이동한 뒤, 프로젝트 생성에 필요한 정보를 모두 입력하여 새 프로젝트를 만듭니다.
2단계 — 레이아웃 파일 작성
res/layout/activity_main.xml 파일에 다음 코드를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click here to hide"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
3단계 — MainActivity 구현
src/MainActivity.java 파일에 다음 코드를 추가합니다.
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TelephonyManager telephonyManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(this);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
deviceId();
break;
}
}
private void deviceId() {
telephonyManager = (TelephonyManager) getSystemService(this.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 101);
return;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
switch (requestCode) {
case 101:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 101);
return;
}
String imeiNumber = telephonyManager.getDeviceId();
Toast.makeText(MainActivity.this,imeiNumber,Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this,"Without permission we check",Toast.LENGTH_LONG).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
위 코드의 핵심은 런타임 권한 처리입니다. READ_PHONE_STATE 권한이 허용되지 않으면 기기 ID를 가져올 수 없기 때문에, 권한이 없을 경우 먼저 사용자에게 권한을 요청하고 그 결과는 onRequestPermissionsResult() 콜백에서 처리하도록 구성했습니다.
기기 ID를 조회하는 핵심 코드는 다음 세 줄입니다.
TelephonyManager telephonyManager; telephonyManager = (TelephonyManager) getSystemService(this.TELEPHONY_SERVICE); String imeiNumber = telephonyManager.getDeviceId();
4단계 — 매니페스트에 권한 선언
AndroidManifest.xml 파일에 다음 코드를 추가합니다.
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.andy.myapplication">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
여기서 선언한 READ_PHONE_STATE 권한은 전화 상태 정보를 읽어오기 위해 반드시 필요합니다.
앱 실행 및 결과 확인
실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정하고 앱을 실행해 보겠습니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의
Run 아이콘을 클릭합니다. 기기 선택 목록에서 본인의 모바일 기기를 고르면 해당 기기에 앱이 설치·실행됩니다.

버튼을 클릭하면 런타임 권한을 요청하는 대화상자가 나타납니다. IMEI 번호를 얻으려면 사용자가 반드시 권한을 허용해야 합니다.

권한이 승인되면 화면에 IMEI 번호, 즉 기기의 고유 번호가 표시됩니다. (보안상의 이유로 여기서는 실제 고유 번호를 가렸습니다.)

반대로 사용자가 런타임 권한을 거부하면 위와 같이 "권한 없이는 확인할 수 없다"는 메시지가 표시됩니다.
참고: 최신 안드로이드 버전에서의 주의 사항
getDeviceId()는 API 26(오레오)부터 공식적으로 지원 중단(deprecated)되었으므로, 가능하다면 getImei() 또는 getMeid()를 사용하는 것이 좋습니다. 또한 안드로이드 10(API 29)부터는 개인정보 보호 정책이 강화되어 일반 서드파티 앱의 IMEI 접근이 제한됩니다. 따라서 최신 OS를 대상으로 하는 앱이라면 Settings.Secure.ANDROID_ID 같은 대체 식별자를 함께 검토하는 것이 바람직합니다.