Capter les interactions de l'écran en background
Bonsoir,
Dans un projet j'ai besoin de capter toutes les interactions que l'utilisateur produira sur l'écran, peu importe l'application se situant au premier plan. Je sais tout à fait que c'est considéré comme une faille de sécurité qui est corrigée depuis ICS, mais c'est faisable dans les versions précédentes. Mon projet est dans le cadre de recherches et n'a pas vocation à être diffusé. Enfin me rappeler que ce que je cherche à produire est considéré comme une faille de sécurité ne m'aidera pas.
Je suis parti du code trouvé ici, qui consiste à créer un service implémentant OnTouchListener et à placer un widget en Overlay. Voici le code que j'obtiens :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| package com.smart.taskbar;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.Toast;
public class HUD extends Service implements OnTouchListener {
Button mButton;
@Override
public IBinder
onBind(Intent intent) {
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
super.onCreate();
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(empty, params);
}
@Override
public void onDestroy() {
super.onDestroy();
if(mButton != null) {
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mButton);
mButton = null;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TEST", event.getX() + " " + event.getY());
return true;
}
} |
Cela fonctionne presque, mais la méthode onTouch n'est appelée qu'une seule fois malgré le "return true", ce qui empêche la détection des Drag.
Il est possible de remplacer "TYPE_SYSTEM_OVERLAY" par "TYPE_SYSTEM_ALERT", cela permet de détecter les drags car onTouch est correctement appelée en boucle, cependant les évènements ne sont plus transmis à l'activité visible, ce qui rend le smartphone inutilisable.
L'idéal serait donc de combiner les deux : pouvoir détecter les drags et que les évènements soient transmis à l'activité visible afin de ne pas déranger l'utilisateur.
J'ai également essayé de créer une vue héritant de View et redéfinissant onTouchEvent mais le résultat est le même.
Avez vous une quelconque piste? Je précise que l'API max disponible est 10, ICS supprimant l'effet de "TYPE_SYSTEM_OVERLAY".
Merci et bonne soirée.