2012-11-29 10 views
37

Sto utilizzando il noto metodo TYPE_SYSTEM_OVERLAY per creare una sovrapposizione a schermo intero che è sempre in primo piano rispetto ad altre viste.Rileva visibilità barra di stato/TYPE_SYSTEM_OVERLAY non ridimensionamento automatico

Su Moto Atrix2 API15 e per ogni AVD da API 10 attraverso 17 vista sovrapposizione ridimensiona automaticamente (espande verticalmente) quando la barra di stato è nascosta da un'altra applicazione. L'overlay sembra "stare in cima" a tutte le altre visualizzazioni, come penso che dovrebbe. Quando la barra di stato è di nuovo visualizzata, l'overlay riduce automaticamente le sue dimensioni (meno pixel verticali, sottraendo sostanzialmente l'altezza della barra di stato).

Questo è il comportamento desiderato e sono propenso a pensare che questo non è l'eccezione o il comportamento difettoso a causa di essa a lavorare su molti emulatori differenti così come almeno un produttore del dispositivo (Motorola), forse più, ma io don 't hanno accesso a addtl devices.

il problema: su una Samsung GS2 (API15) & testato anche sul Kindle Fire (API10?), la sovrapposizione non ridimensiona automaticamente (riempire lo spazio in cui la barra di stato era una volta) quando la barra di stato è nascosta da un'altra applicazione (barra di stato dietro l'app a schermo intero). Su questi dispositivi, dopo che la vista è stata creata la prima volta non ottengo altri eventi da una sovrascrittura onSizeChanged per la vista.

Ecco il codice pertinente:

params = new WindowManager.LayoutParams( 
    1, WindowManager.LayoutParams.MATCH_PARENT, 
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
    |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
    PixelFormat.TRANSPARENT); 
wm.addView(sizeLayout, params); 

sizeLayout ha l'override onSizeChanged.

Ho suonato in giro con quasi ogni windowmanagerlayoutparam Posso trovare, incluso SYSTEM_ALERT, FLAG_LAYOUT_IN_SCREEN, ecc. Non dormirò fino a quando non riesco a capirlo!

Edit 11/30/12: Ho trovato questo da @deviant: https://stackoverflow.com/a/9195733/1851478 che è fondamentalmente quello che sto facendo, ma il problema rimane con alcuni dispositivi non ridimensionando automaticamente lo system_overlay. Forse dovrei sollevare un bug.

Ulteriori informazioni: SE forzare un ridisegno (o anche solo caricare l'app overlay) mentre è presente un'app a schermo intero nella parte superiore dell'albero della vista, la mia sovrapposizione continua a non disegnare nello spazio utilizzato normalmente dalla barra di stato up (anche se la barra di stato non è visibile al momento del sorteggio), quindi sembra che l'overlay non sia "sovrapposto" in cima alla finestra in primo piano che è a schermo intero (e ho creato e testato molti app a schermo intero che utilizzano una varietà di metodi per farli andare a schermo intero). Su questi dispositivi, l'unico modo per ottenere l'overlay per disegnare sulla barra di stato (anche se la barra di stato non è visibile) è usare la bandiera FLAG_LAYOUT_IN_SCREEN, ma la dimensione del layout non cambia mai, è sempre a schermo intero, e quindi di nuovo al problema originale perché funziona su alcuni dispositivi ma non su altri.

Modifica 12/12/12: Quindi non ho avuto ulteriori fortuna su questo, e ho fatto provare a utilizzare getLocalVisibleRect sulle viste, ma purtroppo da quando la mia app non possiede lo SystemUI lo vede posso rileviamo cosa c'è sotto le sovrapposizioni. Suppongo che con una ROM personalizzata potrei farlo, ma ho bisogno di una soluzione senza root.

Vedo che altre app sul mercato hanno lo stesso problema nel rilevare la barra di stato sui telefoni non funzionanti che ho elencato sopra. Esempio: cool tool, omega statusbar barra di stato & +. Bounty sollevata.

Modifica 12/19/12 Immagini aggiunte. Nota che su un dispositivo funzionante l'area grigia "copre" anche l'area nera (qualsiasi app che è attualmente a schermo intero), l'area nera copre effettivamente l'intero schermo, sto solo mostrando l'area grigia come il mio overlay anche se è anche schermo intero (meno o più l'altezza della barra di stato a seconda del dispositivo funzionante/non funzionante e se è visibile o meno).

enter image description hereenter image description here

+0

puoi aggiungere screenshot del comportamento necessario e cosa ottieni? –

+0

@Anis foto aggiunte. – logray

+0

hai provato a girare a schermo intero? prima di aggiungere la tua vista prova: // vai a schermo intero WindowManager.LayoutParams attrs = mActivity.getWindow(). getAttributes(); attrs.flags | = WindowManager.LayoutParams.FLAG_FULLSCREEN; mActivity.getWindow(). SetAttributes (attrs); –

