You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:TelephonyManager.setRadioPower无法解析问题求助

Fixing "cannot resolve 'setRadioPower(?)'" Error & Implementing Call-State Based Cellular Radio Toggle

Hey there! Let's break down why you're hitting that error and get your feature working properly.

Why the setRadioPower Error Happens

The setRadioPower() method you're trying to use is a hidden system API—it's not available to regular third-party apps. Even if you could resolve the method call, Android restricts access to this functionality (especially from Android 10/API 29 onwards) to system-level apps only. On top of that, your code uses an undefined disabled value, which adds to the error.

Correct Approach to Toggle Cellular Radio

Instead of relying on the hidden API, we'll use official, supported methods based on the Android version. Here's how to implement your desired logic:

Step 1: Update Permissions in AndroidManifest.xml

Add the necessary permissions to modify network state and access phone info:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
          package="com.example.vk9621.radiocall">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <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>

Step 2: Modified MainActivity.java Code

This code handles dynamic permissions, call state listening, and uses version-appropriate methods to toggle cellular data:

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

public class MainActivity extends AppCompatActivity {
    private TelephonyManager telephonyManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Check for READ_PHONE_STATE permission first
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_PHONE_STATE}, 100);
            return;
        }

        telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        PhoneStateListener callStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                switch (state) {
                    case TelephonyManager.CALL_STATE_RINGING:
                        Toast.makeText(getApplicationContext(), "Phone Is Ringing", Toast.LENGTH_LONG).show();
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        Toast.makeText(getApplicationContext(), "Phone is Currently in A call", Toast.LENGTH_LONG).show();
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:
                        // Disable cellular radio when device is idle (not ringing/calling)
                        toggleCellularRadio(false);
                        break;
                }
            }
        };

        telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    private void toggleCellularRadio(boolean enable) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                // For Android 12+ (API 31+), use official TelephonyManager method
                if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CHANGE_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CHANGE_NETWORK_STATE}, 101);
                    return;
                }
                // Use default subscription ID (adjust for multi-SIM devices if needed)
                int defaultSubId = telephonyManager.getSubscriptionId();
                telephonyManager.setCellularDataEnabled(defaultSubId, enable);
            } else {
                // For older Android versions, modify system settings
                if (!Settings.System.canWrite(this)) {
                    // Request WRITE_SETTINGS permission via system settings
                    Intent settingsIntent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                    startActivity(settingsIntent);
                    return;
                }
                Settings.Secure.putInt(getContentResolver(), Settings.Secure.MOBILE_DATA, enable ? 1 : 0);
            }
            Toast.makeText(this, enable ? "Cellular radio turned ON" : "Cellular radio turned OFF", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "Failed to toggle cellular radio", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 100:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Re-initialize after permission is granted
                    recreate();
                } else {
                    Toast.makeText(this, "READ_PHONE_STATE permission is required to detect calls", Toast.LENGTH_SHORT).show();
                }
                break;
            case 101:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    toggleCellularRadio(false);
                } else {
                    Toast.makeText(this, "CHANGE_NETWORK_STATE permission is required to toggle radio", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}

Key Notes to Keep in Mind

  • Dynamic Permissions: Android 6.0+ requires runtime permissions for READ_PHONE_STATE and CHANGE_NETWORK_STATE. The WRITE_SETTINGS permission can't be requested via standard dialogs—users have to enable it manually through system settings.
  • Multi-SIM Devices: The code uses the default SIM subscription. If you need to handle multiple SIMs, you'll need to fetch all subscription IDs and toggle each one individually.
  • Manufacturer Restrictions: Some Android OEMs may restrict third-party apps from modifying cellular data settings. Adding error handling ensures your app doesn't crash if this happens.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:29:44