先来一发效果图:

前面是返回效果,最后一下是实现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";@Overridepublic void onCreate() {super.onCreate();//使用EventBus代替广播EventBus.getDefault().register(this);}@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) { }@Overridepublic void onInterrupt() {}@Subscribepublic 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();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(height,width);}@Overrideprotected 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() {@Overridepublic void onClick(View v) {EventBus.getDefault().post(MyAccessibilityService.BACK);Toast.makeText(context, "点击了悬浮球 执行后退操作", Toast.LENGTH_SHORT).show();}});floatBall.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic 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

Android悬浮球及全局返回功能的实现相关推荐

  1. android 悬浮球简书,轻松自制flyme悬浮球

    前言 去年用了一整年的MX4Pro,魅族留给我最大的印象就是悬浮球了(质量问题我就不说了),左右滑动切换应用.上拉返回桌面.下拉打开通知栏.轻触返回...,一切都那么丝滑.然而自从上半年换成了s7de ...

  2. android右滑返回动画,Android仿微信右滑返回功能的实例代码

    先上效果图,如下: 先分析一下功能的主要技术点,右滑即手势判断,当滑到一直距离时才执行返回,并且手指按下的位置是在屏幕的最左边(这个也是有一定范围的),  这些可以实现onTouchEvent来实现. ...

  3. android 悬浮球代码,Android 悬浮球

    闲来无事,搞一波悬浮球,此球: 无需权限 主要代码只有一个类,简简单单放进自己的工程 悬浮球可以用来干啥: 打开侧滑界面 打开一排小按钮 打开客服等等 功能: 显示红点(接收到信息等场景) 关闭红点( ...

  4. android悬浮球代码,Android 仿360悬浮球与加速球

    先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来,做成的效果有: 点击按钮后退出Activity,呈现一个圆形的悬浮球,可以随意拖动并会自动依靠到屏幕 ...

  5. android 悬浮球动画,Android 仿360悬浮球与加速球

    先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来,做成的效果有: 点击按钮后退出Activity,呈现一个圆形的悬浮球,可以随意拖动并会自动依靠到屏幕 ...

  6. android悬浮球截屏,vivoX27怎么双击悬浮球截屏?获取屏幕截图依旧方便快速!

    在此前一段时间中,iphone手机有一项功能在抖音中非常的火爆,那就是双击iphone的小白点进行截图的功能,让你不再依赖于截屏快捷键或是实体快捷键也能进行轻松的截图. 而今天我们要说的,是vivoX ...

  7. android悬浮球截屏,ColorOS7的悬浮球截屏和长截屏怎么用,有哪些方式

    11月20日OPPO官方发布了这个全新的ColorOS 7系统了,在发布会上展现了很多惊艳的功能,但是对于操作便捷来说,我最喜欢的还是截屏方式的改变,变得花样更多了,相信这个截屏在大家使用手机的过程中 ...

  8. android 鼠标 悬浮,鼠标悬浮球不闪退版本下载-鼠标悬浮球 安卓版v1.1-PC6安卓网...

    鼠标悬浮球app是一款专为大屏手机准备的系统工具,鼠标悬浮球不闪退版本支持自定义悬浮球图标,用户可以轻松设置独特的悬浮球,鼠标悬浮球app,为你的手机带来便捷的操作体验. 软件介绍 鼠标悬浮球app从 ...

  9. android 魅族悬浮球,轻松自制flyme悬浮球

    前言 去年用了一整年的MX4Pro,魅族留给我最大的印象就是悬浮球了(质量问题我就不说了),左右滑动切换应用.上拉返回桌面.下拉打开通知栏.轻触返回...,一切都那么丝滑.然而自从上半年换成了s7de ...

最新文章

  1. Windows 到 Linux 之旅: 第 8 部分. 备份与恢复
  2. 旷视砸20亿进军AIoT,发布国内首个机器人协作大脑河图
  3. 从命令行列出所有环境变量?
  4. Linux内核开发之将驱动程序添加到内核
  5. NPM 安装 TypeScript 和 npm 的 Invalid package.json 错误以及运行第一个typescript程序
  6. JDK1.8新特性:Stream流
  7. 全球及中国装饰花盆行业消费规模与投资商机研究报告2022版
  8. 编程打怪升级之路2018-06-01
  9. 字符串系列之最长回文子串
  10. [转载] 将一个整数型字符串转换为一个整数
  11. SET XACT_ABORT各种用法及显示结果
  12. python匹配部分字符串_python – 即使只是部分匹配字符串,如何匹配字符串?
  13. MySQL技术内幕 InnoDB存储引擎【二】后台线程
  14. Java-JVM第一篇认识JVM
  15. Windows Phone 7 手机使用小记
  16. 代码审查工具Jupiter资料汇总
  17. FaWave恢复twitter的办法
  18. 双11还没完,商家已经被退货“逼疯”了
  19. java jnlp_Java Web Start实践:动态生成JNLP
  20. 名编辑电子杂志大师教程 | 如何调用外部本地文件?

热门文章

  1. 大数据在地理信息系统的应用
  2. wangEditor 上传本地视频和图片到oss服务器并在富文本回显。
  3. 成长的代价和教育的意义
  4. iOS 内存泄漏检测 Instruments Leaks
  5. 潭州学院html学习(day07)
  6. 爬虫从入门到精通(16) |最详细的的Fiddler抓包软件介绍
  7. NTLM认证原理及其过程
  8. Excel进行数据分析
  9. long与int转换线上问题解决(必看)
  10. 概率分布之间的距离度量以及python实现