您的位置:首页 > 移动开发 > Android开发

Android中通过按键旋转屏幕

2011-12-28 12:57 323 查看
/article/1879269.html

Android上的home键是系统直接处理的,功能如下:

1:跳转到Home界面,如果Home进程死掉了,则重新启动Home进程

2:长按5s,弹出选择应用的窗口,可以切换应用.

由于需要,我需要修改这里的部分逻辑,修改后的逻辑不能放出,这里放出我找到的大概地点

view plaincopy to clipboardprint?

public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down,

int repeatCount, int flags) {

boolean keyguardOn = keyguardOn();

if (false) {

Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount="

+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);

}

// Clear a pending HOME longpress if the user releases Home

// TODO: This could probably be inside the next bit of logic, but that code

// turned out to be a bit fragile so I'm doing it here explicitly, for now.

if ((code == KeyEvent.KEYCODE_HOME) && !down) {

mHandler.removeCallbacks(mHomeLongPress);

}

// If the HOME button is currently being held, then we do special

// chording with it.

if (mHomePressed) {

// If we have released the home key, and didn't do anything else

// while it was pressed, then it is time to go home!

if (code == KeyEvent.KEYCODE_HOME) {

if (!down) {

mHomePressed = false;

if ((flags&KeyEvent.FLAG_CANCELED) == 0) {

// If an incoming call is ringing, HOME is totally disabled.

// (The user is already on the InCallScreen at this point,

// and his ONLY options are to answer or reject the call.)

boolean incomingRinging = false;

try {

ITelephony phoneServ = getPhoneInterface();

if (phoneServ != null) {

incomingRinging = phoneServ.isRinging();

} else {

Log.w(TAG, "Unable to find ITelephony interface");

}

} catch (RemoteException ex) {

Log.w(TAG, "RemoteException from getPhoneInterface()", ex);

}

if (incomingRinging) {

Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");

} else {

launchHomeFromHotKey();

}

} else {

Log.i(TAG, "Ignoring HOME; event canceled.");

}

}

}

return true;

}

// First we always handle the home key here, so applications

// can never break it, although if keyguard is on, we do let

// it handle it, because that gives us the correct 5 second

// timeout.

if (code == KeyEvent.KEYCODE_HOME) {

// If a system window has focus, then it doesn't make sense

// right now to interact with applications.

WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;

if (attrs != null) {

final int type = attrs.type;

if (type == WindowManager.LayoutParams.TYPE_KEYGUARD

|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {

// the "app" is keyguard, so give it the key

return false;

}

final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;

for (int i=0; i<typeCount; i++) {

if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {

// don't do anything, but also don't pass it to the app

return true;

}

}

}

if (down && repeatCount == 0) {

if (!keyguardOn) {

mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout());

}

mHomePressed = true;

}

return true;

}

public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down,

int repeatCount, int flags) {

boolean keyguardOn = keyguardOn();

if (false) {

Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount="

+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);

}

// Clear a pending HOME longpress if the user releases Home

// TODO: This could probably be inside the next bit of logic, but that code

// turned out to be a bit fragile so I'm doing it here explicitly, for now.

if ((code == KeyEvent.KEYCODE_HOME) && !down) {

mHandler.removeCallbacks(mHomeLongPress);

}

// If the HOME button is currently being held, then we do special

// chording with it.

if (mHomePressed) {

// If we have released the home key, and didn't do anything else

// while it was pressed, then it is time to go home!

if (code == KeyEvent.KEYCODE_HOME) {

if (!down) {

mHomePressed = false;

if ((flags&KeyEvent.FLAG_CANCELED) == 0) {

// If an incoming call is ringing, HOME is totally disabled.

// (The user is already on the InCallScreen at this point,

// and his ONLY options are to answer or reject the call.)

boolean incomingRinging = false;

try {

ITelephony phoneServ = getPhoneInterface();

if (phoneServ != null) {

incomingRinging = phoneServ.isRinging();

} else {

Log.w(TAG, "Unable to find ITelephony interface");

}

} catch (RemoteException ex) {

Log.w(TAG, "RemoteException from getPhoneInterface()", ex);

}

if (incomingRinging) {

Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");

} else {

launchHomeFromHotKey();

}

} else {

Log.i(TAG, "Ignoring HOME; event canceled.");

}

}

}

return true;

}

// First we always handle the home key here, so applications

// can never break it, although if keyguard is on, we do let

// it handle it, because that gives us the correct 5 second

// timeout.

if (code == KeyEvent.KEYCODE_HOME) {

// If a system window has focus, then it doesn't make sense

// right now to interact with applications.

WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;

if (attrs != null) {

final int type = attrs.type;

if (type == WindowManager.LayoutParams.TYPE_KEYGUARD

|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {

// the "app" is keyguard, so give it the key

return false;

}

final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;

for (int i=0; i<typeCount; i++) {

if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {

// don't do anything, but also don't pass it to the app

return true;

}

}

}

if (down && repeatCount == 0) {

if (!keyguardOn) {

mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout());

}

mHomePressed = true;

}

return true;

}

这里贴出一些代码,是在 frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.Java 文包括件里的,主要是处理特殊按键的,里面涵盖来android中的特殊按键,还包括Search和其他特殊键

对于Home键的逻辑,大致的分析是:

1 : 如果用户按下Home键,则开始一个计时器,具体是里面的mHomeLongPress对象,如果超过5s,则弹出一个切换app的窗口

2 : 用户松开Home键,则视为单机时间,现把系统中的一些浮动的模态窗口关闭,具体的代码是 :

sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);

3: 关闭模态窗口后,启动或者切换Home应用,代码:

startDockOrHome

我自己添加的代码这里不能放出,有这样的需求可以在这里手动加入.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: