Android 悬浮窗踩坑体验
来源:互联网 发布:美国硕士一年花费知乎 编辑:程序博客网 时间:2024/05/17 11:34
Android 悬浮窗踩坑体验
大家都知道,悬浮窗的问题,一直都是众开发者比较恶心的问题,加上 google 在7.0之后,更是对悬浮窗加大了管理,原本设置悬浮窗类型为 TYPE_TOAST 还能显示,现在是直接关闭掉了;不过值得提一下的是,TYPE_TOAST 类型的悬浮窗,在国内的一些机型,也不能显示,这要怎么处理呢?
1、判断是否开启了悬浮窗的权限
1、如果用户开启了悬浮窗的权限,那就好办啦,直接使用我们悬浮窗。判断方法:
/** * 判断悬浮窗口权限是否打开 */public static boolean hasFloatWindowAccessPermission(Context context) { if (Build.VERSION.SDK_INT >= 23) { return Settings.canDrawOverlays(context); } try { Object object = context.getSystemService(Context.APP_OPS_SERVICE); if (object == null) { return false; } Class localClass = object.getClass(); Class[] arrayOfClass = new Class[3]; arrayOfClass[0] = Integer.TYPE; arrayOfClass[1] = Integer.TYPE; arrayOfClass[2] = String.class; Method method = localClass.getMethod("checkOp", arrayOfClass); if (method == null) { return false; } Object[] arrayOfObject1 = new Object[3]; arrayOfObject1[0] = Integer.valueOf(24); arrayOfObject1[1] = Integer.valueOf(Binder.getCallingUid()); arrayOfObject1[2] = context.getPackageName(); int m = ((Integer) method.invoke(object, arrayOfObject1)).intValue(); return m == AppOpsManager.MODE_ALLOWED; } catch (Exception e) { e.printStackTrace(); } return false;}
2、使用悬浮窗类型为 TYPE_TOAST 的窗口
1、部分手机,在没有开启悬浮窗的权限的时候,可以使用 TYPE_TOAST 类型,弹出悬浮窗。例如:
mTaskProgressParams.type = WindowManager.LayoutParams.TYPE_TOAST;
3、利用反射,自定义Toast来弹出悬浮窗
1、我们都知道,吐司的显示,也是悬浮窗的级别的,但是不需要悬浮窗的权限,那我们就在Toast基础上,通过反射来,设置悬浮窗。这种对于设置 TYPE_TOAST 类型,也不生效的手机,可以适用。
public class MyToast {
private Toast mToast;private Context mContext;private boolean isShow = false;private TaskView mView;private Object mTN;private Method show;private Method hide;private WindowManager.LayoutParams mLayoutParams;public MyToast(Context context) { this.mContext = context; if (mToast == null) { mToast = new Toast(mContext); } mView = new TaskView(mContext); mToast.setView(mView);}public void setNextOnClickListener(View.OnClickListener l) { mView.setNextOnClickListener(l);}public void setTimeCountDown(int times) { mView.setTimeCountDown(times);}public void show() { if (isShow) return; initTN(); try { if (Build.VERSION.SDK_INT <= 23) { show.invoke(mTN); } else { show.invoke(mTN, mView.getWindowToken()); } } catch (Exception e) { e.printStackTrace(); } isShow = true; Log.i("czc", "SettingSlideLockToast is showing");}public void hide() { if (!isShow) return; try { hide.invoke(mTN); } catch (Exception e) { e.printStackTrace(); } isShow = false; mView.stopTimeCountDown(); Log.i("czc", "SettingSlideLockToast is hided");}private void initTN() { try { Field tnField = mToast.getClass().getDeclaredField("mTN"); tnField.setAccessible(true); mTN = tnField.get(mToast); Field tnParamsField = mTN.getClass().getDeclaredField("mParams"); tnParamsField.setAccessible(true); mLayoutParams = (WindowManager.LayoutParams) tnParamsField.get(mTN); mLayoutParams.format = PixelFormat.TRANSLUCENT; //this flag set view don't interrupt touch event mLayoutParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL; mLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; mLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mLayoutParams.windowAnimations = R.style.SettingClickToastAnim; mLayoutParams.width = ScreenUtil.getRawScreenWidth(); mLayoutParams.height = ScreenUtil.dp2px(70); mLayoutParams.x = 0; mLayoutParams.y = 0; /**调用tn.show()之前一定要先设置mNextView*/ Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView"); tnNextViewField.setAccessible(true); tnNextViewField.set(mTN, mToast.getView()); if (Build.VERSION.SDK_INT <= 23) { show = mTN.getClass().getMethod("show"); } else { show = mTN.getClass().getMethod("show", new Class[]{IBinder.class}); mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; } hide = mTN.getClass().getMethod("hide"); } catch (Exception e) { e.printStackTrace(); } mToast.setGravity(Gravity.LEFT | Gravity.TOP, 0, 0);}}
阅读全文
0 0
- Android 悬浮窗踩坑体验
- Android悬浮框应用--悬浮笔记
- Android悬浮控件
- Android中悬浮窗口
- android 悬浮窗口
- android 悬浮窗口
- Android悬浮窗口基本知识
- android 悬浮窗口
- Android悬浮窗功能
- Android 桌面悬浮框
- Android中悬浮窗口
- Android桌面悬浮窗
- android 悬浮窗
- Android 桌面悬浮框
- Android悬浮窗
- android 悬浮窗口
- Android 中悬浮窗口
- Android 悬浮窗体问题
- iOS静态库.framework的制作
- C判断char型和unsigned int型比较大小,LmiQueryCSmd
- 002day(学习了二进制和十六进制的基本概念)
- OpenMV色块定位-电赛的半个总结
- ThreadLocal类
- Android 悬浮窗踩坑体验
- Java 开发工具–Lombok介绍
- linux chmod和文件权限的设定
- php学习笔记:登录练习(3)
- 2.2.16锁对象的改变
- C语言中使用空的宏定义的作用
- 高斯消元法
- Netty源码分析:AbstractByteBuf
- Servlet 工程 web.xml 中的 servlet 和 servlet-mapping 标签