Android 仅前台浮窗
什么是前台浮窗
前台浮窗是指在Android系统中,可在应用程序界面之上显示的浮动窗口。它可以显示在其他应用程序或系统界面之上,提供额外的功能或信息展示。前台浮窗在很多应用场景中都有广泛的应用,比如悬浮球菜单、实时翻译工具等。
Android系统权限限制
由于浮窗的特性,Android系统对其进行了权限的限制。在Android 6.0及以上的版本中,应用程序需要动态申请悬浮窗权限,并且只有当应用程序处于前台运行状态时,才能显示浮窗。这样做是为了保护用户的隐私和安全,防止恶意应用程序在后台窃取用户信息或进行其他恶意行为。
申请悬浮窗权限
在代码中申请悬浮窗权限可以使用以下方法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_FLOAT_WINDOW);
} else {
// 已经拥有悬浮窗权限,可以显示浮窗
showFloatWindow();
}
} else {
// 不需要申请悬浮窗权限,可以直接显示浮窗
showFloatWindow();
}
以上代码中,我们首先判断当前设备的Android版本是否达到Android 6.0及以上,如果是,则使用Settings.canDrawOverlays()
方法来判断是否已经拥有悬浮窗权限。如果没有权限,则启动系统设置界面让用户手动授权。在授权完成后,系统会返回结果,我们可以在onActivityResult()
方法中处理结果。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_FLOAT_WINDOW) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// 已经拥有悬浮窗权限,可以显示浮窗
showFloatWindow();
} else {
// 用户未授权,无法显示浮窗
Toast.makeText(this, "未授权悬浮窗权限", Toast.LENGTH_SHORT).show();
}
}
}
}
显示浮窗
显示浮窗可以使用WindowManager
来实现。首先,我们需要创建一个浮窗的布局文件float_window.xml
,定义浮窗的界面和样式。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/float_window_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个浮窗"
android:textSize="16sp"
android:textColor="#FFFFFF"
android:background="#AA000000"
android:padding="8dp" />
</RelativeLayout>
然后,在代码中使用WindowManager
来显示浮窗。
private void showFloatWindow() {
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
layoutParams.format = PixelFormat.RGBA_8888;
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = Gravity.START | Gravity.TOP;
layoutParams.x = 100;
layoutParams.y = 200;
View floatWindowView = LayoutInflater.from(this).inflate(R.layout.float_window, null);
TextView floatWindowText = floatWindowView.findViewById(R.id.float_window_text);
floatWindowText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 浮窗点击事件处理
}
});
windowManager.addView(floatWindowView, layoutParams);
}
以上代码中,我们首先通过WindowManager
获取系统的