悬浮窗管理

转载地址:http://blog.csdn.net/guolin_blog/article/details/8689140

主界面启动服务,在服务中根据不同状态对悬浮窗进行管理

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button)findViewById(R.id.btn_float_window);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent(MainActivity.this,FloatWindowService.class);
                startService(intent);
                finish();
            }
        });
    }
}

自定义大悬浮窗VIEW

public class BigFloatView extends LinearLayout implements View.OnClickListener
{
    public static int viewHeight;
    public static int viewWidth;

    public BigFloatView(Context context){
        super(context);
        LayoutInflater.from(context).inflate(R.layout.big_float_window,this);
        View view = findViewById(R.id.big_window);
        viewWidth = view.getLayoutParams().width;
        viewHeight = view.getLayoutParams().height;
        Button btnClose = (Button)view.findViewById(R.id.close);
        Button btnBack = (Button)view.findViewById(R.id.back);
        btnClose.setOnClickListener(this);
        btnBack.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        switch(v.getId()){
            //关闭所有悬浮窗并停止服务
            case R.id.close:
                Intent intent = new Intent(getContext(),FloatWindowService.class);
                getContext().stopService(intent);
                MyWindowManager.removeBigWindow(getContext());
                MyWindowManager.removeSmallView(getContext());
                break;
            //从大悬浮窗返回到小悬浮窗
            case R.id.back:
                MyWindowManager.removeBigWindow(getContext());
                MyWindowManager.createSmallWindow(getContext());
                break;
        }
    }

    //回退键进入小悬浮窗
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if(event.getAction()==KeyEvent.ACTION_DOWN&&event.getKeyCode()==KeyEvent.KEYCODE_BACK){
            MyWindowManager.removeBigWindow(getContext());
            MyWindowManager.createSmallWindow(getContext());
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
}

自定义可拖拽的小悬浮窗VIEW

public class SmallFloatView extends LinearLayout
{
    /**
     * 记录小悬浮窗的宽度
     */
    public static int viewWidth;

    /**
     * 记录小悬浮窗的高度
     */
    public static int viewHeight;

    /**
     * 记录系统状态栏的高度
     */
    private static int statusBarHeight;

    /**
     * 用于更新小悬浮窗的位置
     */
    private WindowManager windowManager;

    /**
     * 小悬浮窗的参数
     */
    private WindowManager.LayoutParams mParams;

    /**
     * 记录当前手指位置在屏幕上的横坐标值
     */
    private float xInScreen;

    /**
     * 记录当前手指位置在屏幕上的纵坐标值
     */
    private float yInScreen;

    /**
     * 记录手指按下时在屏幕上的横坐标的值
     */
    private float xDownInScreen;

    /**
     * 记录手指按下时在屏幕上的纵坐标的值
     */
    private float yDownInScreen;

    /**
     * 记录手指按下时在小悬浮窗的View上的横坐标的值
     */
    private float xInView;

    /**
     * 记录手指按下时在小悬浮窗的View上的纵坐标的值
     */
    private float yInView;

