J'essaie de créer un bouton / une image cliquable toujours en haut qui reste en haut de toutes les fenêtres tout le temps.
La preuve de concept est
- ici - Smart Taskbar (sur AppBrain)
- et ici V1.4.0 style barre latérale SWKey - sauveur de boutons (sur les développeurs xda)
J'ai réussi et j'ai maintenant un service en cours d'exécution. Le service affiche tout le temps du texte dans le coin supérieur gauche de l'écran tandis que l'utilisateur peut interagir librement avec le reste des applications de manière normale.
Ce que je fais, c'est une sous-classe ViewGroup
et l'ajouter au gestionnaire de fenêtres racine avec un indicateur TYPE_SYSTEM_OVERLAY
. Maintenant, je veux ajouter un bouton / image cliquable à la place de ce texte qui peut recevoir des événements tactiles sur lui-même. J'ai essayé de remplacer "onTouchEvent" pour l'ensemble ViewGroup
mais il ne reçoit aucun événement.
Comment puis-je recevoir des événements uniquement sur certaines parties de mon groupe de vues toujours visible? Veuillez suggérer.
public class HUD extends Service {
HUDView mView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
mView = new HUDView(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
0,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
if(mView != null)
{
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
mView = null;
}
}
}
class HUDView extends ViewGroup {
private Paint mLoadPaint;
public HUDView(Context context) {
super(context);
Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show();
mLoadPaint = new Paint();
mLoadPaint.setAntiAlias(true);
mLoadPaint.setTextSize(10);
mLoadPaint.setARGB(255, 255, 0, 0);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("Hello World", 5, 15, mLoadPaint);
}
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//return super.onTouchEvent(event);
Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
return true;
}
}
onDraw()
téléphone soit appelé. Ne devrait pasdispatchDraw()
être remplacé à la place? Voir groups.google.com/forum/?fromgroups#!topic/android-developers/…Réponses:
Cela pourrait être une solution stupide. Mais ça marche. Si vous pouvez l'améliorer, faites-le moi savoir.
OnCréez votre service: j'ai utilisé le
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
drapeau. C'est le seul changement de service.Maintenant, vous commencerez à obtenir chaque événement de clic. Vous devez donc rectifier dans votre gestionnaire d'événements.
Dans votre événement tactile ViewGroup
Vous devrez peut-être également ajouter cette autorisation à votre manifeste:
la source
À la suite de la réponse de @Sam Lu, Indeed Android 4.x empêche certains types d'écouter des événements tactiles extérieurs, mais certains types, tels que
TYPE_SYSTEM_ALERT
, font toujours le travail.Exemple
Autorisations
la source
A partir de Android 4.x, l' équipe Android fixe un problème de sécurité potentiel en ajoutant une nouvelle fonction
adjustWindowParamsLw()
dans laquelle il ajouteraFLAG_NOT_FOCUSABLE
,FLAG_NOT_TOUCHABLE
et supprimer desFLAG_WATCH_OUTSIDE_TOUCH
drapeaux pourTYPE_SYSTEM_OVERLAY
les fenêtres.Autrement dit, une
TYPE_SYSTEM_OVERLAY
fenêtre ne recevra aucun événement tactile sur la plate-forme ICS et, bien sûr, son utilisationTYPE_SYSTEM_OVERLAY
n'est pas une solution viable pour ICS et les futurs appareils.la source
Je suis l'un des développeurs du SDK Tooleap . Nous proposons également aux développeurs un moyen d'afficher toujours les fenêtres et les boutons supérieurs, et nous avons fait face à une situation similaire.
Un problème que les réponses ici n'ont pas résolu est celui des «boutons sécurisés» Android.
Les boutons sécurisés ont la
filterTouchesWhenObscured
propriété qui signifie qu'ils ne peuvent pas interagir avec, s'ils sont placés sous une fenêtre, même si cette fenêtre ne reçoit aucune touche. Citant la documentation Android:Un exemple d'un tel bouton est le bouton d' installation lorsque vous essayez d'installer des apks tiers. Toute application peut afficher un tel bouton si elle ajoute à la disposition de la vue la ligne suivante:
Si vous affichez une fenêtre toujours au-dessus d'un "bouton sécurisé", toutes les parties de bouton sécurisées couvertes par une superposition ne gèreront aucune touche, même si cette superposition n'est pas cliquable. Donc, si vous prévoyez d'afficher une telle fenêtre, vous devez fournir à l'utilisateur un moyen de la déplacer ou de la fermer. Et si une partie de votre superposition est transparente, sachez que votre utilisateur peut être confus pourquoi un certain bouton de l'application sous-jacente ne fonctionne-t-il pas soudainement pour lui.
la source
TRAVAILLER TOUJOURS SUR LE BOUTON D'IMAGE SUPÉRIEUR
tout d'abord désolé pour mon anglais
je modifie vos codes et fais en sorte que le bouton d'image de travail qui écoute son événement tactile ne donne pas de contrôle tactile à ses éléments d'arrière-plan.
il donne également aux auditeurs tactiles d'autres éléments
les modifications des boutons sont en bas et à gauche
vous pouvez modifier les modifications, mais vous devez modifier les cordinats dans l'événement tactile dans l'élément if
la source
En fait, vous pouvez essayer WindowManager.LayoutParams.TYPE_SYSTEM_ERROR au lieu de TYPE_SYSTEM_OVERLAY. Cela peut ressembler à un hack, mais il vous permet d'afficher la vue par-dessus tout et d'obtenir toujours des événements tactiles.
la source
TYPE_SYSTEM_OVERLAY Cette constante est déconseillée depuis le niveau d'API 26. Utilisez plutôt TYPE_APPLICATION_OVERLAY. ou ** pour les utilisateurs inférieurs et supérieurs à Android 8
la source
Essaye ça. Fonctionne bien dans ICS. Si vous souhaitez arrêter le service, cliquez simplement sur la notification générée dans la barre d'état.
METTRE À JOUR
Échantillon ici
Pour créer une vue de superposition, lors de la configuration des LayoutParams, ne définissez PAS le type sur TYPE_SYSTEM_OVERLAY.
la source
Voici une solution simple.Tout ce dont vous avez besoin est de gonfler la disposition XML comme vous le faites sur les adaptateurs de liste, faites simplement la disposition XML pour la gonfler. Voici le code dont vous avez besoin.
la source
Trouvé une bibliothèque qui fait exactement cela: https://github.com/recruit-lifestyle/FloatingView
Il y a un exemple de projet dans le dossier racine. Je l'ai exécuté et cela fonctionne comme requis. L'arrière-plan est cliquable - même s'il s'agit d'une autre application.
la source
Il utilise la permission "android.permission.SYSTEM_ALERT_WINDOW" tutoriel complet sur ce lien: http://androidsrc.net/facebook-chat-like-floating-chat-heads/
la source
Eh bien essayez mon code, au moins il vous donne une chaîne en superposition, vous pouvez très bien le remplacer par un bouton ou une image. Vous ne croirez pas que c'est ma toute première application Android LOL. Quoi qu'il en soit, si vous êtes plus expérimenté avec les applications Android que moi, veuillez essayer
la source
Si quelqu'un lit encore ce fil et n'est pas en mesure de le faire fonctionner, je suis vraiment désolé de vous dire que cette façon d'intercepter l'événement de mouvement est considérée comme un bug et une correction dans Android> = 4.2.
L'événement de mouvement que vous avez intercepté, bien que son action soit ACTION_OUTSIDE, renvoie 0 dans getX et getY. Cela signifie que vous ne pouvez pas voir toute la position du mouvement à l'écran, ni rien faire. Je sais que le doc a dit qu'il obtiendrait x et y, mais la vérité est qu'il ne le fera PAS. Il semble que ce soit pour bloquer l'enregistreur de frappe.
Si quelqu'un a une solution de contournement, veuillez laisser votre commentaire.
ref: Pourquoi ACTION_OUTSIDE retourne 0 à chaque fois sur KitKat 4.4.2?
https://code.google.com/p/android/issues/detail?id=72746
la source
en utilisant le service, vous pouvez y parvenir:
la source
La réponse de @Sarwar Erfan ne fonctionne plus car Android ne permet pas d'ajouter la vue avec WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY à la fenêtre pour qu'elle ne soit plus accessible, même avec WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH.
J'ai trouvé une solution à ce problème. Vous pouvez le vérifier dans la question suivante
Lorsque vous ajoutez une vue à une fenêtre avec WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, il ne reçoit pas d'événement tactile
la source
Il s'agit d'une ancienne question, mais récemment Android prend en charge les bulles. Les bulles vont bientôt être lancées mais actuellement les développeurs peuvent commencer à les utiliser, elles sont conçues pour être une alternative à l'utilisation
SYSTEM_ALERT_WINDOW
. Des applications comme (Facebook Messenger et MusiXMatch utilisent le même concept).Les bulles sont créées via l'API de notification, vous envoyez votre notification comme d'habitude. Si vous voulez qu'il bouillonne, vous devez y attacher des données supplémentaires. Pour plus d'informations sur Bubbles, vous pouvez consulter le Guide officiel du développeur Android sur Bubbles .
la source