我用Android手机装了个电商软件,抢购用。自己手机的状态栏不能显示秒级别的时间,只能精确到分钟。为了能准确的把握抢购时间,自己边学习边开发了一个时间显示悬浮窗。

WindowManager

参考文章

WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。

使用Context.getSystemService(Context.WINDOW_SERVICE)来获取WindowManager。

API 17推出了Presentation,它将自动获取display的Context和WindowManager,可以方便地在另一个display上显示窗口

使用WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口

WindowManager实现悬浮窗需要声明权限,在manifest中添加如下权限:

在MIUI上需要在设置中打开本应用的”显示悬浮窗”开关,并且重启应用,否则悬浮窗只能显示在本应用界面内,不能显示在手机桌面上。

具体过程

创建工程

用Android Studio创建一个Android Basic Activity工程

添加权限

修改AndroidManifest.xml,添加下面结构的数据

修改代码

给MainActivity添加两个属性

public class MainActivity extends AppCompatActivity {

TextView textView; //用于显示时间

Timer timer;//用于定时刷新时间

...

}

Android Basic Activity工程创建后,自带一个按钮,给按钮添加点击事件的处理

final View.OnClickListener listener = new View.OnClickListener() {

@Override

public void onClick(View view) {

final WindowManager.LayoutParams params = new WindowManager.LayoutParams();

// 类型 TYPE_SYSTEM_OVERLAY ,当悬浮窗口在其他App窗口上面时,不会隔断触摸事件,其他App能正常使用。

//若要隔断触摸事件,可以使用TYPE_SYSTEM_ALERT

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 设置flag

int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件

// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口

// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按

params.flags = flags;

// 不设置这个弹出框的透明遮罩显示为黑色

params.format = PixelFormat.TRANSLUCENT;

params.width = 300;

params.height = 50;

params.gravity = Gravity.TOP;

TextView top=new TextView(view.getContext());

//控件字体位置位于左边

top.setGravity(Gravity.LEFT);

top.setText("悬浮窗口");

WindowManager windowManager = (WindowManager)view.getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);

windowManager.addView(top,params);

textView = top;

startTimer();//启动定时器(实现在后面)

}

};

FloatingActionButton fab = findViewById(R.id.fab);

//添加点击事件处理

fab.setOnClickListener(listener);

定时器刷新时间

public void startTimer(){

timer = new Timer();

timer.schedule(new TimerTask() {

@Override

public void run() {

Date currentTime = new Date();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

final String dateString = formatter.format(currentTime);

MainActivity.this.runOnUiThread(new Runnable() {

@Override

public void run() {

textView.setText(dateString);

}

});

}

},1000,300);

}

完整代码如下

package com.zxs.windonwtimer;

import android.content.Context;

import android.graphics.PixelFormat;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;

import androidx.appcompat.widget.Toolbar;

import android.view.Gravity;

import android.view.View;

import android.view.Menu;

import android.view.MenuItem;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.TextView;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

TextView textView;

Timer timer;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Toolbar toolbar = findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

final View.OnClickListener listener = new View.OnClickListener() {

@Override

public void onClick(View view) {

final WindowManager.LayoutParams params = new WindowManager.LayoutParams();

// 类型

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// WindowManager.LayoutParams.TYPE_SYSTEM_ALERT

// 设置flag

int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件

// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口

// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按

// 不设置这个flag的话,home页的划屏会有问题

params.flags = flags;

// 不设置这个弹出框的透明遮罩显示为黑色

params.format = PixelFormat.TRANSLUCENT;

params.width = 300;//WindowManager.LayoutParams.MATCH_PARENT;

params.height = 50;//WindowManager.LayoutParams.MATCH_PARENT;

params.gravity = Gravity.TOP;

TextView top=new TextView(view.getContext());

//控件字体位置位于左边

top.setGravity(Gravity.LEFT);

top.setText("悬浮窗口");

WindowManager windowManager = (WindowManager)view.getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);

windowManager.addView(top,params);

textView = top;

startTimer();

}

};

FloatingActionButton fab = findViewById(R.id.fab);

fab.setOnClickListener(listener);

}

public void startTimer(){

timer = new Timer();

timer.schedule(new TimerTask() {

@Override

public void run() {

Date currentTime = new Date();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

final String dateString = formatter.format(currentTime);

MainActivity.this.runOnUiThread(new Runnable() {

@Override

public void run() {

textView.setText(dateString);

}

});

}

},1000,300);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

//noinspection SimplifiableIfStatement

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

}