    public SmallFloatView(Context context){
        super(context);
        windowManager  = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
        LayoutInflater.from(context).inflate(R.layout.small_float_window,this);
        View view = findViewById(R.id.small_window);
        TextView tvPercent = (TextView)view.findViewById(R.id.percent);
        viewWidth = view.getLayoutParams().width;
        viewHeight = view.getLayoutParams().height;
        tvPercent.setText(MyWindowManager.getMemoryUsedPercent(context));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        Log.d("TAG",slop+"");
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                xInView = event.getX();
                yInView = event.getY();
                xDownInScreen = event.getRawX();
                yDownInScreen = event.getRawY() - getStatusBarHeight();
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                break;
            case MotionEvent.ACTION_MOVE:
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                //更新小悬浮窗的位置
                updateViewPosition();
                break;
            case MotionEvent.ACTION_UP:
                // 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
                if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
                    openBigWindow();
                }
                break;
        }
        return true;
    }

    //获取状态栏高度
    private int getStatusBarHeight(){
        if(statusBarHeight==0){
            Class<?> c;
            try
            {
                c = Class.forName("com.android.internal.R$dimen");
                Object o = c.newInstance();
                Field field = c.getField("status_bar_height");
                int x = (Integer) field.get(o);
                statusBarHeight = getResources().getDimensionPixelSize(x);
            }catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        return statusBarHeight;
    }

    //给小悬浮窗设置窗口布局参数
    public void setParams(WindowManager.LayoutParams params) {
        mParams = params;
    }

    private void updateViewPosition() {
        mParams.x = (int) (xInScreen - xInView);
        mParams.y = (int) (yInScreen - yInView);
        windowManager.updateViewLayout(this, mParams);
    }

    public void openBigWindow(){
        MyWindowManager.createBigWindow(getContext());
        MyWindowManager.removeSmallView(getContext());
    }

}

封装大小悬浮窗的添加、移除操作

public class MyWindowManager
{
    /**
     * 小悬浮窗View的实例
     */
    private static SmallFloatView smallWindow;

    /**
     * 大悬浮窗View的实例
     */
    private static BigFloatView bigWindow;

    /**
     * 小悬浮窗View的参数
     */
    private static WindowManager.LayoutParams smallWindowParams;

    /**
     * 大悬浮窗View的参数
     */
    private static WindowManager.LayoutParams bigWindowParams;

    /**
     * 用于控制在屏幕上添加或移除悬浮窗
     */
    private static WindowManager mWindowManager;

    /**
     * 用于获取手机可用内存
     */
    private static ActivityManager mActivityManager;

    /**
     * 创建小悬浮窗在右边中间位置
     * @param context
     */
    public static void createSmallWindow(Context context){
        WindowManager windowManager = getWindowManager(context);
        int screenWidth = windowManager.getDefaultDisplay().getWidth();
        int screenHeight = windowManager.getDefaultDisplay().getHeight();
        if(smallWindow==null){
            Toast.makeText(context,"new smallWindow",Toast.LENGTH_SHORT).show();
            smallWindow = new SmallFloatView(context);
            if(smallWindowParams==null){
                Toast.makeText(context,"new params",Toast.LENGTH_SHORT).show();
                smallWindowParams = new LayoutParams();
                smallWindowParams.type = LayoutParams.TYPE_PHONE;
                smallWindowParams.format = PixelFormat.RGBA_8888;
                smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | LayoutParams.FLAG_NOT_FOCUSABLE;
                smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
                smallWindowParams.width = SmallFloatView.viewWidth;
                smallWindowParams.height = SmallFloatView.viewHeight;
                //TAG
                smallWindowParams.x = screenWidth - SmallFloatView.viewWidth;
                smallWindowParams.y = screenHeight / 2 - SmallFloatView.viewHeight/2;
            }
            //TAG
            smallWindow.setParams(smallWindowParams);
            windowManager.addView(smallWindow,smallWindowParams);
        }
    }

    public static void removeSmallView(Context context){
        if(smallWindow!=null){
            WindowManager windowManager = getWindowManager(context);
            windowManager.removeView(smallWindow);
            smallWindow = null;
        }
    }


    /**
     * 创建大悬浮窗在屏幕中间位置
     * @param context
     */
    public static void createBigWindow(Context context){
        WindowManager windowManager = getWindowManager(context);
        int screenWidth = windowManager.getDefaultDisplay().getWidth();
        int screenHeight = windowManager.getDefaultDisplay().getHeight();
        if(bigWindow==null){
            bigWindow = new BigFloatView(context);
            if(bigWindowParams==null){
                bigWindowParams = new LayoutParams();
                bigWindowParams = new LayoutParams();
                bigWindowParams.x = screenWidth / 2 - BigFloatView.viewWidth / 2;
                bigWindowParams.y = screenHeight / 2 - BigFloatView.viewHeight / 2;
                bigWindowParams.type = LayoutParams.TYPE_PHONE;
                bigWindowParams.format = PixelFormat.RGBA_8888;
                bigWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
                bigWindowParams.width = BigFloatView.viewWidth;
                bigWindowParams.height = BigFloatView.viewHeight;
            }
            windowManager.addView(bigWindow,bigWindowParams);
        }
    }

