Android 《回到桌面与切换到任务列表》
App不但能监测手机屏幕的方向变更,还能获知回到桌面的事件,连打开任务列表的事件也能实时得知。回到桌面与打开任务列表都由按键触发,例如按下主页键会回到桌面,按下任务键会打开任务列表。虽然这两个操作看起来属于按键事件,但系统并未提供相应的按键处理方法,而是通过广播发出事件信息。因此,若想知晓是否回到桌面,以及是否打开任务列表,均需收听系统广播Intent.ACTION_CLOSE_SYSTEM_DIALOGS。至于如何区分当前广播究竟是回到桌面还是打开任务列表,则要从广播意图中获取原因reason字段,该字段值为homekey时表示回到桌面,值为recentapps时表示打开任务列表。接下来演示一下此类广播的接收过程。首先定义一个广播接收器,只处理动作为Intent.ACTION_CLOSE_SYSTEM_DIALOGS的系统广播,并判断它是主页键来源还是任务键来源。该接收器的代码定义示例如下:
// 定义一个返回到桌面的广播接收器 private class DesktopRecevier extends BroadcastReceiver { // 在收到返回桌面广播时触发 @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra("reason"); // 获取变更原因 // 按下了主页键或者任务键 if (!TextUtils.isEmpty(reason) && (reason.equals("homekey")|| reason.equals("recentapps"))) { showChangeStatus(reason); // 显示变更的状态 } } } }
接着在活动页面的onCreate方法中注册接收器,在onDestroy方法中注销接收器,其中接收器的注册代码如下所示:
private DesktopRecevier desktopRecevier; // 声明一个返回桌面的广播接收器对象 // 初始化桌面广播 private void initDesktopRecevier() { desktopRecevier = new DesktopRecevier(); // 创建一个返回桌面的广播接收器 // 创建一个意图过滤器,只接收关闭系统对话框(即返回桌面)的广播 IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); registerReceiver(desktopRecevier, intentFilter); // 注册接收器,注册之后才能正常接收广播 }
可是监听回到桌面的广播能用来干什么呢?一种用处是开启App的画中画模式,比如原先应用正在播放视频,回到桌面时势必要暂停播放,有了画中画模式之后,可将播放界面缩小为屏幕上的一个小方块,这样即使回到桌面也能继续观看视频。注意从Android 8.0开始才提供画中画模式,故而代码需要判断系统版本,下面是进入画中画模式的代码例子:
// 显示变更的状态 private void showChangeStatus(String reason) { mDesc = String.format("%s%s 按下了%s键\n", mDesc, DateUtil.getNowTime(), reason); tv_monitor.setText(mDesc); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isInPictureInPictureMode()) { // 当前未开启画中画,则开启画中画模式 // 创建画中画模式的参数构建器 PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder(); // 设置宽高比例值,第一个参数表示分子,第二个参数表示分母 // 下面的10/5=2,表示画中画窗口的宽度是高度的两倍 Rational aspectRatio = new Rational(10,5); builder.setAspectRatio(aspectRatio); // 设置画中画窗口的宽高比例 // 进入画中画模式,注意enterPictureInPictureMode是Android8.0之后新增的方法 enterPictureInPictureMode(builder.build()); } }
以上代码用于开启画中画模式,但有时希望在进入画中画之际调整界面,则需重写活动的onPictureInPictureModeChanged方法,该方法在应用进入画中画模式或退出画中画模式时触发,在此可补充相应的处理逻辑。重写后的方法代码示例如下:
// 在进入画中画模式或退出画中画模式时触发 @Override public void onPictureInPictureModeChanged(boolean isInPicInPicMode, Configuration newConfig) { Log.d(TAG, "onPictureInPictureModeChanged isInPicInPicMode="+isInPicInPicMode); super.onPictureInPictureModeChanged(isInPicInPicMode, newConfig); if (isInPicInPicMode) { // 进入画中画模式 } else { // 退出画中画模式 } }
另外,画中画模式要求在AndroidManifest.xml中开启画中画支持,也就是给activity节点添加supportsPictureInPicture属性并设为true,添加新属性之后的activity配置示例如下:
<activity android:name=".ReturnDesktopActivity" android:configChanges="orientation|screenLayout|screenSize" android:supportsPictureInPicture="true" android:theme="@style/AppCompatTheme" />
完整代码
AndroidManifest.xml
<activity android:name=".ui.ReturnDeskActivity" android:exported="true" android:configChanges="orientation|screenLayout|screenSize" android:supportsPictureInPicture="true" />
ReturnDeskActivity.java
public class ReturnDeskActivity extends AppCompatActivity { private DesktopReceiver desktopRecevier; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_return_desk); desktopRecevier = new DesktopReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); registerReceiver(desktopRecevier, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(desktopRecevier); } // 在进入画中画模式或退出画中画模式时触发 @Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); if (isInPictureInPictureMode){ Log.d("xian","进入画中画模式"); }else{ Log.d("xian","退出画中画模式"); } } /** * 定义一个返回桌面的广播接收器 */ private class DesktopReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if(intent!=null && intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)){ String reason = intent.getStringExtra("reason"); if (!TextUtils.isEmpty(reason) && (reason.equals("homekey") || reason.equals("recentapps"))){ // Android 8.0开始才提供画中画模式 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isInPictureInPictureMode()){ // 创建画中画模式的参数构建器 PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder(); // 设置宽高比例值,第一个参数表示分子,第二个参数表示分母 // 下面的10/5=2,表示画中画窗口的宽度是高度的两倍 // 设置画中画窗口的宽高比例 Rational ratio = new Rational(10, 5); builder.setAspectRatio(ratio); // 进入画中画模式 enterPictureInPictureMode(builder.build()); } } } } } }
本文来自博客园,作者:一个小笨蛋,转载请注明原文链接:https://www.cnblogs.com/paylove/p/18066113
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效