我基本上试图从系统覆盖中获取所有触摸事件数据,根据此触摸数据移动我的精灵,然后允许OS /主屏幕/浏览器按照应有的方式对数据进行操作(反之亦然)。我发现了类似的问题,但没有任何东西可以引导我到任何我未曾去过的地方:
Getting the View that is receiving all the touch events
(已实施,结果如下)Creating a system overlay window (always on top)
我可以做什么:
我可以通过移动我的精灵并且不允许操作系统/主屏幕/浏览器看到它们中的任何一个来抓住所有触摸事件并对其进行操作,或者我可以允许触摸事件通过并且仅获得“TOUCH_OUTSIDE”我的应用程序要采取行动。
我未实现的目标:
我不能为我的生活找到一种方法来同时处理数据。我无法实现的唯一方法是:拦截我的APP中的数据并将其传递到OS / homescreen / browser以使用允许OS / homescreen / browser首先获取数据,然后以某种方式获取信息回调允许操作系统/主屏幕/浏览器获取数据,对数据进行操作,并轮询他们的滚动/位置值,以便在我的APP中对其进行操作。
我担心这是不可能的,我想我在某些文档中读到了一些我现在无法找到的内容:“无论是全部还是全无,您的视图都可以获取所有事件,或者都不是”
(为了避免混淆,我并不是说我有两个视图。我的意思是我有一个视图通过覆盖操作系统/主屏幕/浏览器的活动/服务来控制。如果你愿意,就像一块玻璃。)
感谢您提供的任何有用信息,非常感谢!
[更新]在下面的问题上发表我自己的文档,以免混淆。
发现这个文档几乎说明不可能同时做到这两点:Android : Multi touch and TYPE_SYSTEM_OVERLAY
他们讨论了解决方法,但我认为它们中的任何一个都不会真正适用于我正在尝试做的事情。两者都将事件发布到底层应用程序,并且能够窥探它们以便为自己采取行动。
要创建叠加视图,在设置LayoutParams时,需要将类型设置为TYPE_SYSTEM_OVERLAY并使用标志FLAG_WATCH_OUTSIDE_TOUCH。这提出了一个问题,因为Android文档声明:“您不会收到完整的向下/移动/向上手势,只有第一个向下的位置作为ACTION_OUTSIDE。”为了接收完整的触摸事件数组,您需要使用TYPE_SYSTEM_ALERT类型,但这会导致叠加层接管屏幕并停止与其他元素的交互。
任何人都想不同意我很想听到好消息:-D
您可以使用GestureOverlayView,如果您想要隐藏它绘制的线条,您可以将颜色设置为Transparent#00000000,这样它就不会显示,然后您可以捕获所有触摸和手势。
http://developer.android.com/resources/articles/gestures.html
我在寻找同样的事情。
这个标志为我做了FLAG_NOT_TOUCH_MODAL
适用于Android 7和8设置,如下所示。
到目前为止,我实现的唯一操作是关闭覆盖窗口。
我还使用了Example System Overlay Code on Github的代码来获取事件。
顺便说一句,谷歌地图在Android 8上做得非常好。您可以拖动它们的叠加窗口,调整大小或关闭它。所有其他应用程序都可以正常工作。
var type = 0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
var flags = FLAG_NOT_TOUCH_MODAL
mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)
这不是最佳解决方案,但可行。重新启动服务切换不可触摸的标志。将boolean extra添加到Intent,Intent用于启动服务以确定以前的状态切换值。更好的实现方式是在窗口监听时触发触摸意图,在不监听时触发固定时间段。
public class bleh extends Service {
public void onCteqwer(int i) {
Context context; Class <bleh> context1 = bleh.class;
WindowManager.LayoutParams params = null;
WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);
//check previous state of service
if(i==0)
params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);
if(i==1)
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View mViw = inflater.inflate(arg, null);
mViw.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mang.addView(mViw, params);
Intent z = new Intent(context, context1);
if(i==0)
z.putExtra("name", 1);
if(i==1)
z.putExtra("name", 0);
stopSelf();
startService(z);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Bundle i=intent.getExtras();
int userName = 0;
if (i != null)
{
userName = i.getInt("name");
onCteqwer(userName);
}
}
}