自定义Toast显示(不限时+在其他应用之上显示)

一.首先写好自定义Toast的布局

toast_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/tv_toast_number"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/call_locate_white"android:drawableStart="@android:drawable/ic_menu_call"android:gravity="center"android:text="来电话啦"/></LinearLayout>

二.查看源码看看官方是怎么写Toast的

进入Toast源码中,看到

TN() {// XXX This should be changed to use a Dialog, with a Theme.Toast// defined that sets up the layout params appropriately.final WindowManager.LayoutParams params = mParams;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.format = PixelFormat.TRANSLUCENT;params.windowAnimations = com.android.internal.R.style.Animation_Toast;params.type = WindowManager.LayoutParams.TYPE_TOAST;params.setTitle("Toast");params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;}

三.下面开始使用Toast搞点事情

/*** Created by xfhy* 打电话时的归属地悬浮窗由这个服务去管理*/
public class AddressService extends Service {private TelephonyManager mTm;private static final String TAG = "AddressService";/*** 监听电话的监听器*/private MyPhoneStateListener mPhoneStateListener;/*** Toast的规则*/private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();/*** WindowManager管理者对象*/private WindowManager mWM;/*** Toast上的View*/private View mToastView;@Overridepublic void onCreate() {//第一次开启服务之后,就需要去管理Toast的显示//电话状态的监听(服务开启的时候,需要去做监听,关闭的时候电话状态就不需要监听了)//1, 电话管理者对象mTm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);//2, 监听电话状态mPhoneStateListener = new MyPhoneStateListener();mTm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);//3, 获取窗体对象mWM = (WindowManager) getSystemService(WINDOW_SERVICE);super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {throw new UnsupportedOperationException("Not yet implemented");}@Overridepublic void onDestroy() {//取消对电话状态的监听   如果不取消监听的话,则即使停止了Service,还是在监听着的if (mTm != null && mPhoneStateListener != null) {mTm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);}super.onDestroy();}/*** 显示Toast** @param incomingNumber*/private void showToast(String incomingNumber) {//Toast.makeText(MyApplication.getContext(), incomingNumber, Toast.LENGTH_LONG).show();//宽高final WindowManager.LayoutParams params = mParams;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.format = PixelFormat.TRANSLUCENT;//在响铃的时候显示吐司,和电话类型一致params.type = WindowManager.LayoutParams.TYPE_PHONE;params.setTitle("Toast");params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
//                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE   默认是不可以触摸的| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;//指定Toast所在位置params.gravity = Gravity.LEFT + Gravity.TOP;//吐司显示效果(吐司布局文件) ,xml->view(吐司),将吐司挂在windowManager窗体上mToastView = View.inflate(this, R.layout.toast_view, null);mWM.addView(mToastView, mParams);}/*** 电话状态的监听* 监听器类,用于监视设备上特定电话状态的变化,包括服务状态,信号强度,消息等待指示符(语音信箱)等。* 覆盖您希望接收更新的状态的方法,* 并将您的PhoneStateListener对象与按位或LISTEN_标志一起传递给TelephonyManager.listen()。* 请注意,对某些电话信息的访问权限受到保护。 您的应用程序将不会收到受保护信息的更新,* 除非它的清单文件中声明了相应的权限。 在适用权限的情况下,它们会在相应的LISTEN_标志中注明。*/class MyPhoneStateListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_IDLE://无任何状态时    空闲状态LogUtil.d(TAG, "空闲状态");//空闲状态的时候需要移除Toast显示if (mWM != null && mToastView != null) {//最开始的时候是空闲状态的,那个时候mToastView是null的,需要判断非空//挂断电话的时候也是空闲状态,也需要移除ToastmWM.removeView(mToastView);}break;case TelephonyManager.CALL_STATE_OFFHOOK://接起电话时   摘机LogUtil.d(TAG, "摘机状态");break;case TelephonyManager.CALL_STATE_RINGING://电话进来时   响铃LogUtil.d(TAG, "响铃状态");//showToast(incomingNumber);requestPermission(incomingNumber);break;}}}/*** 请求显示在其他应用之上的权限* <p>* 当运行在23之上的时候,不仅需要在清单文件中写入* <uses-permission android:name="android.permission* .SYSTEM_ALERT_WINDOW"/>* 但是仅仅这样还不行,还会报下面的错* Unable to add window android.view.ViewRootImpl$W@18a6ff4 --* permission denied for window type 2002* 现在需要像下面一样判断一下,如果没有权限,则需要用户跳转到相应的界面去给权限才行** @param incomingNumber 需要显示的内容*/public void requestPermission(String incomingNumber) {if (Build.VERSION.SDK_INT >= 23) {if (!Settings.canDrawOverlays(this)) {Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);startActivity(intent);return;} else {//Android6.0以上showToast(incomingNumber);}} else {//Android6.0以下,不用动态声明权限showToast(incomingNumber);}}}

模仿Toast里面的写法,写出上面的showToast()方法,用于显示自定义的Toast.

四.遇到的坑

当运行在23之上的时候,不仅需要在清单文件中写入
<uses-permission android:name="android.permission
.SYSTEM_ALERT_WINDOW"/>
但是仅仅这样还不行,还会报下面的错
Unable to add window android.view.ViewRootImpl$W@18a6ff4 --
permission denied for window type 2002

现在需要像下面一样判断一下,如果没有权限,则需要用户跳转到相应的界面去给权限才行

五.总结

上面的Service是用于监听当电话打入时,显示一个自定义的Toast,当电话挂断时,自定义Toast就取消显示.相当于是Toast可以显示很久很久(只要是电话没挂),而且还会显示在Toast之上.

Android 自定义Toast显示(不限时+在其他应用之上显示)相关推荐

  1. Android 自定义Toast实现多次触发只会显示一次toast

    #使用场景描述 当我们处于某个场景,例如一个按钮可以触发toast的显示,当你在多次点击按钮时,会多次触发toast的显示.而调用android原生的toast的makeText的方式所生产的toas ...

  2. android一天一次弹窗,Android自定义Toast,多次弹出时取消上次弹出,最后一次弹出为准...

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. Android的Toast用队列管理弹出的消息,这个自定义的Toast用于频繁弹出Toas ...

  3. android custom toast,Android自定义Toast

    核心代码: package com.huatec.myapplication; import android.content.Context; import android.graphics.Bitm ...

  4. android中自定义 toast,android 自定义Toast样式和显示方式

    问题: 1.android 开发中如果不停的触发显示Toast,会造成Toast一个接一个的弹出,非常影响用户体验. 2.android设备有千万个,每个设备的Toast的背景有可能不一样,造成在应用 ...

  5. android中自定义 toast,android 自定义Toast

    Toast是android的一个简易消息提示框. 它不会获得焦点,也无法被点击.向用户提示信息,却不停留着不动. 其实,自定义Toast非常简单: 先看效果: 首先:新建一个mtoast.xml布局文 ...

  6. Android自定义Toast

    在Android程序设计中,有时候我们需要自定义Toast提示信息的背景颜色和边框颜色,例如下图: 默认的Toast无法实现我们所需要的效果,那么我们只能自定义布局文件,另外Toast的背景形状是圆角 ...

  7. android toast 自定义时间,android自定义Toast设定显示时间

    开发android的同学可能会抱怨Toast设定显示的时长无效,只能是Toast.LENGTH_LONG 或者Toast.LENGTH_SHORT 之一,为了解决这些办法,有多种实现方式: 1.使用定 ...

  8. Android 自定义 Toast

    前言 安卓原生Toast只提供了两种展示方式 即 Toast.LENGTH_LONG 或者Toast.LENGTH_SHORT ,但这远远满足不了产品经理的各种需求, 所以本文展示的就是一个可自定义位 ...

  9. android点击弹出滑动条,IndicatorSeekBar Android自定义SeekBar,滑动时弹出气泡指示器显示进度...

    overview.png 之前在网上看到了当Slider控件在滑动时会弹出气泡指示器,觉得很有趣,于是就进行拓展,就有了下面介绍的一个安卓控件:IndicatorSeekBar.先附上Indicato ...

最新文章

  1. HBase底层存储原理——我靠,和cassandra本质上没有区别啊!都是kv 列存储,只是一个是p2p另一个是集中式而已!...
  2. java session 是什么意思_Java:Session详解
  3. C++Jump Search跳转搜索的实现算法(附完整源码)
  4. oracle execute immediate执行多条语句_用数据库的方式思考SQL是如何执行的
  5. sklearn查看数据
  6. Python输出当前时间
  7. 推荐一个css帮助手册的版本 同时提供chm和在线
  8. php有重载函数吗,PHP: 重载 - Manual
  9. mips架构中断流程
  10. idea自动删除尾行空格(空行中空格)
  11. CSUOJ 1256 天朝的单行道(最短路)
  12. 当年校招时,我就死在这个问题上...
  13. 论软件自动化测试中 QR_Code 的登录的逻辑
  14. 软件集合贴:学软件测试必备软件,看这里足足够了
  15. python模型预测_用Python如何进行预测型数据分析
  16. Dubbo 专题(基础篇):Dubbo 介绍、环境搭建与实践
  17. 睿智的目标检测——YoloV7-Tiny-OBB旋转目标检测算法部署
  18. Fat32、NTFS、exFAT、HFS+、APFS文件系统的区别
  19. matlab填充封闭包含区域,求指导matlab怎么填充曲线构成的封闭区域
  20. Kotlin | 委托(Delegation )详解

热门文章

  1. 对semantic的部分总结
  2. 10tb服务器硬盘 选购,西部数据硬盘最新命名规则以及外置硬盘My Book 10TB性能评测...
  3. 计算机错误代码105 55,steam错误代码105如何解决_steam错误代码105的处理方法
  4. vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)
  5. 天然药物的复兴,传统靶向药物面临新挑战
  6. arm linux i2c 总线驱动,ARM-Linux中I2C总线驱动开发
  7. Spyder 连接远程服务器(spyder-kernels)
  8. Swing+IO+Awt实现高级抽奖系统
  9. 【Codecs系列】mpeg2解码器开源实现:libmpeg2
  10. ZooKeeper 可视化工具