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