1. 程式人生 > >Android在Service中全域性監聽輸入法的三種可實現方式

Android在Service中全域性監聽輸入法的三種可實現方式

在Service中全域性監聽輸入法意思就是可以在任何介面都可以監聽輸入法,不侷限於自己的APP。

方法一:根據切換輸入法會在通知欄顯示通知實現

  • 優點:簡單高效
  • 缺點:手機必須安裝兩個以上輸入法

通常語言為中文的情況下切換輸入法的通知欄標題有”選擇輸入法”,”更改鍵盤”,”選擇鍵盤”,”更改輸入法”這四種,在NotificationListenerService
onNotificationPosted(StatusBarNotification sbn)
onNotificationRemoved(StatusBarNotification sbn)
兩個方法中分別檢測該四個關鍵字就可以實現開啟關閉輸入法的監聽。

        public static List<String> sKeyboardTitleList = new ArrayList<>(Arrays.asList(new String[] {
        "選擇輸入法","更改鍵盤","選擇鍵盤","更改輸入法"}));

    public void onNotificationPosted(StatusBarNotification sbn) {

     String title = sbn.getNotification().extras.getString("android.title");

        if (title == null) return;

        if(sKeyboardTitleList.contains(title)){

           //輸入法開啟
        }
     }

public void onNotificationRemoved(StatusBarNotification sbn) {

     String title = sbn.getNotification().extras.getString("android.title");

        if (title == null) return;

        if(sKeyboardTitleList.contains(title)){

           //輸入法關閉
        }
     }

方法二:使用輔助功能AccessibilityService檢測編輯框的狀態

  • 優點:不需要安裝多個輸入法,通用性強
  • 缺點:對關閉輸入法的檢測不穩定

    public void onAccessibilityEvent(final AccessibilityEvent accessibilityEvent) {
    
        isClickEditable = false;
        isClickEditable = false;
    
        if(accessibilityEvent.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
    
        if(accessibilityEvent.getSource() != null){
    
            isClickEditable = accessibilityEvent.getSource().isEditable();
    
        }
    
    }else if (accessibilityEvent.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED){
    
    
        if(accessibilityEvent.getSource() != null){
    
           isFocusedEditable = accessibilityEvent.getSource().isEditable();
    
        }
    
    }
    
    if(isClickEditable || isFocusedEditable){
    
        //輸入法已開啟
    
    }else {
    
        //輸入法已關閉
    }
    
    } 
    

方法三:使用Xposed框架獲取系統開啟關閉輸入法訊息

  • 優點:穩定高效
  • 缺點:需要安裝Xposed框架

在InputMethodManagerService的handleMessage(Message msg)方法會處理軟鍵盤的彈出可關閉。

      private static XC_MethodHook sInputMethodManagerServiceInitHook = new XC_MethodHook() {

    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {


        Message message = (Message) param.args[0];

        if (message.what == MSG_SHOW_SOFT_INPUT) {

            //輸入法開啟

        }else if (message.what == MSG_HIDE_SOFT_INPUT){

          //輸入法關閉

        }

        }

        };