问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android悬浮窗开发实战:从权限申请到功能实现

创作时间:
作者:
@小白创作中心

Android悬浮窗开发实战:从权限申请到功能实现

引用
CSDN
1.
https://m.blog.csdn.net/aaajj/article/details/145903435

在Android开发中,悬浮窗是一个非常实用的功能,常用于直播、游戏等场景中。本文将详细介绍如何在Android应用中实现悬浮窗功能,包括权限申请、动态检查、悬浮窗创建、布局定义等关键步骤,并附有详细的代码示例。

在某游戏中,一般都是一队4个人,但是在有的主播直播里,显示栏看上去是5个人,比如

这个是怎么弄的呢?

有2种方式,一个是在投屏的软件画面里拉一个小窗口进去,(PC端操作)

另外一个是在手机上显示一个悬浮窗,达到以假乱真的效果,

这里我们来看看悬浮窗的使用,主要是windowManager.addView方法来添加

如果需要拖动,更新坐标后调用 windowManager.updateViewLayout

在 Android 中实现悬浮窗功能,可以通过

WindowManager

TYPE_APPLICATION_OVERLAY

来实现。以下是一个简单的实现步骤:

1. 添加权限

AndroidManifest.xml

文件中添加悬浮窗权限:


<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  

从 Android 6.0(API 级别 23)开始,

SYSTEM_ALERT_WINDOW

是一个危险权限,需要动态申请。

2. 动态检查和请求悬浮窗权限

在 Android 6.0 及以上版本中,需要通过

Settings.canDrawOverlays()

方法检查是否已授予悬浮窗权限。如果没有权限,则引导用户到设置页面手动开启。

示例代码如下:


if (!Settings.canDrawOverlays(this)) {
    // 如果没有权限,跳转到设置页面
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 1000); // 请求码为 1000
} else {
    // 已经有权限,可以创建悬浮窗
    createFloatingWindow();
}  

3. 创建悬浮窗

使用

WindowManager

将一个视图添加到窗口上。

以下是完整的代码示例:

Java 实现


public class FloatingWindowService extends Service {
    private WindowManager windowManager;
    private View floatingView;
    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化 WindowManager
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        // 创建悬浮窗布局
        floatingView = LayoutInflater.from(this).inflate(R.layout.floating_window_layout, null);
        // 设置悬浮窗参数
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        // 设置初始位置
        params.x = 0;
        params.y = 0;
        // 添加视图到窗口
        windowManager.addView(floatingView, params);
        // 悬浮窗拖动逻辑
        floatingView.setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(v, params);
                        return true;
                }
                return false;
            }
        });
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (floatingView != null) {
            windowManager.removeView(floatingView);
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}  

4. 定义悬浮窗布局

res/layout

目录下创建一个 XML 文件,例如

floating_window_layout.xml

,定义悬浮窗的 UI。

示例:


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/darker_gray">
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/ic_launcher_foreground" />
</FrameLayout>  

5. 启动服务

通过启动

FloatingWindowService

来显示悬浮窗。

示例代码:


Intent serviceIntent = new Intent(this, FloatingWindowService.class);
startService(serviceIntent);  

6. 注意事项

  1. 权限问题:确保在 Android 6.0 及以上版本中动态申请悬浮窗权限。

  2. 适配不同 API 版本

  • 在 Android 8.0(API 级别 26)及以上,

TYPE_PHONE

已被弃用,应使用

TYPE_APPLICATION_OVERLAY

  • 在 Android 7.1(API 级别 25)及以下,可以使用

TYPE_PHONE

  1. 用户体验:悬浮窗可能会干扰用户操作,请谨慎设计,并提供关闭或隐藏的功能
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号