Android 11中通过代码调用实现飞行模式开关(替代长按Home键)
解决方案
针对你需要直接通过代码触发飞行模式开关、无需模拟长按Home键的需求,提供两种适配Android 11的实现方案:
方案1:基于现有VoiceInteractionService逻辑改造
将原onHandleAssist中的飞行模式操作抽为独立方法,直接调用即可触发,无需依赖长按Home的系统触发逻辑:
1. 改造MyInteractionSession类,提取开关逻辑
public class MyInteractionSession extends VoiceInteractionSession { MyInteractionSession(Context context) { super(context); } @Override public void onCreate() { super.onCreate(); } @Override public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { super.onHandleAssist(data, structure, content); toggleAirplaneMode(true); // 复用独立方法 } // 独立的飞行模式开关方法,外部可直接调用 public void toggleAirplaneMode(boolean enable) { // 沿用原VoiceControl意图 Intent intent = new Intent("android.settings.VOICE_CONTROL_AIRPLANE_MODE"); intent.putExtra("airplane_mode_enabled", enable); startVoiceActivity(intent); // 同步更新系统设置并发送广播,确保状态一致 Settings.System.putInt(getContext().getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enable ? 1 : 0); getContext().sendBroadcast(new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)); } }
2. 修改MyInteractionSessionService,暴露会话实例
通过自定义Binder让外部组件获取会话实例,从而调用开关方法:
public class MyInteractionSessionService extends VoiceInteractionSessionService { private MyInteractionSession mSession; @Override public VoiceInteractionSession onNewSession(Bundle bundle) { mSession = new MyInteractionSession(this); return mSession; } // 自定义Binder类 public class MyBinder extends Binder { public MyInteractionSession getSession() { return mSession; } } private final IBinder mBinder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; } }
3. 在需要触发的组件(如Activity)中调用
通过绑定服务获取会话实例,直接调用开关方法:
public class MainActivity extends AppCompatActivity { private MyInteractionSession mSession; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { MyInteractionSessionService.MyBinder binder = (MyInteractionSessionService.MyBinder) service; mSession = binder.getSession(); // 开启飞行模式 mSession.toggleAirplaneMode(true); // 如需关闭则调用:mSession.toggleAirplaneMode(false); } @Override public void onServiceDisconnected(ComponentName name) { mSession = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 绑定会话服务 Intent intent = new Intent(this, MyInteractionSessionService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(mConnection); } }
方案2:直接使用系统Settings API(无需依赖VoiceInteractionService)
如果不需要绑定VoiceInteraction服务,可直接通过系统Settings类修改飞行模式,但Android 11需额外获取修改系统设置的权限:
1. 声明权限(AndroidManifest.xml)
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
2. 实现开关逻辑
public void toggleAirplaneMode(Context context) { // 检查是否拥有修改系统设置的权限 if (Settings.System.canWrite(context)) { boolean isAirplaneModeOn = Settings.System.getInt( context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1; // 切换飞行模式状态 Settings.System.putInt( context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, isAirplaneModeOn ? 0 : 1); // 发送广播通知系统状态变更 context.sendBroadcast(new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)); } else { // 引导用户手动授权 Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } }
关键注意事项
- 确保你的应用已设置为默认设备助手(方案1的前提);
- 方案2需用户手动在系统设置中授权“允许修改系统设置”;
- 修改飞行模式后必须发送
Intent.ACTION_AIRPLANE_MODE_CHANGED广播,确保系统和第三方应用感知状态变化。
内容的提问来源于stack exchange,提问作者Robotic Vn
相关产品推荐
相关产品推荐

