先来一发效果图:

前面是返回效果,最后一下是实现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。所以我们只需要开启服务,调用函数就可以实现全局返回功能了。
编写代码
最重要的服务类
我们要新建一个类去继承自上面那个类:
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 自定义返回按钮的实例详解
# 就可以
# 找了
# 新建一个
# 就不
# 自定义
# 只需要
# 文档
# 应用程序
# 自己的
# 的是
# 辅助功能
# 在这里
# 好了
# 就在
# 还可以
# 下载地址
# 说了
# 如有
# 最重要
# 不多
相关文章:
简历在线制作网站免费,免费下载个人简历的网站是哪些?
,怎么在广州志愿者网站注册?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
宿州网站制作公司兴策,安徽省低保查询网站?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
如何将凡科建站内容保存为本地文件?
建站之星logo尺寸如何设置最合适?
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
常州自助建站工具推荐:低成本搭建与模板选择技巧
如何快速打造个性化非模板自助建站?
公司网站制作费用多少,为公司建立一个网站需要哪些费用?
宝塔建站助手安装配置与建站模板使用全流程解析
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
大学网站设计制作软件有哪些,如何将网站制作成自己app?
如何配置支付宝与微信支付功能?
Android使用GridView实现日历的简单功能
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
linux top下的 minerd 木马清除方法
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
Swift开发中switch语句值绑定模式
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
宝塔面板创建网站无法访问?如何快速排查修复?
西安专业网站制作公司有哪些,陕西省建行官方网站?
新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?
如何通过服务器快速搭建网站?完整步骤解析
如何配置IIS站点权限与局域网访问?
广平建站公司哪家专业可靠?如何选择?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
网站企业制作流程,用什么语言做企业网站比较好?
如何快速搭建高效服务器建站系统?
建站之星下载版如何获取与安装?
网站制作培训多少钱一个月,网站优化seo培训课程有哪些?
C#如何使用XPathNavigator高效查询XML
如何撰写建站申请书?关键要点有哪些?
建站之星微信建站一键生成小程序+多端营销系统
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
宝华建站服务条款解析:五站合一功能与SEO优化设置指南
江苏网站制作公司有哪些,江苏书法考级官方网站?
表情包在线制作网站免费,表情包怎么弄?
招贴海报怎么做,什么是海报招贴?
专业网站建设制作报价,网页设计制作要考什么证?
如何通过虚拟机搭建网站?详细步骤解析
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
免费视频制作网站,更新又快又好的免费电影网站?
如何零基础在云服务器搭建WordPress站点?
北京建设网站制作公司,北京古代建筑博物馆预约官网?
建站之星后台密码遗忘或太弱?如何重置与强化?
免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
*请认真填写需求信息,我们会在24小时内与您取得联系。