Android开发:TelephonyManager.setRadioPower无法解析问题求助
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_STATEandCHANGE_NETWORK_STATE. TheWRITE_SETTINGSpermission 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

