always on top button in android
2011-06-09 11:49
357 查看
how can i put my PopupWindow to system desk or other app?
up vote1down votefavorite 1 | how can i put my PopupWindow to system desk or other app? how can i use this permission:INTERNAL_SYSTEM_WINDOW Any examples?Thanks! ![]() android
| ||||||
|
3 Answers
activeoldestvotesup vote0down vote | ok,the problem is resolved. i use WindowManager.addView in a service, and WindowManager.LayoutParams.type = TYPE_SYSTEM_ALERT, then it's ok! you can try it!
| ||||||||||
|
up vote3down vote | public class PopupService extends Service implements IPopupTouchPosListener { public final static String FIELD_EVENT = "event"; /** * 开启 */ public final static int EVENT_SWITCH_ON = 1; /** * 关闭 */ public final static int EVENT_SWITCH_OFF = 2; private CustomPopupView mPopupView; private int mCurrentY; private RelativeLayout mLayout; private WindowManager mWindowManager; private WindowManager.LayoutParams mWmlp; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE); // 获取屏幕宽度 DisplayMetrics outMetrics = new DisplayMetrics(); mWindowManager.getDefaultDisplay().getMetrics(outMetrics); int width = outMetrics.widthPixels; mWmlp = new WindowManager.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); mWmlp.alpha = 0.5f; mWmlp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不能抢占聚焦点 mWmlp.flags = mWmlp.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; mWmlp.flags = mWmlp.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; // 排版不受限制 mWmlp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 系统提示类型 mWmlp.width = width; mWmlp.height = 30; mWmlp.gravity = 2; mWmlp.format = -1; mWmlp.token = null; mWmlp.x = 0; mWmlp.y = 200; mCurrentY = mWmlp.y; mLayout = new RelativeLayout(this); mLayout.setBackgroundColor(0x00FFFFFF); mLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); mPopupView = new CustomPopupView(this); mPopupView.setTouchPosListener(this); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, 30); lp.bottomMargin = 0; lp.leftMargin = 0; mLayout.addView(mPopupView, lp); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.i(Constants.LOG_TAG, "popup service onstart"); String action = intent.getAction(); if(action != null && action.equals(ActionDef.ACTION_POPUP_SERVICE)) { Bundle bundle = intent.getExtras(); if(bundle != null) { int event = bundle.getInt(FIELD_EVENT); if(event == EVENT_SWITCH_ON) { // 显示 mWindowManager.addView(mLayout, mWmlp); } else { mWindowManager.removeView(mLayout); } } } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onMove(float x, float y) { if(mLayout != null) { Log.i(Constants.LOG_TAG, "y = " + y); if(y > mLayout.getHeight()) { mCurrentY = (int)y + mCurrentY - mLayout.getHeight(); } else if(y < 0) { mCurrentY = (int)y + mCurrentY; } // 只更新位置 mWmlp.y = mCurrentY; mWindowManager.updateViewLayout(mLayout, mWmlp); } } }
| ||||
|
up vote0down vote | When I implement the code posted by @yuankai and add a Button view to the layout where he has a CustomPopupView, it appears as expected, over the top of all windows and responds to click events but won't change colour when pressed as Buttons normally do. How can I update the button to change colour when depressed like its normal behaviour?
| ||||||
|
creating a system overlay (always on top) button in android
up vote8down votefavorite 8 | I'm trying to create an always-op-top button/clickable-image which stays on top of all the windows all the time. The proof of concept is here http://www.appbrain.com/app/smart-taskbar-%28sidebar%29/com.smart.taskbar and here http://forum.xda-developers.com/showthread.php?t=865525 I'm following this example code http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=services/java/com/android/server/LoadAverageService.java;h=0d86429aaa5ccf6ecf311dfb3af0f3ccbf5f8d29;hb=HEAD I have been successful and have a running service now. The service displays some text on top left corner of screen all the time while user can freely interact with rest of apps in normal manner. What I'm doing is subclass ViewGroup and add it to root window manager with flag TYPE_SYSTEM_OVERLAY. Now I want to add a button/clickable-image in place of this text which can receive touch events on itself. I tried overriding "onTouchEvent" for the whole ViewGroup but it does not receive any event. How can I receive events only on certain parts of my always-on-top view group? Kindly suggest. import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PixelFormat; import android.os.IBinder; import android.view.Gravity; import android.view.MotionEvent; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.AbsoluteLayout; import android.widget.Button; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; 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 onDestroy() { super.onDestroy(); Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show(); if(mView != null) { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView); mView = null; } } } class HUDView extends ViewGroup { private Paint mLoadPaint; public HUDView(Context context) { super(context); Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show(); mLoadPaint = new Paint(); mLoadPaint.setAntiAlias(true); mLoadPaint.setTextSize(10); mLoadPaint.setARGB(255, 255, 0, 0); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText("Hello World", 5, 15, mLoadPaint); } @Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { } @Override public boolean onTouchEvent(MotionEvent event) { //return super.onTouchEvent(event); Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); return true; } } ![]() android
| ||||||||||
|
3 Answers
activeoldestvotesup vote5down voteaccepted | This might be a stupid solution. But it works. If you can improve it, please let me know. OnCreate of your Service: I have usedWindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag. This is the only change in service. @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, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT); params.gravity = Gravity.RIGHT | Gravity.TOP; params.setTitle("Load Average"); WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.addView(mView, params); } Now, you will start getting each and every click event. So, you need to rectify in your event handler. In your ViewGroup touch event @Override public boolean onTouchEvent(MotionEvent event) { // ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER // THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); return true; }
| ||||||||||||
|
up vote0down vote | It is not possible to get event in this fashion. You can only "display". ====== I have added a solution that worked for me. See my another reply.
| ||||||||||
|
up vote0down vote | Well try my code, atleast it gives you a string as overlay, you can very well replace it with a button or an image. You wont believe this is my first ever android app LOL. Anyways if you are more experienced with android apps than me, please try changing parameters 2 and 3 in "new WindowManager.LayoutParams" try some different event approach
| ||||
|
相关文章推荐
- how to put the text on the left of a radio button in android
- Android坐标getLeft,getRight,getTop,getBottom,getLocationInWindow和getLocationOnScreen
- In Android how to display one view as overlay on top of another view?
- Android坐标getLeft,getRight,getTop,getBottom,getLocationInWindow和getLocationOnScreen
- 在Ext中如何使窗体总在最前面(how to set a window always on top in Ext)
- You should be the top dog in your department and always keep an eye on the outside world.
- How to get file path in onActivityResult in Android 4.4
- Buttons in button bars should be borderless; use style="?android:attr/buttonBarButtonStyle" (and ?an
- android获得控件在屏幕中的绝对坐标 getLocationInWindow 和 getLocationOnScreen
- In Gradle projects, always use http://schemas.android.com/apk/res-auto for custom attributes more..
- android获得控件在屏幕中的绝对坐标 getLocationInWindow 和 getLocationOnScreen
- Android开发_后台任务task管理_allowTaskReparenting alwaysRetainTaskState clearTaskOn
- Android中getLocationOnScreen和getLocationInWindow 获取屏幕大小
- On Memory Leaks in Java and in Android.
- android获得控件在屏幕中的绝对坐标 getLocationInWindow 和 getLocationOnScreen
- android.intent.action.CAMERA_BUTTON not broadcasting on Desire Z (Froyo)?
- Android file canRead() is always false on SD card
- getLocationInWindow getLocationOnScreen 获取Android坐标
- Running GPS positioning in a background thread on Android
- Android - 警告:it is always overridden by the value specified in the Gradle build script