編輯: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實現的)
android技巧:如何在android應用中插入百度廣告
1.介紹現在游戲中的廣告基本上已經成為了游戲創作者的一個重要的收入來源。其實插入廣告還是挺簡單的,本文選擇百度廣告聯盟作為案例(總覺得百度不會拖欠工資)。注:不過,插入廣
開發可統計單詞個數的Android驅動程序(中)
五、指定與驅動相關的信息雖然指定這些信息不是必須的,但一個完整的Linux驅動程序都會指定這些與驅動相關的信息。一般需要為Linux驅動程序指定如下信息。1. 模塊作者:
Android簡明開發教程二:安裝開發環境
前面Android簡明開發教程一:概述簡要的介紹了Android平台,本篇說明如何安裝搭建Android開發環境。Android開發支 持Windows (Windows
Android開發入門(十五)使用菜單 15.2 選項菜單
現在,我們就可以去修改上一節中的項目了。這樣,在用戶按menu鍵的時候就會彈出選項菜單了。1. 使用上一節中的工程,在MenusActivity.java中添加一些代碼。