Próbuję utworzyć zawsze przycisk / obraz, który zawsze jest na górze, i który pozostaje cały czas nad wszystkimi oknami.
Dowód koncepcji jest
- tutaj - inteligentny pasek zadań (w AppBrain)
- i tutaj V1.4.0 Styl paska bocznego SWKey - Zbawiciel przycisków (w programistach XDA)
Odniosłem sukces i mam teraz działającą usługę. Serwis wyświetla cały tekst w lewym górnym rogu ekranu, podczas gdy użytkownik może swobodnie wchodzić w interakcje z resztą aplikacji w normalny sposób.
To, co robię, to podklasa ViewGroup
i dodaj ją do menedżera okien root z flagą TYPE_SYSTEM_OVERLAY
. Teraz chcę dodać przycisk / klikalny obraz zamiast tego tekstu, który może odbierać zdarzenia dotykowe na sobie. Próbowałem przesłonić „onTouchEvent” dla całości, ViewGroup
ale nie otrzymało żadnego zdarzenia.
Jak mogę odbierać zdarzenia tylko w niektórych częściach mojej grupy zawsze na wierzchu? Uprzejmie sugeruję.
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()
jest to, że nazywasz się.dispatchDraw()
Zamiast tego nie należy go zastępować? Zobacz groups.google.com/forum/?fromgroups#!topic/android-developers/…Odpowiedzi:
To może być głupie rozwiązanie. Ale to działa. Jeśli możesz to poprawić, daj mi znać.
OnCreate of Service: Użyłem
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
flagi. To jedyna zmiana usługi.Teraz zaczniesz otrzymywać każde zdarzenie kliknięcia. Tak więc musisz sprostować w module obsługi zdarzeń.
W zdarzeniu dotykowym ViewGroup
Konieczne może być również dodanie tego uprawnienia do manifestu:
źródło
Po odpowiedzi @Sam Lu, Indeed Android 4.x blokuje niektórym typom odsłuchiwanie zewnętrznych zdarzeń dotykowych, ale niektóre typy, takie jak
TYPE_SYSTEM_ALERT
, nadal wykonują zadanie.Przykład
Uprawnienia
źródło
Zaczynając z Android 4.x, Android zespół naprawiono potencjalny problem bezpieczeństwa, dodając nową funkcję
adjustWindowParamsLw()
, w którym będzie dodaćFLAG_NOT_FOCUSABLE
,FLAG_NOT_TOUCHABLE
i usunąćFLAG_WATCH_OUTSIDE_TOUCH
flagi naTYPE_SYSTEM_OVERLAY
oknach.Oznacza to, że
TYPE_SYSTEM_OVERLAY
okno nie otrzyma żadnego zdarzenia dotyku na platformie ICS i, oczywiście, użycieTYPE_SYSTEM_OVERLAY
nie jest praktycznym rozwiązaniem dla ICS i przyszłych urządzeń.źródło
Jestem jednym z programistów Tooleap SDK . Zapewniamy również programistom możliwość wyświetlania zawsze w górnych oknach i przyciskach, i poradziliśmy sobie z podobną sytuacją.
Jednym z problemów, których tutaj nie rozwiązano, jest problem „zabezpieczonych przycisków” Androida.
Zabezpieczone przyciski mają
filterTouchesWhenObscured
właściwość, co oznacza, że nie można z nimi wchodzić w interakcje, jeśli zostaną umieszczone pod oknem, nawet jeśli okno to nie zostanie dotknięte. Cytując dokumentację Androida:Przykładem takiego przycisku jest przycisk instalacyjny , gdy próbujesz zainstalować aplikacje innych firm. Każda aplikacja może wyświetlić taki przycisk, jeśli doda do układu widoku następujący wiersz:
Jeśli wyświetlasz okno „Zawsze na wierzchu” nad „Zabezpieczonym przyciskiem”, więc wszystkie zabezpieczone części przycisku, które są pokryte nakładką, nie obsługują żadnych dotknięć, nawet jeśli nakładki tej nie można kliknąć. Jeśli więc planujesz wyświetlić takie okno, powinieneś dać użytkownikowi możliwość jego przeniesienia lub odrzucenia. A jeśli część twojej nakładki jest przezroczysta, weź pod uwagę, że użytkownik może być zdezorientowany, dlaczego pewien przycisk w podstawowej aplikacji nie działa dla niego nagle.
źródło
ZAWSZE PRACUJĄC NA GÓRNYM PRZYCISKU OBRAZU
przede wszystkim przepraszam za mój angielski
edytuję kody i sprawiam, że działający przycisk obrazu, który nasłuchuje jego zdarzenia dotykowego, nie daje kontroli dotykowej jego elementom tła.
Daje także dotykowym słuchaczom inne elementy
przyciski są dolne i lewe
możesz wymieniać alingi, ale musisz dotykać kordinatów w zdarzeniu dotykowym w elemencie if
źródło
W rzeczywistości możesz wypróbować WindowManager.LayoutParams.TYPE_SYSTEM_ERROR zamiast TYPE_SYSTEM_OVERLAY. Może to zabrzmieć jak włamanie, ale pozwala wyświetlać widok nad wszystkim i nadal otrzymywać zdarzenia dotykowe.
źródło
TYPE_SYSTEM_OVERLAY Ta stała była przestarzała od poziomu API 26. Zamiast tego użyj TYPE_APPLICATION_OVERLAY. lub ** dla użytkowników poniżej i powyżej Androida 8
źródło
Spróbuj tego. Działa dobrze w ICS. Jeśli chcesz zatrzymać usługę, po prostu kliknij powiadomienie wygenerowane na pasku stanu.
AKTUALIZACJA
Próbka tutaj
Aby utworzyć widok nakładki, podczas konfigurowania LayoutParams NIE ustawiaj typu na TYPE_SYSTEM_OVERLAY.
źródło
Oto kilka prostych rozwiązań: Wszystko czego potrzebujesz to nadmuchać układ XML, tak jak robisz to w przypadku list adapterów, po prostu utwórz układ XML, aby go napompować. Oto kod, którego potrzebujesz.
źródło
Znaleziono bibliotekę, która właśnie to robi: https://github.com/recruit-lifestyle/FloatingView
W folderze głównym znajduje się przykładowy projekt. Uruchomiłem go i działa zgodnie z wymaganiami. Tło można kliknąć - nawet jeśli jest to inna aplikacja.
źródło
Wykorzystuje uprawnienia „android.permission.SYSTEM_ALERT_WINDOW” pełny samouczek na ten link: http://androidsrc.net/facebook-chat-like-floating-chat-heads/
źródło
Wypróbuj mój kod, przynajmniej daje ci ciąg jako nakładkę, możesz bardzo dobrze zastąpić go przyciskiem lub obrazem. Nie uwierzysz, że to moja pierwsza aplikacja LOL na Androida. W każdym razie, jeśli masz większe doświadczenie z aplikacjami na Androida niż ja, spróbuj
źródło
Jeśli ktoś nadal czyta ten wątek i nie jest w stanie go uruchomić, przykro mi powiedzieć, że w ten sposób przechwycenie zdarzenia ruchu jest uważane za błąd i poprawkę w Androidzie> = 4.2.
Przechwycone zdarzenie ruchu, chociaż ma akcję ACTION_OUTSIDE, zwraca 0 w getX i getY. Oznacza to, że nie widzisz całej pozycji ruchu na ekranie, ani nie możesz nic zrobić. Wiem, że doktor powiedział, że dostanie xiy, ale prawda jest taka, że NIE. Wydaje się, że ma to na celu zablokowanie rejestratora kluczy.
Jeśli ktoś ma obejście tego problemu, zostaw swój komentarz.
ref: Dlaczego ACTION_OUTSIDE zwraca 0 za każdym razem na KitKat 4.4.2?
https://code.google.com/p/android/issues/detail?id=72746
źródło
korzystając z usługi możesz to osiągnąć:
źródło
Odpowiedź @ Sarwar Erfan już nie działa, ponieważ Android nie pozwala na dodawanie widoku za pomocą WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY do okna, aby można go było dotykać już nawet przy WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH.
Znalazłem rozwiązanie tego problemu. Możesz to sprawdzić w następującym pytaniu
Podczas dodawania widoku do okna za pomocą WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY nie pojawia się zdarzenie dotykowe
źródło
To stare pytanie, ale ostatnio Android obsługuje Bubbles. Wkrótce zostaną uruchomione bąbelki, ale obecnie programiści mogą zacząć z nich korzystać. Są one zaprojektowane jako alternatywa dla używania
SYSTEM_ALERT_WINDOW
. Aplikacje takie jak (Facebook Messenger i MusiXMatch używają tej samej koncepcji).Pęcherzyki są tworzone za pośrednictwem interfejsu API powiadomień, a powiadomienie wysyłane jest normalnie. Jeśli chcesz, aby bąbelkowała, musisz dołączyć do niej dodatkowe dane. Aby uzyskać więcej informacji o Bubbles, przejdź do oficjalnego Przewodnika programisty Androida na Bubbles .
źródło