android 全局 窗口,学习笔记:WindowManager显示Android全局悬浮窗口相关推荐

  1. 【Android】SerialPortFinder学习笔记,显示串口列表

    显示串口列表这个操作还不涉及底层的东西,因为Android与Linux相似,有串口设备就会在/dev目录下生成一个文件,比如/dev/ttyS0之类的,在谷歌的ndroid-serialport-ap ...

  2. Android学习笔记07---查看Android虚拟机输出的错误信息与如何部署应用到自己的真实手机

    Android学习笔记07---查看Android虚拟机输出的错误信息

  3. Android学习笔记----解决“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”问题

    Android学习笔记----解决"com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 6553 ...

  4. Android编译及编译脚本、Android构建基础学习笔记

    Android编译及编译脚本.Android构建基础学习笔记 Android编译及编译脚本 概述 Android.mk转换成Android.bp 例子(简单Android.mk文件转Android.b ...

  5. Android开发技术学习笔记

    目标:全面学习知识点,能理解原理,多实战练习并做笔记与总结学习心得 Android开发技术学习笔记记录如下: Android开发Google的官网https://developer.android.g ...

  6. Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)

    Unity Shader 学习笔记(33) 全局光照(GI).反射探针.线性空间和伽马空间.高动态范围(HDR) 参考书籍:<Unity Shader 入门精要> [<Real-Ti ...

  7. 便签 java_基于安卓Android的便签笔记APP设计(Android studio)

    基于安卓Android的便签笔记APP设计(Android studio)(论文9000字,程序代码) 摘要:本文介绍了便签的发展史.基础操作流程以及便签的具体功能,提出了基于Android的便签AP ...

  8. Android开发入门之学习笔记(三):程序窗口的布局

    2019独角兽企业重金招聘Python工程师标准>>> Android应用程序的用户界面可以看作是由View和View Group组成的,从字面意思上就可以看出,View Group ...

  9. Android之内核学习笔记

    0.Android系统启动 <Android系统启动流程 -- bootloader> <The Android boot process from power on> < ...

最新文章

  1. shell 执行 oracle sql
  2. 从零开始学_JavaScript_系列(14)——dojo(7)(饼图,BorderContainer,hashchange,弹窗)...
  3. emmet中文文档 (转载)
  4. 函数参数---动态参数
  5. C和C++中的整形数据类型
  6. SharePoint 2010 工作流解决方案:将 SharePoint Designer 可重用工作流导入 Visual Studio...
  7. python读取日志错误信息_关于修复 Bug 这件“小事”|利用Python 日志查找错误也可行...
  8. [XSY3112] 接水果(树上包含路径,整体二分,扫描线)
  9. Java十六进制浮点文字
  10. eclipse指定JDK版本启动,解决version XXX of the JVM is not suitable for this product.Version:XXX 问题
  11. LINQ to CSV,一种类型安全,动态的高性能方法
  12. (转)Uncaught TypeError: Cannot set property 'innerHTML' of null
  13. vijos1777 引水入城
  14. python批量下载文件
  15. cpu多开测试软件,教你用多核CPU多开畅玩大型3D游戏
  16. 图片转换成文字的在线转换方法
  17. 面试总结系列(一)------ 国际化中台事业部
  18. js中的生成器函数Generator
  19. 147计算机代表啥,147代表什么意思
  20. revit常用机电工具,如何实现管线快速翻弯

热门文章

  1. 京东总部4号楼即将投入使用:建面超过13万平方米 耗时644天
  2. 史上最牛“老赖”,如今走下神坛:骗遍全国,牛皮终于吹破了!
  3. Facebook合并WhatsApp和Instagram?德国:展开反垄断调查!
  4. 程序员8月薪资新鲜出炉,圈外人却在酸?
  5. java smtp pop3_POP3/SMTP指令
  6. pythonsupermro_Python高级编程之继承问题详解(super与mro)
  7. sv信道模型是什么_Unity Shader|基本光照模型实现中遇到的疑思
  8. r720支持多少频率的内存吗_DDR4 2400到DDR4 3200,最大内存频率买多少?为什么买了高频 速度却上不去...
  9. shell脚本执行命令错误处理
  10. oracle中文转全拼音,Oracle 将汉字转为全拼或返回拼音首字母SQL(二)