You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android Oreo及以上版本如何通过代码实现电话挂断?

Android Oreo+ 来电拦截替代方案

Hey there, I’ve dealt with this exact problem when building a call-blocking app for newer Android versions—those old reflection tricks simply don’t work anymore because of strict permission restrictions. Let’s walk through the valid, supported alternatives you can use:

1. Call Screening Service (API 28+)

This is the official, recommended approach from Google for call blocking on Android Pie and above. It’s purpose-built for handling incoming calls and doesn’t rely on any restricted system permissions.

Implementation Steps:

  • Create a class extending CallScreeningService:
    public class MyCallScreeningService extends CallScreeningService {
        @Override
        public void onScreenCall(CallDetails callDetails) {
            // Replace this with your app's logic to decide if the call should be blocked
            boolean shouldBlock = true;
    
            if (shouldBlock) {
                // Reject and disallow the incoming call
                respondToCall(callDetails, new CallResponse.Builder()
                        .setDisallowCall(true)
                        .setRejectCall(true)
                        .build());
            } else {
                // Let the call proceed normally
                respondToCall(callDetails, new CallResponse.Builder()
                        .setAllowCall(true)
                        .build());
            }
        }
    }
    
  • Register the service in your AndroidManifest.xml:
    <service
        android:name=".MyCallScreeningService"
        android:permission="android.permission.BIND_SCREENING_SERVICE">
        <intent-filter>
            <action android:name="android.intent.action.ANSWER_PHONE_CALL" />
        </intent-filter>
    </service>
    
  • Request required runtime permissions:
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1001);
    }
    
    Note: Android will automatically prompt users to set your app as the default call screening app the first time you use this service—this is a required step for it to work.

2. Accessibility Service (API 26-27)

For Android Oreo (API 26) and Pie (API 27) before Call Screening Service existed, your only viable option is to use an Accessibility Service. This requires users to manually enable accessibility for your app in system settings (a minor UX tradeoff, but it’s the only way).

Implementation Steps:

  • Create a class extending AccessibilityService:
    public class CallBlockAccessibilityService extends AccessibilityService {
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                String packageName = event.getPackageName().toString();
                // Target common phone app packages (adjust for OEM-specific dialers if needed)
                if (packageName.equals("com.android.phone") || packageName.equals("com.google.android.dialer")) {
                    // Simulate pressing the system's "End Call" action
                    performGlobalAction(GLOBAL_ACTION_CALL_END);
                }
            }
        }
    
        @Override
        public void onInterrupt() {}
    
        @Override
        protected void onServiceConnected() {
            super.onServiceConnected();
            AccessibilityServiceInfo info = new AccessibilityServiceInfo();
            info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
            info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
            setServiceInfo(info);
        }
    }
    
  • Register the service in AndroidManifest.xml:
    <service
        android:name=".CallBlockAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_service_config" />
    </service>
    
  • Create the accessibility config file (res/xml/accessibility_service_config.xml):
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityEventTypes="typeWindowStateChanged"
        android:accessibilityFeedbackType="feedbackGeneric"
        android:accessibilityFlags="flagDefault"
        android:description="@string/accessibility_service_desc" />
    
    Add a user-friendly description in strings.xml explaining what the service does—users will see this when enabling accessibility for your app.

Why Your Original Approach Fails

Starting with Android Oreo, the MODIFY_PHONE_STATE permission is locked to system apps exclusively. Third-party apps can’t request or use it, no matter how you try to bypass lint checks. That’s exactly why your reflection of ITelephony.endCall() throws the permission error. The methods above are the only supported ways to block calls on modern Android versions.

内容的提问来源于stack exchange,提问作者user11068505

火山引擎 最新活动