Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> Android開發教程 >> android 4.3中一次完整的android源碼截屏事件的捕獲

android 4.3中一次完整的android源碼截屏事件的捕獲

編輯:Android開發教程

1.背景

我們知道android提供了一個系統截屏功能,就是按住電源鍵和音量減的按鍵0.5秒,系統將執行截屏功能。所以要實現系統截屏的功能,就是要捕獲系統的這兩個組合鍵下面的函數,然後一層一層的向下挖掘。現在網上找到的版本是在Surface.java文件下存在ScreenShot()函數,是@hide的。但是這是之前版本的辦法,在android4.3之後已經是不適用的,因為在/frameworks/base/core/java/android/view/的Surface.java下並沒有ScreenShot()函數,我猜google不會這麼絕情,一定會在framework層給開發者留了接口,只不過寫到了別的地方。所以博主按照前任的思路自行挖掘,最後找到了新版本的ScreenShot函數,在這與大家分享。

2.挖掘過程

(1)Android源碼中對按鍵的捕獲位於文件PhoneWindowManager.java(\frameworks\base\policy\src\com\android\internal\policy\impl)中

ase KeyEvent.KEYCODE_VOLUME_UP:  
            case KeyEvent.KEYCODE_VOLUME_MUTE: {  
                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {  
                    if (down) {  
                        if (isScreenOn && !mVolumeDownKeyTriggered  
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {  
                            mVolumeDownKeyTriggered = true;  
                            mVolumeDownKeyTime = event.getDownTime();  
                            mVolumeDownKeyConsumedByScreenshotChord = false;  
                            cancelPendingPowerKeyAction();  
                            interceptScreenshotChord();  
                        }  
                    } else {  
                        mVolumeDownKeyTriggered = false;  
                        cancelPendingScreenshotChordAction();  
                    }

我們看到了,如果同時按下電源鍵與音量減會啟動函數,

interceptScreenshotChord();  

我們來看下著個函數

private void interceptScreenshotChord() {  
        if (mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {  
            final long now = SystemClock.uptimeMillis();  
            if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS  
                    && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {  
                mVolumeDownKeyConsumedByScreenshotChord = true;  
                cancelPendingPowerKeyAction();  
      
                mHandler.postDelayed(mScreenshotChordLongPress,  
                        ViewConfiguration.getGlobalActionKeyTimeout());  
            }  
        }  
    }

我們看到handle中的這個函數,應該就是我們要執行的截屏功能

mScreenshotChordLongPress

我們進入這個函數

private final Runnable mScreenshotChordLongPress = new Runnable() {  
        public void run() {  
            takeScreenshot();  
        }  
    };

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/extra/

終於讓我們找到了takeScreenShot,不過別急,我們轉到這個函數

private void takeScreenshot() {  
        synchronized (mScreenshotLock) {  
            if (mScreenshotConnection != null) {  
                return;  
            }  
            ComponentName cn = new ComponentName("com.android.systemui",  
                    "com.android.systemui.screenshot.TakeScreenshotService");  
            Intent intent = new Intent();  
            intent.setComponent(cn);  
            ServiceConnection conn = new ServiceConnection() {  
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {  
                    synchronized (mScreenshotLock) {  
                        if (mScreenshotConnection != this) {  
                            return;  
                        }  
                        Messenger messenger = new Messenger(service);  
                        Message msg = Message.obtain(null, 1);  
                        final ServiceConnection myConn = this;  
                        Handler h = new Handler(mHandler.getLooper()) {  
                            @Override
                            public void handleMessage(Message msg) {  
                                synchronized (mScreenshotLock) {  
                                    if (mScreenshotConnection == myConn) {  
                                        mContext.unbindService(mScreenshotConnection);  
                                        mScreenshotConnection = null;  
                                        mHandler.removeCallbacks(mScreenshotTimeout);  
                                    }  
                                }  
                            }  
                        };  
                        msg.replyTo = new Messenger(h);  
                        msg.arg1 = msg.arg2 = 0;  
                        if (mStatusBar != null && mStatusBar.isVisibleLw())  
                            msg.arg1 = 1;  
                        if (mNavigationBar != null && mNavigationBar.isVisibleLw())  
                            msg.arg2 = 1;  
                        try {  
                            messenger.send(msg);  
                        } catch (RemoteException e) {  
                        }  
                    }  
                }  
                @Override
                public void onServiceDisconnected(ComponentName name) {}  
            };  
            if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {  
                mScreenshotConnection = conn;  
                mHandler.postDelayed(mScreenshotTimeout, 10000);  
            }  
        }  
    }

我們看到它啟動了一個截圖的service( "com.android.systemui.screenshot.TakeScreenshotService")。(這也印證了我一個猜想,android的一切功能都是handle通過sendmessage然後通過service實現的)

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved