当前位置:首页 » 安卓系统 » android悬浮窗实现

android悬浮窗实现

发布时间: 2023-01-05 12:31:24

㈠ Android实现类似qq,微信消息悬浮窗通知

实现方法:(需要开启悬浮窗通知权限、允许应用在其他应用上显示)

悬挂式Notification,他是5.0中新增的,也就是API中的Headsup的Notification,可以在不打断用户操作的时候,给用户通知

注意:在某些rom下使用headsup并不会显示桌面悬浮窗,而是直接跳转到相应的界面,亲测华为,小米都是这种情况,这种情况下需要自己实现悬浮窗

具体实现:

㈡ android8.0之悬浮窗和通知栏

悬浮窗:

        使用场景:例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示;

        注意事项:

                1、一般需要在后台进行操作的时候才需要悬浮窗,这样悬浮窗才有意义;

                2、API Level >= 23的时候,需要在AndroidManefest.xml文件中声明权限SYSTEM_ALERT_WINDOW才能在其他应用上绘制控件。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />;除了这个权限外,我们还需要在系统设置里面对本应用进行设置悬浮窗权限。该权限在应用中需要启动Settings.ACTION_MANAGE_OVERLAY_PERMISSION来让用户手动设置权限:startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), REQUEST_CODE);

                3、LayoutParam设置:LayoutParam里的type变量。这个变量是用来指定窗口类型的。在设置这个变量时,需要注意一个坑,那就是需要对不同版本的Android系统进行适配。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

} else {

    layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;

};在Android 8.0之前,悬浮窗口设置可以为TYPE_PHONE,这种类型是用于提供用户交互操作的非应用窗口。

而Android 8.0对系统和API行为做了修改,包括使用SYSTEM_ALERT_WINDOW权限的应用无法再使用一下窗口类型来在其他应用和窗口上方显示提醒窗口:

- TYPE_PHONE

- TYPE_PRIORITY_PHONE

- TYPE_SYSTEM_ALERT

- TYPE_SYSTEM_OVERLAY

- TYPE_SYSTEM_ERROR

如果需要实现在其他应用和窗口上方显示提醒窗口,那么必须该为TYPE_APPLICATION_OVERLAY的新类型;

如果在Android 8.0以上版本仍然使用TYPE_PHONE类型的悬浮窗口,则会出现如下异常信息:

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f8ec928 -- permission denied for window type 2002;

        具体实现:

        1、Activity:
        public void startFloatingService(View view) {        

    ...

    if (!Settings.canDrawOverlays(this)) {

        Toast.makeText(this, "当前无权限,请授权", Toast.LENGTH_SHORT);

        startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);

    } else {

        startService(new Intent(MainActivity.this, FloatingService.class));

    }

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == 0) {

        if (!Settings.canDrawOverlays(this)) {

            Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();

        } else {

            Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();

            startService(new Intent(MainActivity.this, FloatingService.class));

        }

    }

}

2、service:

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

    showFloatingWindow();

    return super.onStartCommand(intent, flags, startId);

}

private void showFloatingWindow() {

    if (Settings.canDrawOverlays(this)) {

        // 获取WindowManager服务

        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        // 新建悬浮窗控件

        Button button = new Button(getApplicationContext());

        button.setText("Floating Window");

        button.setBackgroundColor(Color.BLUE);

        // 设置LayoutParam

        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.width = 500;

        layoutParams.height = 100;

        layoutParams.x = 300;

        layoutParams.y = 300;

        // 将悬浮窗控件添加到WindowManager

        windowManager.addView(button, layoutParams);

    }

}

        效果展示:

                

㈢ Android悬浮窗权限适配

悬浮窗相信大家都不陌生,比如360手机卫士的加速球,视频应用的小窗,可以占用很少的空间,又能保持跟用户的交互。悬浮窗可以通过WindowManager.addView添加。具体用法可以看 Android悬浮窗用法总结 ,按照这篇文章添加过悬浮窗之后,会发现有的手机上显示不出来,这就是权限的问题了。

到这里,就明白我们只需要处理18<=API<23下某些rom的权限。
为什么某些rom那么特殊呢?
因为在API 18,Google新增了一个函数AppOpsManager,不过在这个版本,该函数是隐藏的 ( Android 4.3 隐藏功能 App Ops 分析 ),到API 19才公开。用这个函数可以对manifest申请的权限做一层限制,于是就有了360手机卫士,小米安全中心。。。

检测这些rom的权限,方法是一样的,可以通过反射使用AppOpsManager.checkOp

检测应用是否有权限,可以防止异常,或者点击事件没反应。为了给用户提供更好地体验,我们应该引导用户去权限设置页面开启权限。这些特殊rom的权限设置是不一样的,所以需要先判断手机rom,再分别去对应的权限设置页面。

具体方法见: Android判断手机ROM

未完待续。。。

参考:

http://blog.csdn.net/adrianandroid/article/details/49911681

http://blog.csdn.net/u012573920/article/details/49514115

http://blog.csdn.net/adrianandroid/article/details/49911681

http://www.cnblogs.com/fangyucun/p/4027750.html

