KeyEventシステムイベントシミュレーション(Homeキー、Backキーなど)

10061 ワード

質問の紹介
前言:Remote Controllerの携帯電話はBluetoothでハンドルを接続し、ハンドルから送信された各種データメッセージを受け取り、最終的にandroid標準のシステムイベント、すなわちKeyEventイベントをシミュレートする.
簡単な実装コードは次のとおりです.
public static void simulateKeyEvent(final int KeyCode) {
    new Thread(new Runnable() {
        public void run() {
            //        
            try {
                Instrumentation inst=new Instrumentation();
                inst.sendKeyDownUpSync(KeyCode);
            } catch (Exception e) {
                //   catch
            }
        }
    }).start();
}

注意:keyCodeはKeyEventを表示します.JAvaにおける各種システムイベントシステムイベントの詳細
上記の簡単な方法は、サービスとしてオープンしており、単一のプロセスや単一のアプリケーションで使用するのは問題ありませんが、Homeキーまたは他の方法で現在のアプリケーションを終了すると、サービスはまだありますが、上記の方法では実行できません:Injecting to anotherアプリケーションrequires INJECT_EVENTS permission、ヒントは権限がありませんが、AndroidManifest.xmlに権限を追加しても、問題は解決できません.
解決策
この問題を解決する鍵は,現在のアプリケーションのidがシステムレベルになることであり,システム権限を取得することと理解でき,解決方法はこの点をめぐって展開される.
  • アプリケーションのAndroidManifest.xmlのmanifestノードにandroid:sharedUserId="androidを加える.uid.システム」という属性.
  • Androidを修正します.mkファイル、LOCAL_に追加CERTIFICATE:=platform行
  • ソースコードの下でmmコマンドを使用してコンパイルし、生成したapkにはシステムの権限があります.

  • 具体的なコード実装(本質的な違いはなく、詳細のみ)
    package com.bingka.demo1;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.Handler;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.app.Instrumentation;
    
    public class myService extends Service {
    
        private static final String TAG = "[bingka]";
        private static final int TIME = 5*1000;
    
        public static final int SYSTEM_EVENT_BACK_ID = 0;
        public static final int SYSTEM_EVENT_ENTER_ID = 1;
        public static final int SYSTEM_EVENT_UP_ID = 2;
        public static final int SYSTEM_EVENT_DOWN_ID = 3;
        public static final int SYSTEM_EVENT_LEFT_ID = 4;
        public static final int SYSTEM_EVENT_RIGHT_ID = 5;
    
        Handler handler = new Handler(); 
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.d(TAG,"onBind...");
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            handler.postDelayed(runnable, TIME);
            Log.d(TAG,"onStartCommand...");
            return super.onStartCommand(intent, flags, startId);
        }
    
        //timer
        Runnable runnable = new Runnable() {  
            @Override  
            public void run() {  
                // handler to implement the timer 
                try {  
                    handler.postDelayed(this, TIME);
                    sendSelfEvent(SYSTEM_EVENT_UP_ID);
                    android.util.Log.d(TAG,"KeyEvent done..."); 
                } catch (Exception e) {   
                    e.printStackTrace();  
                    android.util.Log.d(TAG,"KeyEvent exception..."); 
                }
            }  
        };
    
    
        /*simulation key event of system
            KeyEvent: 1.KEYCODE_BACK
                      2.KEYCODE_ENTER || KEYCODE_DPAD_CENTER
                      3.KEYCODE_DPAD_UP,KEYCODE_DPAD_DOWN,
                        KEYCODE_DPAD_LEFT,KEYCODE_DPAD_RIGHT                          
        */
        private synchronized void sendSelfEvent(final int systemEventId){
            Thread th = new Thread(){
                //can not run in UI thread
                public void run() {
                    Instrumentation inst = new Instrumentation();
                    String logInfo = "";
                    try {
                        switch (systemEventId){
                            case SYSTEM_EVENT_BACK_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
                                logInfo = "KeyEvent.KEYCODE_BACK";
                                break;
                            case SYSTEM_EVENT_ENTER_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
                                logInfo = "KeyEvent.KEYCODE_ENTER";
                                break;
                            case SYSTEM_EVENT_UP_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
                                logInfo = "KeyEvent.KEYCODE_DPAD_UP";
                                break;
                            case SYSTEM_EVENT_DOWN_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
                                logInfo = "KeyEvent.KEYCODE_DPAD_DOWN";
                                break;
                            case SYSTEM_EVENT_LEFT_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_LEFT);
                                logInfo = "KeyEvent.KEYCODE_DPAD_LEFT";
                                break;
                            case SYSTEM_EVENT_RIGHT_ID:
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_RIGHT);
                                logInfo = "KeyEvent.KEYCODE_DPAD_RIGHT";
                                break;
                            default:
                                logInfo = "This behavior does not match system event ! ";
                                break;
                        }
                        android.util.Log.d(TAG, logInfo);
                    } catch (Exception e) {
                        android.util.Log.d(TAG," Instrumentation Exception = "+e);
                    }
                };
            };
            th.start();
        }
    }

    注意:上記のコードは戻りキー、確認キー、上、下、左、右キーのシステムイベントシミュレーションを実現し、他のイベントは自分で拡張することができます.