2017-03-15 1 views
6

J'ai regardé à travers plusieurs question de stackoverflow pour découvrir comment je peux écouter le bouton de backpress sur un service utilisant le gestionnaire de fenêtres. La plupart des réponses proposent que ce n'est pas possible, mais je peux voir que messenger gère très bien.Comment détecter backbutton/home press à partir d'un service comme le service de tête de chat messenger?

Comment le messager gère-t-il le bouton de backpress sur son service de chat principal? (Ou je suis complètement faux et ils ne sont pas un service utilisant le gestionnaire de fenêtres?)

Répondre

3

Pour réaliser ce dont vous avez besoin, vous devez étendre ViewGroup que vous allez utiliser comme conteneur racine pour vos vues. Commençons par ceci:

public class BackButtonAwareLinearLayout extends LinearLayout { 

    public interface BackButtonListener { 
     void onBackButtonPressed(); 
    } 

    @Nullable 
    private BackButtonListener mListener; 

    public BackButtonAwareLinearLayout(Context context) { 
     super(context); 
    } 

    public BackButtonAwareLinearLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public BackButtonAwareLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    public void setBackButtonListener(@Nullable BackButtonListener listener) { 
     mListener = listener; 
    } 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent event) { 
     if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK 
       && mListener != null) { 
      mListener.onBackButtonPressed(); 
      return true; 
     } 
     return super.dispatchKeyEvent(event); 
    } 
} 

Fondamentalement, outrepasser dispatchKeyEvent est ce qui fait un truc pour nous ici. ensuite faire un usage en XML (je l'ai appelé chat_head_container.xml):

<?xml version="1.0" encoding="utf-8"?> 
<com.pablo432.myapplication.BackButtonAwareLinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:textSize="48sp" 
     android:text="Hello, world!" 
     android:textColor="#000" 
     android:background="#f5f5f5" 
     android:gravity="center"/> 

</com.pablo432.myapplication.BackButtonAwareLinearLayout> 

Ensuite, créer un service qui ajoute notre point de vue à l'WindowManager (bien que je suppose que vous savez comment le faire, Je vais le poster de toute façon pour être complet):

public class ChatHeadService extends Service 
     implements BackButtonAwareLinearLayout.BackButtonListener { 

    private WindowManager mWindowManager; 
    private BackButtonAwareLinearLayout mRootContainer; 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 
     LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     mRootContainer = (BackButtonAwareLinearLayout) inflater.inflate(
       R.layout.chat_head_container, null, false); 
     mRootContainer.setBackButtonListener(this); 

     WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.MATCH_PARENT, 
       WindowManager.LayoutParams.MATCH_PARENT, 
       WindowManager.LayoutParams.TYPE_PHONE, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       PixelFormat.TRANSPARENT); 

     mWindowManager.addView(mRootContainer, layoutParams); 
    } 

    @Override 
    public void onBackButtonPressed() { 
     mRootContainer.setBackButtonListener(null); 
     mWindowManager.removeView(mRootContainer); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (mRootContainer != null) mWindowManager.removeView(mRootContainer); 
    } 
} 

Tant histoire courte, BackButtonAwareLinearLayout expose une interface d'écoute, que notre service a besoin de mettre en œuvre et se souscrire à la mise en page.

Sachez également que cette adresse gère le bouton de retour. Pour gérer le bouton d'accueil, vous pouvez jeter un oeil à https://stackoverflow.com/a/31340960 et https://stackoverflow.com/a/33580971 - essentiellement ma réponse est un peu un résumé de ces deux liens + https://stackoverflow.com/a/15980900 mais contient quelques réglages (comme, par exemple, vous ne pouvez pas définir FLAG_NOT_FOCUSABLE dans WindowManager .LayoutParams).

Bien sûr, vous devez démarrer votre service quelque part en appelant startService, déclarer ce service dans AndroidManifest.xml et ajouter une autorisation SYSTEM_ALERT_WINDOW.