Android非本应用获取屏幕点击坐标(实践篇)

前言

这一周又遇到个麻烦事儿,公司对接了一个老外客户,要求在现有的USDK密码键盘界面自定义密码界面风格,但密码按键的处理以及获取密码数据需要USDK去实现,也就是说老外只负责画界面,把绘制出的界面中的控件坐标传下来(控件的左上角和右下即角坐标),不处理点击事件,让USDK把click事件屏蔽并返回密码数据给他们(这需求也是没谁了~~无力吐槽),so开动吧!谁让我是苦逼的程序猿呢~

正文

首先我们先整理下需要做的事儿:

  1. 如何屏蔽应用层点击事件并获取点击的位置;
  2. 考虑到交互的安全性,输入密码界面需屏蔽最近任务键,Home键,Back键以及下拉任务栏;

针对上面问题1,我首先想到的是setOnTouchListener方法,获取点击的位置不正合适吗?可问题来了,不是一个进程的如何获取到界面的MotionEvent方法呢?那我可以在USDK中添加一个空白的View上去,这样不久可以获取了吗?而且通过设置View的属性也正好可以消耗点击事件,一举两得呀~至于问题2,这个修改系统就OK了,so方案有了:

  1. 添加透明空白View,通过setOnTouchListener方法获取用户点击位置;
  2. 修改系统,找到Home键,Back键以及下拉任务栏的事件处理位置,使用SystemProperties类设置自定义系统属性,在事件处理位置截取判断使能即可;

获取点击位置坐标

这里我定义了一个空的View,layout文件如下:代码块

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/offlinepin_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@android:color/transparent">

    <!--显示透明View可见 方便调试,后续调试OK屏蔽即可-->
    <TextView
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="test"/>

</LinearLayout>

这里通过设置android:background="@android:color/transparent" 将其设置为透明;然后在USDK中添加本View,主要代码如下:代码块

	LinearLayout mLayout = (LinearLayout) LayoutInflater.from(TopwiseApplication.getContext()).
	                inflate(R.layout.view_offlinepin, null);
	WindowManager.LayoutParams params = new WindowManager.LayoutParams();
	// 设置框口属性为系统提示级别,属于最上层显示
	params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
	// 设置View颜色支持属性
	params.format = PixelFormat.RGBA_8888;
	params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
	        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
	//宽 高显示限制
	params.width = WindowManager.LayoutParams.MATCH_PARENT;
	params.height = WindowManager.LayoutParams.MATCH_PARENT;
	SDKLog.d(TAG, "addView");
	//if (manager != null) {
   
    //    manager.addView(layout, params);
    //    isAddView = true;
    //}
	mHandler = new ViewHandler(mWindowManager, mLayout, params);

此处先获取layout实例,通过WindowManager服务去addView,WindowManager可通过mWindowManager = (WindowManager) TopwiseApplication.getContext().
getSystemService(Context.WINDOW_SERVICE);获取;
解释下WindowManager.LayoutParams布局属性,此属性用于设置当前添加的View的显示,活动包括事件处理等相关配置,其中flags值比较重要,介绍几个常用的:

FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
//Constant Value: 1 (0x00000001)
只要这个window对用户是可见的,则允许在屏幕开启的时候锁定屏幕
这个flag可以单独的使用,也可以配合FLAG_KEEP_SCREEN_ON和(或者) FLAG_SHOW_WHEN_LOCKED使用

FLAG_DIM_BEHIND
//Constant Value: 2 (0x00000002)
所有在这个window之后的会变暗,
使用dimAmount属性来控制变暗的程度(1.0不透明,0.0完全透明)

FLAG_NOT_FOCUSABLE
//Constant Value: 8 (0x00000008)
设置之后window永远不会获取焦点,所以用户不能给此window发送点击事件
焦点会传递给在其下面的可获取焦点的window
这个flag同时会启用 FLAG_NOT_TOUCH_MODAL flag , 不管你有没有手动设置
设置这个flag同时表明了这个window不会和软键盘交互

FLAG_NOT_TOUCHABLE
//Constant Value: 16 (0x00000010)
这个window永远无法获取点击事件

FLAG_NOT_TOUCH_MODAL
//Constant Value: 32 (0x00000020)
即使这个window是可获取焦点的,
也允许window之外点击事件传递给其他在其之后的window
如果不设置这个值
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值