问题
My question is pretty much similar to this one. The question was asked almost 3 years ago and was not answered yet.
My goal is to catch all touch-events using a system-overlay (see code below), change the event's parameters (i.e. event.x = event.getX()+5) and pass it on to the current running application (any application).
Currently, I can catch all MotionEvent's by using the TYPE_PHONE flag OR pass all of the events to to the current application by using the TYPE_SYSTEM_OVERLAY, but not both.
The application is used for accessibility purpose so using any accessibility ability is also an option.
The basic code for the overlay service:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
public class OverlayService extends Service {
OverlayView oView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
oView = new OverlayView(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.TYPE_PHONE, // TYPE_SYSTEM_OVERLAY
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(oView, params);
}
@Override
public void onDestroy() {
super.onDestroy();
if(oView != null)
{
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(oView);
oView = null;
}
}
}
class OverlayView extends View {
private Paint mLoadPaint;
public OverlayView(Context context) {
super(context);
setBackgroundColor(Color.BLUE);
getBackground().setAlpha(128);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
Toast.makeText(getContext(), "Touch", Toast.LENGTH_SHORT).show();
//********************** THIS IS WHERE I NEED YOUR HELP *************
}
return false;
}
}
Any advise will be much appreciated.
回答1:
My goal is to catch all touch-events using a system-overlay (see code below), change the event's parameters (i.e. event.x = event.getX()+5) and pass it on to the current running application (any application).
That is not possible, for privacy and security reasons.
Currently, I can catch all MotionEvent's by using the TYPE_PHONE flag OR pass all of the events to to the current application by using the TYPE_SYSTEM_OVERLAY, but not both.
Correct. That was the fix added in Android 4.0 to defend against tapjacking attacks, which is what you are trying to do whether you realize it or not.
The application is used for accessibility purpose so using any accessibility ability is also an option.
I cannot rule out that possibility, though I don't see low-level touch events in AccessibilityEvent, let alone modifying them. This would be a fairly radical departure from the approach that you are taking and as such would warrant a separate Stack Overflow question.
来源:https://stackoverflow.com/questions/29156556/android-use-system-overlay-to-change-touch-events