Android悬浮球及全局返回功能的实现示例

先来一发效果图:

前面是返回效果,最后一下是实现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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-21 19:54:47

Android悬浮球及全局返回功能的实现示例的相关文章

Android悬浮按钮点击返回顶部FloatingActionButton

先看一下Android悬浮按钮点击回到顶部的效果: FloatingActionButton是Design Support库中提供的一个控件,这个控件可以轻松实现悬浮按钮的效果 首先,要在项目中使用这个悬浮按钮就要先把design这个包导入项目 gradle中加入依赖 compile 'com.android.support:design:25.0.0' 接下来就是在xml中使用: 我这里是放置一个listView模拟返回顶部 <?xml version="1.0" encodi

Android左滑返回功能的实现示例代码

前几天用了个app发现左滑可以返回首页,发现这个功能很炫酷,就想着自己能不能做出来,于是研究了一下 原理 将activity的背景设置为透明同时设置切换动画 手指滑动的时候,根View跟着滑动,滑倒一定的距离就finish掉. 原理很简单,但实现起来可能有些坑.这里记录一下.源码参考 处理onInterceptTouchEvent 事件拦截要处理一件事情:确定这次触摸事件是不是应该交给SlideFinishLayout的onTouchEvent处理. override fun onInterce

Android悬浮对话框(即点即关对话框)实现代码_Android

Activity是Android系统的4个应用程序组件之一.通过传统方法显示的Activity都是充满整个屏幕,也就是全屏的Activity.事实上,Activity不仅可以全屏显示,还可以象对话框一样直接显示在屏幕上.而且可以通过单击屏幕的任何位置(包括Activity内部和Activity外部)来关闭Activity. Activity的传统风格 Activity是学习Android的入门技术.几乎所有的初学者都会从Activity学起.因此,Activity这个组件对于Android的开发

miui8悬浮球有什么功能?miui8悬浮球在哪设置

miui8悬浮球有什么功能 执行应用内操作 执行常用操作 滑动操作,流畅好用 功能可自定义 常用操作随手可得 自动透明.不遮挡浏览内容 这就是我们的悬浮球,滑动操作,流畅可用.操作功能可自定义,常用功能随手可得. miui8悬浮球在哪设置 小米悬浮球可以开启或关闭,开启后乖乖地吸附在边缘做一个小透明,支持滑动操作,流畅好用. 功能方面,悬浮球可以自定义操作,点击会弹出环状菜单,拥有返回桌面.菜单.锁定屏幕.截图.返回等功能,常用操作随手可得. 值得一提的是,输入法弹起的时候它还会自动弹上去,避免

android 返回-关于android自定义返回功能的问题

问题描述 关于android自定义返回功能的问题 碰到一个问题,android程序里面. A界面跳转到B界面,用intent跳转的 ,在B界面自定义了返回响应,返回方法里面直接finish(). 有一个问题是,当从A界面跳转到B界面,然后程序切到后台之后,再点打开程序,在B界面点击返回按钮,就不返回到A界面了,程序直接退了. 网上查了一些资料,好像是切到后台之后堆栈就被清空了,请问大家怎么解决这个问题

Android 经典笔记七 全局弹窗Dialog

目录介绍 1.全局弹窗分析 2.全局弹窗必要条件 3.全局弹窗实现方式 3.1. 利用系统弹出dialog 3.2. 获取WindowManager,直接添加view 3.3. 在服务里,获取栈顶的Activity,弹窗 4.Dialog实现全局Loading加载框 4.1. 自定义Loading类 4.2. 给自定义的Dialog添加自定义属性 4.3. Loading布局 4.4. 开始使用 5.遇到的问题 5.1. 权限问题 5.2. Unable to add window 6.其他说明

Android 使用SwipeBackLayout实现滑动返回上一级页面——实战来袭

  我们知道,APP在设计上习惯性的把返回按钮放在屏幕的左上角,那么,在很多时候(尤其是大屏幕手机),操作改返回按钮,就会有诸多不便了.为了更加方便实现"返回"功能,现在的一些APP,如百度贴吧等,开始引入一种的新的交互方式,通过滑动屏幕,利用手势事件来快速且友好的实现该功能.   如何快速实现上图的效果呢,Github上提供了一个开源的库SwipeBackLayout,地址:https://github.com/ikew0ng/SwipeBackLayout , 通过它,我们就能快速

我的Android进阶之旅------&amp;gt;Android利用Sensor(传感器)实现指南针功能

首先来说一说该指南针的实现思路: 程序先准备一张指南针图片,该图片上方向指针指向北方.接下来开发一个检测方向的传感器,程序检测到手机顶部绕Z轴转过多少度,让指南针图片反向转多少度即可.由此可见指南针应用只要在界面中添加一张图片,并让图片总是反向转过反向传感器返回的第一个角度值即可. 下面介绍一下方向传感器:方向传感器用于感应手机设备的摆放状态.方向传感器可以返回三个角度,这三个角度即可确定手机的摆放状态.关于方向传感器返回的三个角度的说明如下. 第一个角度:表示手机顶部朝向正北方的夹角.当手机绕

我的Android进阶之旅------&amp;gt;Android利用Sensor(传感器)实现水平仪功能的小例

       这里介绍的水平仪,指的是比较传统的气泡水平仪,在一个透明圆盘内充满液体,液体中留有一个气泡,当一端翘起时,该气泡就会浮向翘起的一端.    利用方向传感器返回的第一个参数,实现了一个指南针小应用.    我的Android进阶之旅------>Android利用Sensor(传感器)实现指南针功能  (地址:http://blog.csdn.net/ouyang_peng/article/details/8801204)    接下来,我们利用返回的第二.三个参数实现该水平仪.因为