Mam usługę, która uruchamia nakładkę systemową. Kiedy nakładka jest widoczna, chcę, aby była dotykalna/wykrywa dotyk, ale chcę zachować interakcję z ekranem za nią (z tyłu mam na myśli podstawowe działanie, na przykład obok nakładki).Dlaczego nakładka systemu przechwytuje wszystkie dotknięcia (nie jest możliwa interakcja z widokiem podstawowym)
Moja nakładka to bitmapa/PNG o wymiarach 128x128px. Zostaje narysowany, a kiedy go klikam, otrzymuję TOUCH! log, co jest dobre. Ale kiedy kliknę na inną część ekranu (oprócz nakładki) otrzymuję DOTYKĘ! log i brak interakcji z ekranem pod nim jest możliwe.
Oto części mojego kodu:
główny przedmiot, aby uruchomić usługę
buttonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// start Service and return to Homescreen
Intent i = new Intent(MainActivity.this, MyService.class);
startService(i);
Intent newActivity = new Intent(Intent.ACTION_MAIN);
newActivity.addCategory(Intent.CATEGORY_HOME);
newActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newActivity);
}
});
życzenie/Pokaż nakładki
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
myOverlay = new Overlay(MyService.this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(myOverlay, params);
myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
myOverlay.postInvalidate();
return super.onStartCommand(intent, flags, startId);
}
Overlay
public MyOverlay(Context context) {
super(context);
this.context = context;
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TOUCH!", event.getAction() + ", x:"+event.getX()+", y:"+event.getY());
return false;
}
});
}
Co robię źle? Wypróbowałem również WindowManager.LayoutParams.TYPE_PHONE zamiast WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, ale to samo zachowanie.
Nie używam flagi FLAG_WATCH_OUTSIDE_TOUCH, więc dlaczego akcenty nie są zarejestrowane obok nakładki?
EDIT
Wydaje Znalazłem problem, ale nadal nie wiem jak go rozwiązać chociaż ... Wyświetlany obraz w nakładce jest bardzo małe i nie ma problemu, ale (!) sama nakładka jest pełny ekran
dodałem następujący raport do nakładka/onTouch() imprezy:
Log.i("TOUCH!", "View: "+v.toString() +", size="+ v.getWidth()+"/"+v.getHeight());
które potem mówi mi Widok: package.overlay.myOverlay, size = 480/762
Teraz starałem się go zmusić, by nie być pełny ekran, dodając następujący wiersz w Serwisie:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
myOverlay = new Overlay(MyService.this);
//HERE
myOVerlay.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(myOverlay, params);
myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
myOverlay.postInvalidate();
return super.onStartCommand(intent, flags, startId);
}
Ale to nie pomaga ... nadal myOverlay ma rozmiar 480x762 ... Dlaczego jest tak duży i jak mogę go uzyskać, żeby miał rozmiar zawartego obrazu?
Jak duża jest twoja nakładka? Czy obejmuje on cały podstawowy układ? Czy to przejrzysta rzecz? – abbath
"ale chcę zachować interakcję z ekranem za nim" - na szczęście nie jest to już możliwe od Androida 4.0.3, aby zapobiec atakom typu "tapjacking", przynajmniej w przypadku dotknięć samej nakładki. Nakładka może odbierać zdarzenia dotykowe (i te nie są przesyłane dalej) lub nie otrzymywać zdarzeń dotyku (w rodzaju "Toast"). – CommonsWare
@abbath Jest to mapa bitowa o wymiarach 128x128 px narysowana na płótnie. Ma przezroczyste tło, tak, co oznacza, że powinienem sprawić, że będzie nieprzejrzysty, aby sprawdzić, czy to naprawdę tak małe ... wypróbuję to. –