risposta

1

Penso che questo possa essere lo stesso problema con nascondere la barra del titolo sulle finestre di dialogo in cui il sistema imposta la visibilità di nascosto invece di andata. Questo fa sì che la finestra di dialogo venga centrata in modo errato.

Per questo, ecco come ho risolto il problema. Questo potrebbe funzionare per la tua situazione ma potrebbe essere necessario regolarlo per il nome dell'identificatore della barra di stato.

Window window = dialog.getWindow(); 
View view = window.getDecorView(); 
int topPanelId = getResources().getIdentifier("topPanel", "id", "android"); 
LinearLayout topPanel = (LinearLayout) view.findViewById(topPanelId); 
topPanel.setVisibility(View.GONE); 
+0

Sono abbastanza sicuro che questo richiederà root (e forse un SystemUI.apk personalizzato), e ho bisogno di una soluzione senza uno di questi. Secondariamente non sono interessato a nascondere la barra di stato, solo rilevando se è visibile o meno. Ne giocherò un po ', ma non sono fiducioso. – logray

+0

Non ho avuto successo nell'impostare la visibilità di una vista che la mia app non possiede ... grazie per aver provato. – logray

3

Spero di capire quello che stai dopo qui, ma, nella mia app (TEAM BatteryBar) ho avuto un problema simile. (senza permessi minimi di root)

Non sono riuscito a rilevare un intero schermo su qualcosa sotto API11 (e intermittente su alcuni dispositivi (soprattutto Samsung) sopra API11). Quindi ho creato un listener personalizzato aggiungendo un secondo layout al WindowManager con un parametro di layout diverso, quindi sovrascrivendo onLayout per verificare se lo statusBar è ancora presente controllando la dimensione della finestra. da lì puoi fare tutto ciò che è necessario per la tua vista principale.

Stavo andando a riordinare, ma ha funzionato così non l'ho fatto: il codice P ha più di un anno e viene da quando ho iniziato a scrivere codice per Android, quindi sì. Cibo per il pensiero tho. spero che sia d'aiuto.

here is the code in a repo at my github con una copia incolla direttamente dalla mia app su come sto usando. small snippet here

wm.addView(sizeLayout, params);// add your view 

// then add the next one 
Screendetect mDetector; 
mDetector = new Screendetect(this); 
mDetector.setOnFullScreenListener(new OnFullScreenListener() { 
      @Override 
      public void fsChanged(boolean FS_Bool) { 
       // TODO rethink this to be better.... bit hacky... 
       if (FS_Bool) { 
        Log.d("battbardetect", "Statusbar hidden"); 
        FS_vissible(); // do what ever you need to 
       } else if (!FS_Bool) { 
        Log.d("battbardetect", "Statusbar Vissible"); 
        FS_hidden(); // do what ever you need to 
       } 
      } 
     }); 
wm.addView(mDetector, params); 
+0

Proverò OnFullScreenListener, ma fondamentalmente la tua risposta è solo riformulando/facendo la stessa cosa che ho già provato, e ciò che ho documentato non funziona su tutti i dispositivi. Funziona su alcuni, ma non su altri (apparentemente senza spiegazione). Sui dispositivi non funzionanti, il metodo (e il mio/i devianti) non sembrano rilevare automaticamente il ridimensionamento dell'overlay, che si tratti di utilizzare OnFullScreenListener, OnGlobalLayoutListener o di sovrascrivere onSizeChanged nel layout dell'overlay. – logray

+0

Ho guardato il tuo codice e hai appena scavalcato suLayout, cosa che ho già provato senza successo sui dispositivi non funzionanti.Nel mio esempio/domanda sovrascrivo onSizeChanged e ho provato a sovrascrivere praticamente ogni metodo di visualizzazione che potevo all'interno di un layout overlay gonfiato (praticamente lo stesso di quello che hai fatto tu). – logray

+1

Ok grazie per aver provato. Ho provato il tuo codice, praticamente parola per parola e lo stesso problema, onLayout viene chiamato una sola volta quando la vista viene prima aggiunta (o sulla modifica della configurazione), e non ancora finché il servizio (o la vista) non viene distrutto/rimosso e creato/aggiunto ancora. E anche se aggiungo e rimuovo ripetutamente la vista, la dimensione verticale non cambia mai a meno che non aggiungo il layout nella bandiera dello schermo. Quindi fondamentalmente gli stessi problemi, almeno come testati su un Samsung GS2 API15. BTW onSystemUiVisibilityChange non funziona neanche. Non ottengo alcun evento da questo: il dispositivo GS2 è ICS ​​con chiavi di navigazione fisiche. – logray

Problemi correlati