http://blog.csdn.net/xx326664162/article/details/52438706

㈣ Android桌面悬浮窗效果怎么实现

先谈一下基本的实现原理,这种桌面悬浮窗的效果很类似与Widget,但是它比Widget要灵活的多。主要是通过WindowManager这个类来实现的,调用这个类的addView方法用于添加一个悬浮窗,updateViewLayout方法用于更新悬浮窗的参数,removeView用于移除悬浮窗。其中悬浮窗的参数有必要详细说明一下。
WindowManager.LayoutParams这个类用于提供悬浮窗所需的参数,其中有几个经常会用到的变量:
type值用于确定悬浮窗的类型,一般设为2002,表示在所有应用程序之上,但在状态栏之下。
flags值用于确定悬浮窗的行为,比如说不可聚焦,非模态对话框等等,属性非常多,大家可以查看文档。
gravity值用于确定悬浮窗的对齐方式,一般设为左上角对齐,这样当拖动悬浮窗的时候方便计算坐标。
x值用于确定悬浮窗的位置,如果要横向移动悬浮窗,就需要改变这个值。
y值用于确定悬浮窗的位置,如果要纵向移动悬浮窗,就需要改变这个值。
width值用于指定悬浮窗的宽度。
height值用于指定悬浮窗的高度。
创建悬浮窗这种窗体需要向用户申请权限才可以的,因此还需要在AndroidManifest.xml中加入

安卓手机开启无障碍功能与悬浮窗的方法

怎么开启辅助服务?

使用优Q的功能必须开服辅助服务,辅助服务是安卓官方提供的功能。

打开优Q点击【我的】点击权限设置,开启即可。如果无法快速开启,请参考如下的方法。

部分手机辅助可通过快捷键开启,优Q仍提示未开启,将辅助服务关闭一下再打开就可以了。

如果仍然无效,请先关闭优Q然后重启手机。

VIVO设置-更多设置-辅助功能-开启-优Q

OPPO设置-其他设置-辅助功能-开启-优Q

小米设置-更多设置-无障碍-开启-优Q

魅族设置-辅助功能-无障碍-开启-优Q

华为设置-高级设置-辅助功能-开启-优Q

联想设置-高级设置-辅助功能-开启-优Q

三星设置-辅助功能-开启-优Q

乐视设置-辅助功能-开启-优Q

360设置-辅助功能-开启优Q

锤子设置-全局高级设置-辅助功能-开启-优Q

一加设置-其他高级设置-无障碍-开启-优Q

怎么开启悬浮窗?

部分高版本手机打开优Q会自动跳转到悬浮窗开关。

打开优Q点击【我的】点击权限设置,开启悬浮窗即可。如果无法快速开启,请参考如下的方法。

不同的手机打开悬浮窗权限的方法不一样,常见的方法是在应用权限管理或手机管家进行设置。

VIVO

系统6.0:设置-更多设置-权限管理-优Q-开启悬浮窗系统

5.0:i管家-软件管理-悬浮窗管理-开启-"优Q

OPPO手机管家-隐私权限-悬浮窗权限管理-开启

优Q

小米安全中心-应用权限管理-优Q-允许显示悬浮窗

魅族手机管家-应用权限管理-优Q-开启桌面悬浮窗

华为设置权限管理-悬浮窗开启优Q

联想安全中心-权限管理-显示悬浮窗-

允许"优Q显示悬浮窗

三星设置-应用程序-应用程序管理器-右上角更多-

可出现在顶部的应用程序-开启优Q

乐视设置-隐私权限-应用权限管理器-应用列表

优Q-允许显示悬浮窗

360安全卫士-软件管理-权限管理-优Q-

允许显示悬浮窗

锤子设置-安全中心-应用程序权限管理-悬浮窗-

开启优Q

一加设置-应用程序-特殊访问权限-出现在其他应用上--找到优Q打开即可

三条鱼软件官网

㈥ android 系统级的悬浮窗实现

当我们在使用的app的时候,如果需要实时观测到某个功能的实时进度并且不影响其他的操作的时候或者不影响使用其他应用的时候,系统级的悬浮球是个非常不错的选择。

public class QueueUpFloatService extends Service {

/**

* 启动服务并传值

*

* @param activity 启动服务的activity

* @param modeBean 数据对象

*/

public static void launchService(Activity activity, ModeBean modeBean) {

try {

        Intent intent =new Intent(activity, QueueUpFloatService.class);

        Bundle bundle =new Bundle();

        bundle.putSerializable(KEY_MODEL, modeBean);

        intent.putExtras(bundle);

        activity.startService(intent);

    }catch (Exception e) {

        e.printStackTrace();

    }

}

    @Override

    public void onCreate() {

            super.onCreate();

    }

    @Override

    public IBinder onBind(Intent intent) {

            return null;

    }

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

            return super.onStartCommand(intent, flags, startId);

    }

    @Override

    public void onDestroy() {

            super.onDestroy();

    }

}

@Override

