2017-03-15 15 views
6

Tôi đã xem xét một số câu hỏi về stackoverflow để tìm hiểu làm thế nào tôi có thể nghe nút bấm trên một dịch vụ bằng cách sử dụng trình quản lý cửa sổ. Hầu hết các câu trả lời đều đề xuất rằng điều đó là không thể, tuy nhiên tôi có thể thấy rằng sứ giả xử lý nó rất tốt.Làm thế nào để phát hiện nút backbutton/home từ một dịch vụ như dịch vụ head chat messenger?

Messenger xử lý nút bấm trên dịch vụ trò chuyện đầu của nó như thế nào? (Hoặc tôi hoàn toàn sai và họ không phải là dịch vụ bằng cách sử dụng trình quản lý cửa sổ?)

Trả lời

3

Để đạt được những gì bạn cần, bạn cần mở rộng một số Nhóm View mà bạn sẽ sử dụng làm vùng chứa gốc cho chế độ xem của mình. Hãy bắt đầu với điều này:

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); 
    } 
} 

Về cơ bản, ghi đè dispatchKeyEvent là một mẹo cho chúng tôi ở đây. Sau đó, làm cho việc sử dụng của nó trong một số xml (Tôi đã gọi nó là 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> 

Tiếp theo, tạo một dịch vụ có thêm cái nhìn của chúng tôi để các Chương trình quản lý cửa sổ X (mặc dù tôi giả sử bạn biết làm thế nào để làm điều đó, tôi sẽ đăng nó anyway vì lợi ích của sự hoàn chỉnh):

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); 
    } 
} 

câu chuyện vì vậy, dài ngắn, BackButtonAwareLinearLayout cho thấy một giao diện người nghe, rằng dịch vụ của chúng tôi cần phải thực hiện và đăng ký chính nó vào Layout.

Cũng nên nhớ rằng địa chỉ này xử lý nút quay lại. Để xử lý nút trang chủ, bạn có thể xem https://stackoverflow.com/a/31340960https://stackoverflow.com/a/33580971 - về cơ bản câu trả lời của tôi là một phần tóm tắt từ hai liên kết đó + https://stackoverflow.com/a/15980900 nhưng có vài chỉnh sửa (ví dụ: bạn không thể đặt FLAG_NOT_FOCUSABLE trong WindowManager .LayoutParams).

Tất nhiên bạn cần bắt đầu dịch vụ của bạn ở đâu đó bằng cách gọi startService, khai báo dịch vụ này trong AndroidManifest.xml và thêm quyền SYSTEM_ALERT_WINDOW.

Các vấn đề liên quan