使用WindowManager实现Android悬浮窗

ShaRoyer 8年前
   <p>在做项目的时候有时候会用到windowmanager,下面将一些核心代码贴出来供参考。</p>    <p>效果图</p>    <p><img src="https://simg.open-open.com/show/c5e02d12d6e8f03769212e4934434e56.png"></p>    <p style="text-align:center">windowmanager.png</p>    <p>声明权限</p>    <pre>  <code class="language-java"><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /></code></pre>    <p>控制类</p>    <pre>  <code class="language-java">package com.test.window;    import java.lang.reflect.Method;    import android.app.Service;  import android.content.Context;  import android.content.Intent;  import android.graphics.PixelFormat;  import android.graphics.drawable.ColorDrawable;  import android.os.Handler;  import android.os.IBinder;  import android.os.Message;  import android.util.DisplayMetrics;  import android.view.LayoutInflater;  import android.view.View;  import android.view.Window;  import android.view.WindowManager;  import android.view.WindowManager.LayoutParams;    public class ControlService extends Service {      public static final String TAG = ControlService.class.getSimpleName();      LayoutInflater mLayoutInflater;      public static Context mContext;      Test testView;      Test2 testView2;      public static int screenWidth = 0, screenHeight = 0;      public static WindowManager mWindowManager;      public static Window mWindow;      static ColorDrawable colorDrawable = new ColorDrawable();      public static final int CHANGE_VIEW_EVENT = 0X30;// 界面转换事件标志      public static final int LIVE_TV = 0x39;// 主界面      public static final int TEST_VIEW = 13;// 第一个界面      public static final int TEST_VIEW2 = 14;// 第二个界面      public static Handler myHandler;        class MyHandler extends Handler {          @Override          public void handleMessage(Message msg) {              switch (msg.what) {              case CHANGE_VIEW_EVENT:                  changeView(msg);                  break;              }          }      }        public int onStartCommand(Intent intent, int flags, int startId) {          if (intent != null) {              String event = intent.getStringExtra(Const.START_SERVICE_HEAD);              if (event == null) {                  return super.onStartCommand(intent, flags, startId);              } else if (Const.START_DTV_EVENT.equals(event)) {                  changeViewEvent(LIVE_TV, TEST_VIEW, null);              }          }          return super.onStartCommand(intent, flags, startId);      }        @Override      public void onCreate() {          super.onCreate();          myHandler = new MyHandler();          mContext = this;          mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);          mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);          DisplayMetrics metric = new DisplayMetrics();          mWindowManager.getDefaultDisplay().getMetrics(metric);          int width = metric.widthPixels; // 屏幕宽度(像素)          int height = metric.heightPixels; // 屏幕高度(像素)          screenHeight = height;          screenWidth = width;          String POLICYMANAGER_CLASS_NAME = "com.android.internal.policy.PolicyManager";          try {              Class policyManagerClass = Class.forName(POLICYMANAGER_CLASS_NAME);              Class[] parameterTypes = { Context.class };              Method method = policyManagerClass.getMethod("makeNewWindow", parameterTypes);              mWindow = (Window) method.invoke(null, mContext);              mWindow.setFormat(PixelFormat.TRANSLUCENT);              mWindow.requestFeature(Window.FEATURE_NO_TITLE);              mWindow.setWindowManager(mWindowManager, null, null);              colorDrawable.setAlpha(0);          } catch (Exception e1) {              e1.printStackTrace();          }            testView = new Test(mLayoutInflater, mContext);          testView2 = new Test2(mLayoutInflater, mContext);      }        private void changeView(Message msg) {          int toView = msg.arg2;          switch (toView) {          case TEST_VIEW:              testView.showView();              break;          case TEST_VIEW2:              testView2.showView();              break;          case LIVE_TV:              removeContentView();              break;          }      }        public static void changeViewEvent(int ar1, int ar2, Object obj) {          Message msg = myHandler.obtainMessage(CHANGE_VIEW_EVENT, ar1, ar2, obj);          myHandler.sendMessage(msg);      }        static Handler handler = new Handler();        public static void setContentView(View view, LayoutParams params) {          try {              mWindowManager.removeView(mWindow.getDecorView());          } catch (Exception e) {              e.printStackTrace();          }          mWindow.setBackgroundDrawable(colorDrawable);          mWindow.setContentView(view, params);          mWindowManager.addView(mWindow.getDecorView(), params);      }        public static void removeContentView() {          try {              mWindowManager.removeView(mWindow.getDecorView());          } catch (Exception e) {              e.printStackTrace();          }      }        @Override      public IBinder onBind(Intent intent) {          return null;      }    }</code></pre>    <p>界面展示</p>    <pre>  <code class="language-java">package com.test.window;    import com.htv.daoshi.R;    import android.content.Context;  import android.graphics.PixelFormat;  import android.view.Gravity;  import android.view.KeyEvent;  import android.view.LayoutInflater;  import android.view.View;  import android.view.WindowManager;  import android.widget.Button;    /**   * Created by Think on 2016/9/19.   */  public class Test implements View.OnKeyListener, View.OnClickListener {      public static final String TAG = Test.class.getSimpleName();      Context context;      View myRoot;      Button btnSkip,btnClose;      WindowManager.LayoutParams mParams;      int x, y, width, height;        public Test(LayoutInflater inflater, Context c) {          context = c;          width = ControlService.screenWidth;          height = ControlService.screenHeight * 264 / 720;          x = 0;          y = 0;          mParams = new WindowManager.LayoutParams();          mParams.width = width;          mParams.height = height;          mParams.x = x;          mParams.y = y;          mParams.gravity = Gravity.RIGHT | Gravity.BOTTOM;          mParams.format = PixelFormat.TRANSLUCENT;          mParams.type = WindowManager.LayoutParams.TYPE_PHONE;          myRoot = (View) inflater.inflate(R.layout.test, null);          btnSkip = (Button) myRoot.findViewById(R.id.btn_skip);          btnClose = (Button) myRoot.findViewById(R.id.btn_close);          btnSkip.setOnClickListener(this);          btnSkip.setOnKeyListener(this);          btnClose.setOnClickListener(this);          btnClose.setOnKeyListener(this);      }      /**       * 显示view       */      public void showView() {          ControlService.setContentView(myRoot, mParams);      }      /**       * 关闭view       */      public void closeView() {          ControlService.removeContentView();      }        @Override      public void onClick(View v) {          switch (v.getId()) {          case R.id.btn_skip://跳转到第二个windowmanager              ControlService.changeViewEvent(ControlService.TEST_VIEW, ControlService.TEST_VIEW2, null);              break;          case R.id.btn_close://关闭              closeView();              break;          }      }        @Override      public boolean onKey(View v, int keyCode, KeyEvent event) {          if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {              closeView();              return true;          }          return false;      }  }</code></pre>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/29b385e53feb</p>    <p> </p>