Android SDK 31对电话相关的权限和API做了调整,监听电话状态变化需要遵循新的规范,避免因为权限不足或者API过时导致功能失效。开发者需要同时处理普通权限声明、动态权限申请以及回调逻辑适配三个核心环节,才能稳定获取电话状态的变化信息。

核心权限声明
首先需要在AndroidManifest.xml中声明对应的权限,Android SDK 31中监听电话状态需要用到READ_PHONE_STATE权限,这个权限属于危险权限,仅声明无法直接使用,还需要动态申请。
<!-- 声明读取电话状态权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 如果需要获取来电号码,还需要声明READ_CALL_LOG权限,同样属于危险权限 --> <uses-permission android:name="android.permission.READ_CALL_LOG" />
动态权限申请
由于READ_PHONE_STATE和READ_CALL_LOG都是危险权限,在Android 6.0及以上版本都需要动态申请,SDK 31中申请流程和之前版本基本一致,需要在Activity或者Fragment中发起申请。
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;
public class PhoneStateActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PHONE_STATE = 1001;
// 需要申请的权限列表
private String[] requiredPermissions = {
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_CALL_LOG
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_state);
checkAndRequestPermissions();
}
// 检查并申请权限
private void checkAndRequestPermissions() {
List<String> needRequestPermissions = new ArrayList<>();
for (String permission : requiredPermissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
needRequestPermissions.add(permission);
}
}
if (!needRequestPermissions.isEmpty()) {
ActivityCompat.requestPermissions(this, needRequestPermissions.toArray(new String[0]), REQUEST_CODE_PHONE_STATE);
} else {
// 权限已经全部授予,初始化电话状态监听
initPhoneStateListener();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PHONE_STATE) {
boolean allGranted = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allGranted = false;
break;
}
}
if (allGranted) {
initPhoneStateListener();
} else {
// 权限被拒绝,提示用户功能无法使用
}
}
}
}
电话状态监听实现
Android SDK 31中仍然使用TelephonyManager配合PhoneStateListener来监听电话状态,不过需要注意PhoneStateListener的部分回调方法在SDK 31中已经过时,需要使用新的替代方法。
初始化监听对象
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.content.Context;
public class PhoneStateActivity extends AppCompatActivity {
private TelephonyManager telephonyManager;
private MyPhoneStateListener phoneStateListener;
private void initPhoneStateListener() {
// 获取TelephonyManager实例
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new MyPhoneStateListener();
// 注册监听,监听电话状态变化,SDK 31中推荐使用的注册方式
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
// 自定义电话状态监听器
private static class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
// 电话空闲状态,没有通话也没有来电
break;
case TelephonyManager.CALL_STATE_RINGING:
// 来电响铃状态,phoneNumber为来电号码(需要READ_CALL_LOG权限)
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// 通话中状态,包括拨打接通、接听来电
break;
default:
break;
}
}
}
}
释放监听资源
当页面销毁或者不需要监听的时候,需要及时取消注册,避免内存泄漏。
@Override
protected void onDestroy() {
super.onDestroy();
if (telephonyManager != null && phoneStateListener != null) {
// 取消监听
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
}
常见注意事项
- 如果没有申请
READ_CALL_LOG权限,onCallStateChanged回调中的phoneNumber参数会返回空字符串,无法获取来电号码。 - Android SDK 31中
PhoneStateListener的LISTEN_SERVICE_STATE等常量仍然可用,如果需要监听更多状态可以按需添加注册参数。 - 部分定制系统可能对电话状态监听做了限制,需要在系统设置中允许应用获取电话相关权限,否则回调可能无法触发。
- 不要在
onCallStateChanged回调中做耗时操作,避免阻塞主线程导致监听异常。
Android_SDK_31电话状态监听TelephonyManagerPhoneStateListenerAndroid权限修改时间:2026-06-10 05:42:26