2015-07-20 28 views
8

Chciałbym narysować ikonę (wskaźnik myszy) na ekranie w stosunku do innych aplikacji z usługi. Zaimplementowałem funkcjonalność i mogę rysować na ekranie, poza paskiem nawigacji. Sprawdziłem tutaj: severalotherquestions i wypróbowałem TYPE_SYSTEM_OVERLAY, TYPE_TOAST, TYPE_SYSTEM_ERROR i kilka innych typów okien bez powodzenia.Rysowanie na pasku nawigacyjnym (i innych aplikacjach) w wersji Android> = 5

Nie próbuję przechwycić fokusa, po prostu rysując wskaźnik myszy na ekranie przez sekundę lub dwie. Kiedy próbuję narysować nad paskiem nawigacyjnym, to po prostu przechodzi pod (w rzeczywistości RelativeLayout kończy się na granicy z paskiem nawigacji - nawet gdy określam wymiar ręczny dla wysokości). Poniższy zrzut ekranu pokazuje wskaźnik dłoni w prawej dolnej części ekranu. To tak nisko, jak mogę to ustawić. Zauważ, że nie próbuję ukrywać paska nawigacji w mojej aplikacji - próbując narysować inne aplikacje.

overlay-pointer-on-screen

Próbowałem nawet ustawienie xpos i ypos przesunięcie ustawienia w WindowManager.LayoutParams przykład, ale to tylko równoważy układ i nadal spada poniżej paska nawigacyjnego).

params układ Używam aby pokazać okno:

 WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.MATCH_PARENT, 
       WindowManager.LayoutParams.MATCH_PARENT, 
       WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 
       WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 
       WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
       PixelFormat.TRANSPARENT); 

jestem następnie dodanie RelativeLayout z tych parametrów do managerem okien: windowManager.addView(relativeLayout, params);

+0

Czy zadeklarowałeś uprawnienie "narysuj na innych aplikacjach" na twoim pliku manifestu? –

+0

@ mr.icetea tak, oczywiście, inaczej nie byłbym w stanie narysować w ogóle. pasek stanu również, nie na pasku nawigacyjnym (na dole, gdzie są tylne, domowe i ostatnie klawisze programowalne) – miha

Odpowiedz

6

Po wielu manipulacjach udało mi się uzyskać odpowiednie flagi, które sprawiają, że działa. To prawie działa (dla większości aplikacji). Kod osiągnąć następująco (przykład na przycisk click obsługi):

@Override 
public void onClick(View view) { 
    if (_windowManager == null) { 
     _windowManager = (WindowManager) MainActivity.this.getSystemService(Context.WINDOW_SERVICE); 
    } 

    WindowManager.LayoutParams params; 
    // create the view on the first try 
    if (_overlayView == null) { 
     ImageView hand; 

     _overlayView = new FrameLayout(MainActivity.this); 
     hand = new ImageView(MainActivity.this); 
     hand.setImageResource(R.drawable.icon_hand_pointer); 
     int w = hand.getDrawable().getIntrinsicWidth(); 
     int h = hand.getDrawable().getIntrinsicHeight(); 
     _overlayView.addView(hand); 

     params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN | 
       WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 
       WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 
       WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, 
       PixelFormat.TRANSLUCENT); 

     params.width = w; 
     params.height = h; 
     params.gravity = Gravity.LEFT | Gravity.TOP; 
     params.x = _xOffset; 
     params.y = _yOffset; 
     _windowManager.addView(_overlayView, params); 
    } else { 
     // move the view 
     params = (WindowManager.LayoutParams) _overlayView.getLayoutParams(); 
     params.x = _xOffset; 
     params.y = _yOffset; 
     _windowManager.removeView(_overlayView); 
     _overlayView.setLayoutParams(params); 
     _windowManager.addView(_overlayView, params); 
    } 

    _xOffset += 40; 
    _yOffset += 100; 
} 

Oto zrzut ekranu z tym kodem pracy w aplikacji (widać nakładkę ręki, to jest na Nexusa 5 z Androidem 6.0.1 : enter image description here

+0

Zobacz także następujący [komentarz] (http: // stackoverflow.com/questions/21380167/draw-bitmaps-on-top-of-the-nawigacja-bar-in-android/21877720 # comment52626546_21877720) o tym, że nie zawsze można rysować na pasku nawigacyjnym. – miha

+0

Czy kiedykolwiek znalazłeś sposób, aby działał we wszystkich aplikacjach? Nie mogę się dostać do mojego paska nawigacyjnego w niektórych aplikacjach, takich jak tryb widoku profilu przeglądarki Chrome i Tinder! Po prostu rysuje się pod navbar. – Flyview

+0

@Flyview, nie, nie zrobiłem; Ostatecznie otrzymaliśmy to rozwiązanie. – miha

2

Pasek nawigacyjny na dole jest coś, nie można go przeciągnąć, ponieważ powyższe elementy mogą utrudnić dostęp do przycisku głównego, przycisku wstecz itd. Możesz jednak wykonywać całą czynność na pełnym ekranie, co oznacza, że ​​będzie ukrywać przyciski nawigacyjne, dopóki nie przesuniesz palcem od dołu, aby możesz narysować w dowolnym miejscu na ekranie:

EDYCJA: Znalazłem kilka podobnych pytań, a ten ma odpowiedź: Draw bitmaps on top of the Navigation bar in Android Odpowiedź była taka, aby dodać przesunięcie y, które jest wielkością paska nawigacyjnego.

+0

[Aplikacja TeamViewer QS] (https://play.google.com/store/apps/details?id=com. teamviewer.quicksupport.market) może to zrobić w. Chodzi o to, aby narysować inne aplikacje, nie tyle nad własną działalnością. – miha

+0

screenshot @miha? – tachyonflux

+0

@miha wygląda tak, jakby zrobił szybki zrzut ekranu, a następnie pozwala technikowi narysować ekran, a następnie pozwolić użytkownikowi przejąć kontrolę ponownie. – LonelyIdiot