Android键盘系统——改变按键功能(2)
来源:互联网 发布:jdk 7u1 windows 7.0 编辑:程序博客网 时间:2024/06/05 11:44
按键控制屏幕旋转功能
屏幕旋转功能在android源码中已经实现,即有专门的代码实现屏幕的旋转,这部分代码中的状态值是可以通过输入设备来改变的。如键盘、触摸屏等。
通过对android键盘系统分析我们知道,android系统把键盘的按键输入包装成了标准的事件输入。由于每一个按键都对应着相应的中断,而相应的中断对应着相应的中断处理。对于一个做好的产品,每一个按键的功能都是确定的,而且约定俗成的与android系统中键盘布局文件相一致。所以要实现按键来控制屏幕的旋转,可以采用复合按键。
在复合按键的处理代码中,我们只需增加一个分支,即新定义的复合键情况。如长按MENU
先看看android源码中屏幕旋转功能的相关代码。
*******************************************************************************
/framewords/policies/base/phone/android/internal/policy/impl中的PhoneWindowManager.java文件的PhoneWindowManaget类中就有对屏幕旋转进行处理的代码。
1、内部类SettingsObserver的重载方法onChange:
try {
mWindowManager.setRotation(USE_LAST_ROTATION, false,
mFancyRotationAnimation);
} catch (RemoteException e) {
}
2、内部类MyOrientationListener中的重载方法onOrientationChanged:
public void onOrientationChanged(int rotation) {
if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation);
try {
mWindowManager.setRotation(rotation, false,
mFancyRotationAnimation);
} catch (RemoteException e) {
}
}
3、方法readRotation:
private int readRotation(int resID) {
try {
int rotation = mContext.getResources().getInteger(resID);
switch (rotation) {
case 0:
return Surface.ROTATION_0;
case 90:
return Surface.ROTATION_90;
case 180:
return Surface.ROTATION_180;
case 270:
return Surface.ROTATION_270;
}
} catch (Resources.NotFoundException e) {
// fall through
}
return -1;
}
4、完成按键控制屏幕旋转最核心的代码在方法interceptKeyTi。在后面会对这部分代码进行分析。
public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down,
int repeatCount, int flags) {
if ((code == KeyEvent.KEYCODE_HOME) && !down) {
…………
…………
}
*******************************************************************************
/frameworks/base/services/java/com/android/server/WindowManagerServices.java中
1、方法:setRotation
public void setRotation(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"setRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
}
2、紧接着setRotation调用了方法setRotationUnchecked
public void setRotationUnchecked(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
long origId = Binder.clearCallingIdentity();
boolean changed;
synchronized(mWindowMap) {
changed = setRotationUncheckedLocked(rotation, animFlags);
}
if (changed) {
sendNewConfiguration();
synchronized(mWindowMap) {
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
} else if (alwaysSendConfiguration) {
//update configuration ignoring orientation change
sendNewConfiguration();
}
Binder.restoreCallingIdentity(origId);
}
3、在setRotationUnchecked中,对变量change赋值为了setRotationUncheckedLocked
public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
boolean changed;
if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
rotation = mRequestedRotation;
} else {
mRequestedRotation = rotation;
mLastRotationFlags = animFlags;
}
if (DEBUG_ORIENTATION) Log.v(TAG, "new rotation is set to " + rotation);
changed = mDisplayEnabled && mRotation != rotation;
Log.v(TAG, "====Qdroid====" + "mDisplayEnabled = " + mDisplayEnabled + " mRotation = " + mRotation + " changed = " + changed + " rotation = " + rotation);
if (changed) {
if (DEBUG_ORIENTATION) Log.v(TAG,
"Rotation changed to " + rotation
+ " from " + mRotation
+ " (forceApp=" + mForcedAppOrientation
+ ", req=" + mRequestedRotation + ")");
mRotation = rotation;
mWindowsFreezingScreen = true;
mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
2000);
startFreezingDisplayLocked();
Log.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
mQueue.setOrientation(rotation);
if (mDisplayEnabled) {
Surface.setOrientation(0, rotation, animFlags);
}
for (int i=mWindows.size()-1; i>=0; i--) {
WindowState w = (WindowState)mWindows.get(i);
if (w.mSurface != null) {
w.mOrientationChanging = true;
}
}
for (int i=mRotationWatchers.size()-1; i>=0; i--) {
try {
mRotationWatchers.get(i).onRotationChanged(rotation);
} catch (RemoteException e) {
}
}
} //end if changed
return changed;
}
1)、mQueue.setOrientation(rotation);这个函数完成了旋转后上下左右键功能的改变:
public void setOrientation(int orientation) {
synchronized(mFirst) {
mOrientation = orientation;
switch (orientation) {
case Surface.ROTATION_90:
mKeyRotationMap = KEY_90_MAP;
break;
case Surface.ROTATION_180:
mKeyRotationMap = KEY_180_MAP;
break;
case Surface.ROTATION_270:
mKeyRotationMap = KEY_270_MAP;
break;
default:
mKeyRotationMap = null;
break;
}
}
}
以case Surface.ROTATION_90:为例
static final int[] KEY_90_MAP = new int[] {
KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT,
KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_UP,
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_DOWN,
};
2)、Surface.setOrientation(0, rotation, animFlags);则完成了屏幕布局的旋转:
具体实现过程见/frameworks/base/libs/surfaceflinger/路径的SurfaceFlinger.cpp
int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation, uint32_t flags)
{
…………
- Android键盘系统——改变按键功能(2)
- 改变按键功能
- android 按键、键盘移植
- android 键盘按键监听
- android 键盘按键监听
- android imeAction 的使用(改变软件键盘回车键的功能与显示文字)
- 通过键盘按键改变 光标形状
- 通过键盘按键改变 光标形状
- android模拟器按键对应的键盘按键
- Android模拟器按键对应的键盘按键
- Symbian开发——模拟键盘按键
- android 模拟器键盘 按键对应
- android 模拟键盘按键事件
- Android Studio 对应键盘按键
- android编程2:menu按键功能实现
- android处理键盘事件之物理按键 (一)
- PC键盘和苹果键盘的按键功能对照
- 键盘(键盘基础,按键消息)
- 学习笔记——XSL简介及入门
- 接口功能扩展举例
- Objective-C学习纪录1
- 调用webservice 设置超时时间
- jQuery插件使用之 --- 滑块的应用(移动滑块使图片变化)
- Android键盘系统——改变按键功能(2)
- poj 1733
- xmlpull解释xml
- 函数的打桩和hook
- 实现异步调用web service,防止超时现象
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存
- Linux命令行技巧
- 开始学HTML5-第一天
- OpenCV二值化函数Threshold