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

來源:互聯網
上載者:User

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.cnhttp://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實現的)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.