Ich versuche, eine Schaltfläche / ein anklickbares Bild zu erstellen, die immer über allen Fenstern angezeigt wird.
Der Proof of Concept ist
- hier - Smart Taskbar (auf AppBrain)
- und hier V1.4.0 Sidebar-Stil SWKey - Button Saviour (bei xda-Entwicklern)
Ich war erfolgreich und habe jetzt einen laufenden Dienst. Der Dienst zeigt ständig Text in der oberen linken Ecke des Bildschirms an, während der Benutzer auf normale Weise frei mit anderen Apps interagieren kann.
Was ich mache, ist eine Unterklasse ViewGroup
und füge sie dem Root-Fenstermanager mit Flag hinzu TYPE_SYSTEM_OVERLAY
. Jetzt möchte ich anstelle dieses Textes eine Schaltfläche / ein anklickbares Bild hinzufügen, das Berührungsereignisse für sich selbst empfangen kann. Ich habe versucht, "onTouchEvent" für das Ganze zu überschreiben, ViewGroup
aber es wird kein Ereignis empfangen.
Wie kann ich Ereignisse nur für bestimmte Teile meiner Gruppe "Immer im Blick" empfangen? Bitte vorschlagen.
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()
angerufen werden. SolltedispatchDraw()
stattdessen nicht überschrieben werden? Siehe groups.google.com/forum/?fromgroups#!topic/android-developers/…Antworten:
Dies könnte eine dumme Lösung sein. Aber es funktioniert. Wenn Sie es verbessern können, lassen Sie es mich bitte wissen.
OnCreate Ihres Dienstes: Ich habe
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
flag verwendet. Dies ist die einzige Änderung im Service.Jetzt erhalten Sie jedes einzelne Klickereignis. Sie müssen also in Ihrem Event-Handler korrigieren.
In Ihrem ViewGroup-Touch-Ereignis
Möglicherweise müssen Sie diese Berechtigung auch zu Ihrem Manifest hinzufügen:
quelle
Nach der Antwort von @Sam Lu verhindert Android 4.x zwar, dass bestimmte Typen externe Berührungsereignisse abhören, aber einige Typen, z. B.
TYPE_SYSTEM_ALERT
, erledigen den Job immer noch.Beispiel
Berechtigungen
quelle
Beginnend mit Android 4.x, Fest Android - Team ein potenzielles Sicherheitsproblem durch eine neue Funktion hinzugefügt ,
adjustWindowParamsLw()
in dem es hinzuzufügenFLAG_NOT_FOCUSABLE
,FLAG_NOT_TOUCHABLE
und entfernenFLAG_WATCH_OUTSIDE_TOUCH
Flaggen fürTYPE_SYSTEM_OVERLAY
Fenster.Das heißt, ein
TYPE_SYSTEM_OVERLAY
Fenster empfängt kein Berührungsereignis auf der ICS-Plattform und die VerwendungTYPE_SYSTEM_OVERLAY
ist natürlich keine praktikable Lösung für ICS und zukünftige Geräte.quelle
Ich bin einer der Entwickler des Tooleap SDK . Wir bieten Entwicklern auch die Möglichkeit, immer oben Fenster und Schaltflächen anzuzeigen, und wir haben uns mit einer ähnlichen Situation befasst.
Ein Problem, das die Antworten hier nicht angesprochen haben, ist das der Android "Secured Buttons".
Gesicherte Schaltflächen haben die
filterTouchesWhenObscured
Eigenschaft, dass sie nicht interagiert werden können, wenn sie unter einem Fenster platziert werden, selbst wenn dieses Fenster keine Berührungen erhält. Zitieren der Android-Dokumentation:Ein Beispiel für eine solche Schaltfläche ist die Schaltfläche " Installieren" , wenn Sie versuchen, Apks von Drittanbietern zu installieren. Jede App kann eine solche Schaltfläche anzeigen, wenn dem Ansichtslayout die folgende Zeile hinzugefügt wird:
Wenn Sie über einer "gesicherten Schaltfläche" ein Fenster anzeigen, das immer oben angezeigt wird, können alle gesicherten Schaltflächenteile, die von einer Überlagerung abgedeckt werden, keine Berührungen verarbeiten, auch wenn diese Überlagerung nicht anklickbar ist. Wenn Sie also ein solches Fenster anzeigen möchten, sollten Sie dem Benutzer die Möglichkeit geben, es zu verschieben oder zu schließen. Und wenn ein Teil Ihres Overlays transparent ist, berücksichtigen Sie, dass Ihr Benutzer möglicherweise verwirrt ist, warum eine bestimmte Schaltfläche in der zugrunde liegenden App nicht plötzlich für ihn funktioniert.
quelle
IMMER AUF DER OBEREN BILD-TASTE ARBEITEN
Zunächst einmal entschuldigen Sie mein Englisch
Ich bearbeite Ihre Codes und lasse die Schaltfläche für Arbeitsbilder, die sein Berührungsereignis abhört, seinen Hintergrundelementen keine Berührungssteuerung geben.
Es gibt auch Touch-Listener für andere Elemente
Schaltflächen sind unten und links
Sie können Alingments ändern, aber Sie müssen Koordinaten im Berührungsereignis im if-Element ändern
quelle
Sie können WindowManager.LayoutParams.TYPE_SYSTEM_ERROR anstelle von TYPE_SYSTEM_OVERLAY ausprobieren. Es mag wie ein Hack klingen, aber Sie können die Ansicht über alles anzeigen und trotzdem Berührungsereignisse erhalten.
quelle
TYPE_SYSTEM_OVERLAY Diese Konstante ist seit API-Ebene 26 veraltet. Verwenden Sie stattdessen TYPE_APPLICATION_OVERLAY. oder ** für Benutzer unter und über Android 8
quelle
Versuche dies. Funktioniert gut in ICS. Wenn Sie den Dienst beenden möchten, klicken Sie einfach auf die in der Statusleiste generierte Benachrichtigung.
AKTUALISIEREN
Probieren Sie hier
Um eine Überlagerungsansicht zu erstellen, setzen Sie beim Einrichten der LayoutParams den Typ NICHT auf TYPE_SYSTEM_OVERLAY.
quelle
Hier ist eine einfache Lösung: Sie müssen lediglich das XML-Layout wie bei Listenadaptern aufblasen. Erstellen Sie einfach ein XML-Layout, um es aufzublasen. Hier ist Code, den Sie alles brauchen.
quelle
Es wurde eine Bibliothek gefunden, die genau das tut: https://github.com/recruit-lifestyle/FloatingView
Im Stammordner befindet sich ein Beispielprojekt. Ich habe es ausgeführt und es funktioniert wie erforderlich. Der Hintergrund ist anklickbar - auch wenn es sich um eine andere App handelt.
quelle
Es verwendet die Berechtigung "android.permission.SYSTEM_ALERT_WINDOW", das vollständige Tutorial für diesen Link: http://androidsrc.net/facebook-chat-like-floating-chat-heads/
quelle
Probieren Sie meinen Code aus, zumindest erhalten Sie eine Zeichenfolge als Überlagerung. Sie können ihn sehr gut durch eine Schaltfläche oder ein Bild ersetzen. Sie werden nicht glauben, dass dies meine erste Android-App LOL ist. Wenn Sie mehr Erfahrung mit Android-Apps haben als ich, versuchen Sie es bitte
quelle
Wenn jemand diesen Thread noch liest und nicht in der Lage ist, dies zum Laufen zu bringen, tut es mir sehr leid, Ihnen zu sagen, dass diese Art, Bewegungsereignisse abzufangen, in Android> = 4.2 als Fehler und Fehlerbehebung angesehen wird.
Das Bewegungsereignis, das Sie abgefangen haben, hat zwar die Aktion ACTION_OUTSIDE, gibt jedoch 0 in getX und getY zurück. Dies bedeutet, dass Sie nicht alle Bewegungspositionen auf dem Bildschirm sehen und auch nichts tun können. Ich weiß, dass der Arzt sagte, dass es x und y bekommen wird, aber die Wahrheit ist, dass es NICHT wird. Es scheint, dass dies den Key Logger blockieren soll.
Wenn jemand eine Problemumgehung hat, hinterlassen Sie bitte Ihren Kommentar.
ref: Warum gibt ACTION_OUTSIDE in KitKat 4.4.2 jedes Mal 0 zurück?
https://code.google.com/p/android/issues/detail?id=72746
quelle
Mit dem Service können Sie Folgendes erreichen:
quelle
Die Antwort von @Sarwar Erfan funktioniert nicht mehr, da Android das Hinzufügen einer Ansicht mit WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY zum Fenster nicht mehr zum Berühren zulässt, auch nicht mit WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH.
Ich habe eine Lösung für dieses Problem gefunden. Sie können es in der folgenden Frage überprüfen
Beim Hinzufügen einer Ansicht zum Fenster mit WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY wird kein Berührungsereignis angezeigt
quelle
Dies ist eine alte Frage, aber seit kurzem unterstützt Android Bubbles. Bubbles werden bald gestartet, aber derzeit können Entwickler sie verwenden. Sie sind als Alternative zur Verwendung konzipiert
SYSTEM_ALERT_WINDOW
. Apps wie (Facebook Messenger und MusiXMatch verwenden dasselbe Konzept).Blasen werden über die Benachrichtigungs-API erstellt. Sie senden Ihre Benachrichtigung wie gewohnt. Wenn Sie möchten, dass es sprudelt, müssen Sie einige zusätzliche Daten anhängen. Weitere Informationen zu Bubbles finden Sie im offiziellen Android Developer Guide on Bubbles .
quelle