我正在尝试创建一个始终操作顶部按钮/可点击图像,它始终位于所有窗口的顶部.
概念证明是
我已经成功并且现在有一个正在运行的服务.该服务始终在屏幕的左上角显示一些文本,而用户可以正常方式与其他应用程序自由交互.
我正在做的是子类ViewGroup并将其添加到带有标志的根窗口管理器TYPE_SYSTEM_OVERLAY.现在我想添加一个按钮/可点击图像来代替这个文本,它可以自己接收触摸事件.我尝试覆盖整个"onTouchEvent",ViewGroup但它没有收到任何事件.
如何仅在我的常见顶视图组的某些部分接收活动?请建议.
public class HUD extends Service {
HUDView mView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
mView = new HUDView(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
0,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
}
@Override
public void …Run Code Online (Sandbox Code Playgroud) 我比较喜欢这篇文章但是我在将viewgroup添加到windowmanager对象时遇到了错误,我已经使用相同的服务类来发布到问题而没有任何变化,我可能会误认为我没有得到它
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params); // here
Run Code Online (Sandbox Code Playgroud)
当我向WindowManger添加视图时
这是我的清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.searce.testoverlay"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="TestOverlayActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".HUD"></service>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
错误
09-27 18:49:23.561: ERROR/AndroidRuntime(653): Uncaught handler: thread main exiting due to uncaught exception
09-27 18:49:23.571: ERROR/AndroidRuntime(653): java.lang.RuntimeException: Unable to create service com.searce.testoverlay.HUD: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRoot$W@44da9bc0 -- permission denied for this window type …Run Code Online (Sandbox Code Playgroud) 是否可以在Android API级别15中接收通知,只要用户执行任何使设备保持唤醒的操作 - 实际上,无论何时PowerManager.userActivity()调用?
(背景知识:我正在开发一款适用于非固定电源的非移动设备的大型Android应用程序.当用户与屏幕,键盘等交互时,我需要向另一个人发送"保持清醒"信号,连接设备.)
当我尝试从InputMethodService弹出PopupWindow(或Dialog)时,我得到了同样的异常:
FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:505)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:828)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:688)
at mypackage.MyInputMethodService.onClick(MyInputMethodService.java:123)
...
Run Code Online (Sandbox Code Playgroud)
如果我尝试弹出一个Dialog,我会在ViewRoot.java的完全相同的行中得到完全相同的异常.这是我的代码(删节):
public class MyInputMethodService
extends InputMethodService
implements View.OnClickListener {
public void onClick(View v) {
// This is the handler for View.OnClickListener
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
PopupWindow pw = new PopupWindow(inflater.inflate(R.layout.popup_example, null, false), 100, 100, true);
pw.showAtLocation(mInputView, Gravity.CENTER, 0, 0);
// mInputView was previously created and returned by …Run Code Online (Sandbox Code Playgroud) 我知道 SO 对“我该怎么做”的问题非常不满,但这次我没有找到解决办法。
我是一个经验丰富的专家 Android 开发人员,所以我觉得问这个问题真的很傻,但我刚刚安装了这个应用程序 ,它做了一些我认为不可能的事情。
也就是说,它会监听屏幕手势(在这种情况下是从屏幕边缘向内滑动),无论您在设备上的哪个位置......意思是,它会在您在 Launcher 主屏幕上以及当您在其他应用程序......无论你在做什么,它都在监听,当它检测到从屏幕边缘滑动时,它会让你带出一个隐藏的设置抽屉,然后作为一个透明的(片段?对话框?)View在顶部您在使用的任何其他应用程序以及在被解雇时(通过按 BACK 键)会让您在之前的体验中处于任何位置。
老实说,我不知道这是怎么可能的,并且真的很想朝正确的方向推动。[编辑]
我创建了一个TYPE_SYSTEM_ALERT视图,设置标志FLAG_NOT_TOUCH_MODAL和FLAG_WATCH_OUTSIDE_TOUCH,并用WindowManager.addView()添加它;
当我在视图之外触摸我自己的活动时,一切正常,MotionEvent.getY()返回正确的值.
但是,如果我退出我的活动并触摸另一个应用程序,MotionEvent.getY()始终返回0.
我不确定这是否只发生在4.2上.
任何帮助,将不胜感激!