public void onCreate() {

    super.onCreate();

    //加一点简单的动画 

    buttonScale = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_float);

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    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.gravity = Gravity.LEFT | Gravity.TOP;

    layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |             WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

    layoutParams.width = ScreenUtils.dp2px(66);

    layoutParams.height = ScreenUtils.dp2px(66);

    layoutParams.x = ScreenUtils.getRealWidth() - ScreenUtils.dp2px(60);

    layoutParams.y = ScreenUtils.deviceHeight() *2 /3;

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

    ModeBean modeBean = (ModeBean) intent.getExtras().getSerializable(KEY_MODEL);

    LayoutInflater layoutInflater = LayoutInflater.from(this);

    floatView = layoutInflater.inflate(R.layout.view_float, null);

    RelativeLayout rlFloatParent =floatView.findViewById(R.id.rl_float_parent);

    rlFloatParent.startAnimation(buttonScale);

    TextView tvIndex =floatView.findViewById(R.id.tv_queue_index);

    tvIndex.setText(modeBean.title);

    floatView.findViewById(R.id.iv_close_float).setOnClickListener(v -> stopSelf());

    //修改悬浮球的滑动实现

    floatView.setOnTouchListener(new FloatingOnTouchListener());

    windowManager.addView(floatView, layoutParams);

    return super.onStartCommand(intent, flags, startId);

}

private class View.OnTouchListener {

    private int x;

    private int y;

    private long downTime;

    @SuppressLint("ClickableViewAccessibility")

    @Override

    public boolean onTouch(View view, MotionEvent event) {

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                        downTime = System.currentTimeMillis();

                        x = (int) event.getRawX();

                        y = (int) event.getRawY();

                        break;

                case MotionEvent.ACTION_MOVE:

                        int nowX = (int) event.getRawX();

                        int nowY = (int) event.getRawY();

                        int movedX = nowX -x;

                        int movedY = nowY -y;

                        x = nowX;

                        y = nowY;

                        layoutParams.x =layoutParams.x + movedX;

                        layoutParams.y =layoutParams.y + movedY;

                        windowManager.updateViewLayout(view, layoutParams);

                        break;

                case MotionEvent.ACTION_UP:

                        /* *

                        * 这里根据手指按下和抬起的时间差来判断点击事件还是滑动事件

                        * */

                        if ((System.currentTimeMillis() -downTime) <200) {

                                //检测应用在前台还是后台

                                if (AppUtils.isAppIsInBackground()) {

                                        AppUtils.moveToFront(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1).getClass());

                                } else {

                                        //检测栈顶是否为SecondActivity 不是就打开SecondActivity

                                      if (!CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1)

                                                .getClass().getSimpleName().contains("SecondActivity")) {

                                        SecondActivity.launchActivity(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1));

                                }

                      }

            }

                        break;

            default:

                        break;

        }

           return false;

    }

}

        @Override

        public void onDestroy() {

            super.onDestroy();

            if (null ==floatView) {

                return;

               }

            windowManager.removeView(floatView);

            windowManager=null;

}

㈦ 安卓添加白色悬浮窗

安卓悬浮窗设置 原创
2021-08-01 20:14:18

andy.cao

码龄14年

关注
1、悬浮窗不能在当前app中展示
使用activity中的moveTaskToBack(true),获得的悬浮窗效果。

要修改AndroidManifest.xml中
对应的VideoChatViewActivity的模式一定不要用singleTop,修改成singleInstance
如果用singleTop,会认为当前activity就是root,不能获得想要的结果。
一定要修改成这样

2、悬浮窗开发
a、语音通话
浮窗显示一张图片

b、视频通话
浮窗需要显示对方的视频

上代码
1、service

2、activity

3、布局文件

4、授权,老版本不需要,新版本则需要授权

㈧ 按键精灵安卓版获取悬浮窗位置

按键精灵安卓版获取悬浮窗位置想要有提示的效果,就需要能够在屏幕上显示内容,在按键中能够显示的有showmessage、悬浮窗、动态ui、对话窗这些命令。
1、从可控性角度来说悬浮窗命令最合适,所以我也是选择用悬浮窗实现这个效果。
2、悬浮窗的设置悬浮窗的位置、悬浮窗的大小、悬浮窗的背景色、悬浮窗的透明度、悬浮窗的圆角等
3、实现过程这个过程其实就是解决悬浮窗设置的过程,那么我们就逐个来说一下。
4、悬浮窗的大小这个数值最小是1,最大值无上限,不过没必要做太多,一是不美观,二是影响图色命令的精准性。

热点内容
随机启动脚本 发布:2025-07-05 16:10:30 浏览:513
微博数据库设计 发布:2025-07-05 15:30:55 浏览:17
linux485 发布:2025-07-05 14:38:28 浏览:297
php用的软件 发布:2025-07-05 14:06:22 浏览:747
没有权限访问计算机 发布:2025-07-05 13:29:11 浏览:421
javaweb开发教程视频教程 发布:2025-07-05 13:24:41 浏览:671
康师傅控流脚本破解 发布:2025-07-05 13:17:27 浏览:229
java的开发流程 发布:2025-07-05 12:45:11 浏览:673
怎么看内存卡配置 发布:2025-07-05 12:29:19 浏览:273
访问学者英文个人简历 发布:2025-07-05 12:29:17 浏览:823