想在Android上做一个透明视图,可在整个屏幕上任意涂鸦(包括状态导航栏),但是不想影响下层窗口的操作,偶然发现developer Option中的Pointer Location接近我的需求。于是顺便研究了一下:
PointerLocationView
PhoneWindowManager.java
public void updateSettings() {
ContentResolver resolver = mContext.getContentResolver();
boolean updateRotation = false;
View addView = null;
View removeView = null;
.................................
if (mSystemReady) {
int pointerLocation = Settings.System.getInt(resolver,
Settings.System.POINTER_LOCATION, 0);
if (mPointerLocationMode != pointerLocation) {
mPointerLocationMode = pointerLocation;
if (pointerLocation != 0) {
if (mPointerLocationView == null) {
mPointerLocationView = new PointerLocationView(mContext);
mPointerLocationView.setPrintCoords(false);
addView = mPointerLocationView;
}
} else {
removeView = mPointerLocationView;
mPointerLocationView = null;
}
}
}
.................................................
if (addView != null) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle("PointerLocation");
WindowManager wm = (WindowManager)
mContext.getSystemService(Context.WINDOW_SERVICE);
lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
wm.addView(addView, lp);
if (mPointerLocationInputChannel == null) {
try {
mPointerLocationInputChannel =
mWindowManager.monitorInput("PointerLocationView");
InputQueue.registerInputChannel(mPointerLocationInputChannel,
mPointerLocationInputHandler, mHandler.getLooper().getQueue());
} catch (RemoteException ex) {
Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
ex);
}
}
}
if (removeView != null) {
if (mPointerLocationInputChannel != null) {
InputQueue.unregisterInputChannel(mPointerLocationInputChannel);
mPointerLocationInputChannel.dispose();
mPointerLocationInputChannel = null;
}
WindowManager wm = (WindowManager)
mContext.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(removeView);
}
TYPE_SYSTEM_OVERLAY,TYPE_TOAST,TYPE_SECURE_SYSTEM_OVERLAY三个类型的窗口不接收inputevent, 所以android为它单独注册InputQueue.registerInputChannel以响应触摸事件绘制滑动轨迹。