按下主页键会回到桌面,按下任务键会打开任务列表,这两个操作并未提供相应的按键处理方法,而是通过广播发出事件信息。
若想知晓是否回到桌面,以及是否打开任务列表,均需收听系统广播Intent.ACTION_CLOSE_SYSTEM_DIALOGS。
从收到的广播意图中获取原因reason字段,该字段值为homekey时表示回到桌面,值为recentapps时表示打开任务列表。
======================================================================================
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/tv_monitor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请按下主页键或者任务键,然后回到该页面观察结果"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
代码:
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PictureInPictureParams;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Rational;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity
{
private final static String TAG = "ReturnDesktopActivity";
private TextView tv_monitor;
private String mDesc = "";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_monitor = findViewById(R.id.tv_monitor);
initDesktopRecevier(); // 初始化桌面广播
}
// 显示变更的状态
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(20,10);
builder.setAspectRatio(aspectRatio); // 设置画中画窗口的宽高比例
// 进入画中画模式,注意enterPictureInPictureMode是Android8.0之后新增的方法
enterPictureInPictureMode(builder.build());
}
}
// 在进入画中画模式或退出画中画模式时触发
@Override
public void onPictureInPictureModeChanged(boolean isInPicInPicMode, Configuration newConfig)
{
Log.d(TAG, "onPictureInPictureModeChanged isInPicInPicMode="+isInPicInPicMode);
super.onPictureInPictureModeChanged(isInPicInPicMode, newConfig);
if (isInPicInPicMode) // 进入画中画模式
{
} else // 退出画中画模式
{
}
}
// 初始化桌面广播
private void initDesktopRecevier()
{
desktopRecevier = new DesktopRecevier(); // 创建一个返回桌面的广播接收器
// 创建一个意图过滤器,只接收关闭系统对话框(即返回桌面)的广播
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(desktopRecevier, intentFilter); // 注册接收器,注册之后才能正常接收广播
}
@Override
protected void onDestroy()
{
super.onDestroy();
unregisterReceiver(desktopRecevier); // 注销接收器,注销之后就不再接收广播
}
private DesktopRecevier desktopRecevier; // 声明一个返回桌面的广播接收器对象
// 定义一个返回到桌面的广播接收器
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); // 显示变更的状态
}
}
}
}
}
DateUtil:
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@SuppressLint("SimpleDateFormat")
public class DateUtil
{
// 获取当前的日期时间
public static String getNowDateTime(String formatStr)
{
String format = formatStr;
if (TextUtils.isEmpty(format))
{
format = "yyyyMMddHHmmss";
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(new Date());
}
// 获取当前的时间
public static String getNowTime()
{
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date());
}
// 获取当前的时间(精确到毫秒)
public static String getNowTimeDetail()
{
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
return sdf.format(new Date());
}
public static String getNowDate()
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
return sdf.format(new Date());
}
public static String getDate(Calendar calendar)
{
Date date = calendar.getTime();
// 创建一个日期格式化的工具
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 将当前日期时间按照指定格式输出格式化后的日期时间字符串
return sdf.format(date);
}
public static String getMonth(Calendar calendar)
{
Date date = calendar.getTime();
// 创建一个日期格式化的工具
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
// 将当前日期时间按照指定格式输出格式化后的日期时间字符串
return sdf.format(date);
}
public static Date formatString(String strTime)
{
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
date = sdf.parse(strTime);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.VIBRATE" />
<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/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>