【Android】聲控注入點擊事件實現系統級“喫雞”輔助

這裏我們從“喫雞”說起。

絕·地·求·生 遊戲的畫面效果超級強悍,像我這樣只玩摜蛋小遊戲的三不青年(不抽菸,不喝酒,不玩網遊)都被吸引到了

 

近年來掀起了一股“喫雞”熱潮,更衍生出了一種文化現象

(相關cosplay)

 

其手遊版本也是相當火爆,直播平臺上的觀看人數都超級多,當然,不確定這裏的數據是否有水分

 

 

一些周邊產品也被帶得風生水起

當然,也包括一些黑產,如外·掛,

(有些外·掛還是很有想象力的)

 

但是外·掛是“暴富寶典” ---- 《刑法》中掛了號的

(破壞計算機信息系統罪)

第二百八十六條 違反國家規定,對計算機信息系統功能進行刪除、修改、增加、干擾,造成計算機信息系統不能正常運行,後果嚴重的,處五年以下有期徒刑或者拘役;後果特別嚴重的,處五年以上有期徒刑。

違反國家規定,對計算機信息系統中存儲、處理或者傳輸的數據和應用程序進行刪除、修改、增加的操作,後果嚴重的,依照前款的規定處罰。

故意製作、傳播計算機病毒等破壞性程序,影響計算機系統正常運行,後果嚴重的,依照第一款的規定處罰。

作爲有道德與社會責任感的我們,自然是不能去製作外·掛程序。

 

同時,一些物理輔助工具也火了起來,可以用來協助使用者進行多指操作,就像觸控筆一樣,方便了手指的觸控操作,就加快了在遊戲中的反應速度,關鍵時刻剛得過

(主要操作有 水平移動,視線旋轉,射擊,跳躍等,所以多指操作相對於2個拇指的操作要有優勢)

作爲Android Developer 我們完全可以在系統中通過注入點擊事件來實現類似的功能。

聲控設計

大吼一聲,射擊鍵就被點擊起來,2個拇指進行其他的操作,這就實現了3指操作的效果。

主要步驟:

1.使用 AudioRecord實時獲取外部聲音的音量大小,達到設定的閾值時觸發點擊

                public RecordThread() { 

                super(); 

                bs = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, 

                        AudioFormat.CHANNEL_CONFIGURATION_MONO, 

                        AudioFormat.ENCODING_PCM_16BIT); 

                ar = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ, 

                        AudioFormat.CHANNEL_CONFIGURATION_MONO, 

                        AudioFormat.ENCODING_PCM_16BIT, bs); 

            } 

          

            public void run() { 

                super.run(); 

                Log.d("getVoice", "run");

                ar.startRecording(); 

                        // ..... buffer 

                byte[] buffer = new byte[bs]; 

                isRun = true; 

                Log.d("getVoice", "buffer len=" + buffer.length);

                while (isRun) { 

                    int r = ar.read(buffer, 0, bs); 

                    int v = 0; 

                                // . buffer ............ 

                    for (int i = 0; i < buffer.length; i++) { 

                        // ...................... 

                        v += buffer[i] * buffer[i]; 

                    } 

                    // ................. sendMessage ...... Handler ......  

                    float soundLevel = v / (float) r;

                

 if (soundLevel > 3300){

                            sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);

                        }

                } 

                ar.stop(); 

            } 

            public void pause() { 

                        // ....... Activity . onPause ...... Activity ........ 

                isRun = false; 

            } 

            public void start() { 

                        // ....... Activity . onResume ...... Activity .............. 

                if (!isRun) { 

                    super.start(); 

                } 

            } 

        }

2.模擬點擊

//向inputManager發送一個touch事件,點擊x=220, y=330的座標3000ms

sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);

這裏修改於 frameworks/base/cmds/input/src/com/android/commands/input/Input.java 裏的處理

實現如下:

    private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {

        final float DEFAULT_SIZE = 1.0f;

        final int DEFAULT_META_STATE = 0;

        final float DEFAULT_PRECISION_X = 1.0f;

        final float DEFAULT_PRECISION_Y = 1.0f;

        final int DEFAULT_EDGE_FLAGS = 0;

        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,

                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,

                getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);

        event.setSource(inputSource);

        Log.i(TAG, "injectMotionEvent: " + event);

        InputManager.getInstance().injectInputEvent(event,

                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);

    }

 

    private int getInputDeviceId(int inputSource) {

        final int DEFAULT_DEVICE_ID = 0;

        int[] devIds = InputDevice.getDeviceIds();

        for (int devId : devIds) {

            InputDevice inputDev = InputDevice.getDevice(devId);

            if (inputDev.supportsSource(inputSource)) {

                return devId;

            }

        }

        return DEFAULT_DEVICE_ID;

    }

 

    private void sendLongPress(int inputSource, float x, float y, int duration) {

        if (duration < 0) {

            duration = 300;

        }

        long now = SystemClock.uptimeMillis();

        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x, y, 1.0f);

        long startTime = now;

        long endTime = startTime + duration;

        while (now < endTime) {

//            injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, x, y, 1.0f);

            now = SystemClock.uptimeMillis();

        }

        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x, y, 0.0f);

    }


 

代言人

這樣,戴上耳機,沉浸其中,大吼一聲,多有氣勢

 

(這個試驗場景是找了一個人機,瞄準好,咳嗽了一聲,左邊的射擊鍵被點擊)

好了,就到這裏,有什麼想法可以留言和我一起討論。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章