Android悬浮球及全局返回功能的实现示例
发布时间 - 2026-01-11 00:45:39 点击率:次先来一发效果图:

前面是返回效果,最后一下是实现home键的效果
前言
很久之前,就想做一个悬浮球了,毕竟是程序猿嘛,有想要的功能的时候总是想自己尝试一下,于是兴致勃勃的找了好久,都没有找到全局返回功能该如何实现!最后也无疾而终,就在前两天,又想到了这个功能,今天硬是花了好久,从一个同类软件获得了一点灵感,有一个关键的地方被我察觉到了,顺着这个思路找了很多资料,便实现了全局返回功能。
思路
废话不多说了,说说主要的思路吧,关键的一个类就是:AccessibilityService,官方文档地址,这个类与手机里面的一个功能密切相关:辅助功能-服务。官方文档来看,这个功能是为了方便有障碍的人士更好的使用手机。我们这里就不展开介绍里面的API了,为了实现我们的全局返回功能,我们只需要使用一个函数即可:boolean performGlobalAction (int action),官方解释如下:
Performs a global action. Such an action can be performed at any moment regardless of the current application or user location in that application. For example going back, going home, opening recents, etc.
翻译过来就是:
执行全局动作。无论该应用程序中的当前应用程序或用户位置如何,都可以随时执行此类操作。例如执行HOME键,BACK键,任务键等
其中可以传入的参数有四个:
- GLOBAL_ACTION_BACK
- GLOBAL_ACTION_HOME
- GLOBAL_ACTION_NOTIFICATIONS
- GLOBAL_ACTION_RECENTS
从字面就可以理解,我们返回功能需要的就是GLOBAL_ACTION_BACK。所以我们只需要开启服务,调用函数就可以实现全局返回功能了。
编写代码
最重要的服务类
我们要新建一个类去继承自上面那个类:
public class MyAccessibilityService extends AccessibilityService {
public static final int BACK = 1;
public static final int HOME = 2;
private static final String TAG = "ICE";
@Override
public void onCreate() {
super.onCreate();
//使用EventBus代替广播
EventBus.getDefault().register(this);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) { }
@Override
public void onInterrupt() {}
@Subscribe
public void onReceive(Integer action){
switch (action){
case BACK:
performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
break;
case HOME:
performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
break;
}
}
}
上面的onReceive方法是我们使用EventBus的订阅函数,当其他地方发送消息之后,我们这里就可以收到,然后判断是要执行后退还是回到桌面。
然后我们在AndroiManifest里面要注册我们的服务,但是这个注册的比较特殊:
首先加入权限声明:
复制代码 代码如下: <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
然后注册服务:
<service android:name=".MyAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService"/> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice"/> </service>
其中resource中的内容我们要在xml包中声明,首先新建一个xml包,如下:
然后新建一个accessibilityservice.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/start_floatingBall"/> <!--我这里写的是开启悬浮球功能-->
里面还可以设置许多属性,在这里就不介绍了,有兴趣的可以在官方文档里面查看。
到时候description的显示效果如下:
好了,到现在就已经完成了AccessibilityService服务的创建与注册了,接下来在Activity中启动服务就可以了: startService(new Intent(this,MyAccessibilityService.class));
使用EventBus传递事件即可实现返回:EventBus.getDefault().post(MyAccessibilityService.BACK);
但是要打开服务才行,简单办法是直接调用Intent跳到设置界面:startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
或者手动进入设置->辅助功能->服务->找到自己的app,然后开启服务即可。(不同的系统可能略有差异,小米就是在无障碍里面),界面如下:
悬浮球的简单实现
1.自定义一个View,画一个悬浮球:
public class FloatingView extends View {
public int height = 150;
public int width = 150;
private Paint paint;
public FloatingView(Context context){
super(context);
paint = new Paint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(height,width);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画大圆
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(getResources().getColor(R.color.state_one));
canvas.drawCircle(width/2,width/2,width/2,paint);
//画小圆圈
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
canvas.drawCircle(width/2,width/2, (float) (width*1.0/4),paint);
}
代码很简单,是画了一个大圆,然后一个小点的圆圈。
接下来,把这个view展示在桌面:
public class ViewManager {
FloatingView floatBall;
WindowManager windowManager;
public static ViewManager manager;
Context context;
private WindowManager.LayoutParams floatBallParams;
private ViewManager(Context context) {
this.context = context;
}
public static ViewManager getInstance(Context context) {
if (manager == null) {
manager = new ViewManager(context);
}
return manager;
}
public void showFloatBall() {
floatBall = new FloatingView(context);
windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
if (floatBallParams == null) {
floatBallParams = new WindowManager.LayoutParams();
floatBallParams.width = floatBall.width;
floatBallParams.height = floatBall.height;
floatBallParams.gravity = Gravity.TOP | Gravity.LEFT;
floatBallParams.type = WindowManager.LayoutParams.TYPE_TOAST;
floatBallParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
floatBallParams.format = PixelFormat.RGBA_8888;
}
windowManager.addView(floatBall, floatBallParams);
floatBall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(MyAccessibilityService.BACK);
Toast.makeText(context, "点击了悬浮球 执行后退操作", Toast.LENGTH_SHORT).show();
}
});
floatBall.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
EventBus.getDefault().post(MyAccessibilityService.HOME);
Toast.makeText(context, "长按了悬浮球 执行返回桌面", Toast.LENGTH_SHORT).show();
return false;
}
});
}
public int getScreenWidth() {
return windowManager.getDefaultDisplay().getWidth();
}
}
为了简单起见,就没有贴上拖动悬浮窗的代码了,如有需要,可以在文章末尾查看源码。
上面代码把view加入到window中,并给view设置了点击事件,以及长按事件,向AccessibilityService传递消息,执行相应的事件。
要显示悬浮窗,要声明权限:
复制代码 代码如下:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
然后手动开启权限!不然无法显示悬浮窗。
最后我们在Activity中开启我们自定义的悬浮窗即可:
ViewManager.getInstance(MainActivity.this).showFloatBall();
结束语
现在看来,实现一个全局返回功能真的非常简单,但是当初就真的找了非常久,怎么找,怎么试都没法实现这个功能,于是尝试着去学学别的悬浮窗的代码,但是没办法,加壳了,反编译后没法看。但是我注意到了一个细节,它要我打开服务才能使用悬浮窗的功能,所以就从这里下手,慢慢找到了实现全局返回的方法。
源码地址:https://github.com/CHNicelee/FloatingBall
demo下载地址:FloatingBall_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android全局悬浮球
# android
# 悬浮球
# Android全局返回
# Android 滑动返回Activity的实现代码
# Android 实现按两次返回键退出程序(两种方法)
# Android onKeyDown监听返回键无效的解决办法
# Android标题栏中添加返回按钮功能
# ionic2如何处理android硬件返回按钮
# Android悬浮按钮点击返回顶部FloatingActionButton
# Android 自定义返回按钮的实例详解
# 就可以
# 找了
# 新建一个
# 就不
# 自定义
# 只需要
# 文档
# 应用程序
# 自己的
# 的是
# 辅助功能
# 在这里
# 好了
# 就在
# 还可以
# 下载地址
# 说了
# 如有
# 最重要
# 不多
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
如何在搬瓦工VPS快速搭建网站?
如何用搬瓦工VPS快速搭建个人网站?
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
Laravel如何配置Horizon来管理队列?(安装和使用)
简历在线制作网站免费版,如何创建个人简历?
如何制作一个表白网站视频,关于勇敢表白的小标题?
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
网站图片在线制作软件,怎么在图片上做链接?
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
如何快速搭建支持数据库操作的智能建站平台?
长沙企业网站制作哪家好,长沙水业集团官方网站?
如何正确下载安装西数主机建站助手?
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
公司门户网站制作流程,华为官网怎么做?
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
如何实现建站之星域名转发设置?
奇安信“盘古石”团队突破 iOS 26.1 提权
开心动漫网站制作软件下载,十分开心动画为何停播?
高端企业智能建站程序:SEO优化与响应式模板定制开发
Python高阶函数应用_函数作为参数说明【指导】
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
网页设计与网站制作内容,怎样注册网站?
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
在线制作视频的网站有哪些,电脑如何制作视频短片?
如何自定义建站之星模板颜色并下载新样式?
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
长沙做网站要多少钱,长沙国安网络怎么样?
Laravel Session怎么存储_Laravel Session驱动配置详解
Laravel如何为API编写文档_Laravel API文档生成与维护方法
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
简单实现Android验证码
Laravel怎么实现验证码(Captcha)功能
JavaScript中的标签模板是什么_它如何扩展字符串功能
太平洋网站制作公司,网络用语太平洋是什么意思?
活动邀请函制作网站有哪些,活动邀请函文案?
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门
Python3.6正式版新特性预览
三星、SK海力士获美批准:可向中国出口芯片制造设备
如何在腾讯云免费申请建站?
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
javascript读取文本节点方法小结
JS去除重复并统计数量的实现方法
Android GridView 滑动条设置一直显示状态(推荐)
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
如何用PHP快速搭建CMS系统?

