如何使用CallScreeningService API获取来电号码并在Activity中注册服务
Android CallScreeningService 实现与Activity集成指南
1. 清单文件中声明服务与权限
首先必须在AndroidManifest.xml中注册你的CallScreeningService子类,并添加必要权限:
<!-- 基础权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <!-- Android 10+ 需添加 --> <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> <!-- Android 12+ 需添加 --> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <application ...> <service android:name=".YourCallScreeningService" android:permission="android.permission.BIND_SCREENING_SERVICE"> <intent-filter> <action android:name="android.telecom.CallScreeningService" /> </intent-filter> </service> </application>
2. Activity中请求动态权限
上述权限均为危险权限,需在Activity中动态申请:
private static final int REQUEST_PERM = 100; private String[] getRequiredPermissions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { return new String[]{ Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.READ_CALL_LOG }; } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { return new String[]{ Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, Manifest.permission.ANSWER_PHONE_CALLS }; } else { return new String[]{ Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE }; } } // 在Activity初始化时调用 private void checkAndRequestPermissions() { boolean allGranted = true; for (String perm : getRequiredPermissions()) { if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (!allGranted) { ActivityCompat.requestPermissions(this, getRequiredPermissions(), REQUEST_PERM); } else { setDefaultScreeningApp(); } } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERM) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { setDefaultScreeningApp(); } else { Toast.makeText(this, "需授予全部权限才能使用来电筛选功能", Toast.LENGTH_SHORT).show(); } } }
3. 设置应用为默认来电筛选应用
只有被设为默认的应用才能收到来电回调,在Activity中添加以下代码:
private static final int REQUEST_SET_DEFAULT = 200; private void setDefaultScreeningApp() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE); if (telecomManager == null) return; ComponentName serviceComponent = new ComponentName(this, YourCallScreeningService.class); String currentDefault = telecomManager.getDefaultCallScreeningApp(); if (!serviceComponent.flattenToString().equals(currentDefault)) { Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_CALL_SCREENING_APP); intent.putExtra(TelecomManager.EXTRA_CALL_SCREENING_COMPONENT_NAME, serviceComponent); startActivityForResult(intent, REQUEST_SET_DEFAULT); } } } // 处理默认应用设置结果 @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_SET_DEFAULT) { if (resultCode == RESULT_OK) { Toast.makeText(this, "已设为默认来电筛选应用", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "未设置默认应用,无法获取来电信息", Toast.LENGTH_SHORT).show(); } } }
4. 在服务类中获取来电号码
你的YourCallScreeningService子类中,重写onScreenCall方法即可获取来电信息:
public class YourCallScreeningService extends CallScreeningService { @Override public void onScreenCall(Call.Details callDetails) { // 获取来电号码 String phoneNumber = callDetails.getHandle().getSchemeSpecificPart(); Log.d("CallLog", "来电号码:" + phoneNumber); // 允许通话(如需拦截可调用responseBuilder.setDisallowCall(true)) CallResponse response = new CallResponse.Builder().build(); respondToCall(callDetails, response); // 可通过广播/ViewModel等方式将号码传递给Activity sendCallNumberToActivity(phoneNumber); } // 示例:用LocalBroadcast传递数据到Activity private void sendCallNumberToActivity(String number) { Intent intent = new Intent("com.your.package.CALL_RECEIVED"); intent.putExtra("PHONE_NUMBER", number); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } }
5. Activity接收来电数据
以LocalBroadcast为例,在Activity中注册接收器:
private BroadcastReceiver callReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String number = intent.getStringExtra("PHONE_NUMBER"); // 更新UI或处理号码 tvCallNumber.setText("收到来电:" + number); } }; @Override protected void onResume() { super.onResume(); LocalBroadcastManager.getInstance(this) .registerReceiver(callReceiver, new IntentFilter("com.your.package.CALL_RECEIVED")); } @Override protected void onPause() { super.onPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(callReceiver); }
内容的提问来源于stack exchange,提问作者Akshay M Joshi
相关产品推荐
相关产品推荐

