一个服务从 MainActivity 启动
public void buttonClicked(View v){
//method to call after button is clicked in MainActivity
if(v.getTag() == null){
globalService = new Intent(this,GlobalTouchService.class);
startService(globalService);//start the service
v.setTag("on");
Toast.makeText(this, "Start Service", Toast.LENGTH_SHORT).show();
}
else{
stopService(globalService);
v.setTag(null);
Toast.makeText(this, "Stop Service", Toast.LENGTH_SHORT).show();
}
}
在服务的 OnCreate 中,将创建一个透明布局并实现触摸侦听器。
public class GlobalService extends Service{
@Override
public void onCreate() {
super.onCreate();
// create linear layout
touchLayout = new LinearLayout(this);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
touchLayout.setLayoutParams(lp);
// set on touch listener
//touchLayout.setOnTouchListener(this);
// fetch window manager object
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// set layout parameter of window manager
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.LEFT | Gravity.TOP;
mWindowManager.addView(touchLayout, mParams);
touchLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("Action :" + event.getAction() + "t X :" + event.getRawX() + "t Y :"+ event.getRawY());
return false;
}
});
}
由于 onTouch 返回 false,因此当我们单击透明布局上方时,控件应移动到后台 MainActivity。但事实并非如此.可能是什么原因?
我不认为控件应该移动到后台 MainActivity - 这将是一个重大的安全风险,因为您将能够实现类似触摸事件记录器的东西。获得记录的触摸事件列表后,您可以将它们映射到单独键盘键的坐标并泄露用户的密码!
操作系统以这种方式行事是绝对没有意义的。
由于服务不是您活动的一部分,因此您进入的所有事件都不会到达该活动。如果你想要的只是让事件通过,你可以通过使你的新层不可触摸来实现:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
但是您必须考虑到您不会在侦听器中获取事件。