    public static void removeBigWindow(Context context){
        if(bigWindow!=null){
            WindowManager windowManager = getWindowManager(context);
            windowManager.removeView(bigWindow);
            bigWindow = null;
        }
    }

    public static WindowManager getWindowManager(Context context){
        if(mWindowManager==null)
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        return mWindowManager;
    }

    public static ActivityManager getActivityManager(Context context){
        if(mActivityManager==null)
            mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        return mActivityManager;
    }

    /**
     * 获取当前可用内存,字节为单位
     * @param context
     * @return
     */
    public static long getAvailableMemory(Context context){
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        getActivityManager(context).getMemoryInfo(memoryInfo);
        return memoryInfo.availMem;
    }

    public static String getMemoryUsedPercent(Context context){
        String filePath = "/proc/meminfo";
        try {
            FileReader fileReader = new FileReader(filePath);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String memoryLine = bufferedReader.readLine();
            String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
            bufferedReader.close();
            long totalMemorySize = Integer.parseInt(subMemoryLine.replaceAll("\\D+", ""));
            long availableSize = getAvailableMemory(context) / 1024;
            int percent = (int) ((totalMemorySize - availableSize) / (float) totalMemorySize * 100);
            return percent + "%";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "Error";
    }

    public static boolean isWindowShow(){
        return smallWindow!=null||bigWindow!=null;
    }

    /**
     * 小悬浮窗数据更新
     * @param context
     */
    public static void updateMemoryUsedPercent(Context context){
        if(smallWindow!=null){
            TextView tv = (TextView) smallWindow.findViewById(R.id.percent);
            tv.setText(getMemoryUsedPercent(context));
        }
    }
}

服务中开启新线程,每隔0.5S刷新状态

//在服务中管理悬浮窗的显示,刷新悬浮窗数据
public int onStartCommand(Intent intent, int flags, int startId) {
    if (timer == null) {
        timer = new Timer();
        timer.scheduleAtFixedRate(new RefreshTask(), 0, 500);
    }
    return super.onStartCommand(intent, flags, startId);
}

//服务销毁时定时器取消任务
public void onDestroy() {
    super.onDestroy();
    if (timer != null)
        timer.cancel();
    timer = null;
}

//刷新任务,每500ms执行一次
class RefreshTask extends TimerTask {
    @Override
    public void run() {
        //在桌面且没有悬浮窗显示
        if (isHome() && !MyWindowManager.isWindowShow()) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    MyWindowManager.createSmallWindow(FloatWindowService.this);
                }
            });
        //不在桌面且有悬浮窗显示
        } else if (!isHome() && MyWindowManager.isWindowShow()) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    MyWindowManager.removeBigWindow(FloatWindowService.this);
                    MyWindowManager.removeSmallView(FloatWindowService.this);
                }
            });
        //在桌面且有悬浮窗显示
        } else if (isHome() && MyWindowManager.isWindowShow()) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    MyWindowManager.updateMemoryUsedPercent(FloatWindowService.this);
                }
            });
        }
    }
}

//判断当前界面是否在桌面
private boolean isHome() {
    ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
    return getHome().contains(runningTasks.get(0).topActivity.getPackageName());
}

private List<String> getHome() {
    PackageManager packageManager = getPackageManager();
    List<String> names = new ArrayList<String>();
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo info : resolveInfos) {
        names.add(info.activityInfo.packageName);
    }
    return names;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值