我们都知道Toast的几种用法,像什么居中啊,添加图片显示啊等等。不过这里我要说的是能够全屏显示和永远不会消失的另类Toast。全屏显示和之前大家了解的居中有点类似,只要修改setGravity(int gravity, int xOffset,int yOffset)中的第一个参数值为Gravity.FILL就ok了。麻烦的是要让Toast永远不消失,这里我们要用到反射机制。

我们要了解一件事,那就是我们在弹出Toast的时候,必须加上.show()。顾名思义,大家可能都会以为,这里的.show()是去显示这个Toast。不过遗憾的是,事实并非如此。我们可以看看如下show()的源代码:

public void show() {if (mNextView == null) {throw new RuntimeException("setView must have been called");}INotificationManager service = getService();String pkg = mContext.getPackageName();TN tn = mTN;try {//  将当前Toast加入到Toast队列service.enqueueToast(pkg, tn, mDuration);} catch (RemoteException e) {// Empty}
}

正如 service.enqueueToast(pkg, tn, mDuration);这一句所说,我们只是通过.show()来把当前Toast加入到Toast队列中, 再由系统根据Toast队列来显示Toast信息提示框, 并不是去显示当前Toast。因为我们不能去直接控制系统中要做的事,所以我们不能再去调用show()方法了。如果不调用show()方法,我们知道,Toast是不会显示出来的。所以,这里我们就要去自己写一个方法让我们当前的Toast显示出来。我们是用反射来解决这个问题的。关键代码如下:

private Object mTN;private Method mShow;private Method mHide;private Field mViewFeild;private View mLayout;private HomeKeyEventBroadCastReceiver receiver; // 监听HOME键/*** 开启永不消失的Toast*/private void showForeverToast() {mLayout = getLayoutInflater().inflate(R.layout.newtoast, null);Toast toast = new Toast(getApplicationContext());toast.setGravity(Gravity.FILL, 0, 0);toast.setDuration(0);Field field = null;try {field = toast.getClass().getDeclaredField("mTN");field.setAccessible(true);mTN = field.get(toast);mShow = mTN.getClass().getDeclaredMethod("show");mHide = mTN.getClass().getDeclaredMethod("hide");mViewFeild = mTN.getClass().getDeclaredField("mNextView");mViewFeild.setAccessible(true);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (NoSuchMethodException e1) {e1.printStackTrace();}show(mLayout); // 显示Toast}

显示Toast的代码如下:

private void show(View layout) {try {mViewFeild.set(mTN, layout);mShow.invoke(mTN, new Object[] {});} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

隐藏Toast的代码如下:

private void hide(View layout) {try {mHide.invoke(mTN, new Object[] {});} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

通过以上的代码就可以让我们的Toast全屏显示和永不消失了。

下面我就来说说关于拦截Home键的方法。之前我也是找了很多关于拦截和屏蔽Home键的方法,自己都试过,根本行不通(当然也可能是我自己的问题,如果大家有什么好的方法,可以给我留言)。所以,这里我就取了个巧(其实是一个假的拦截和屏蔽),我是采用了当我们点击Home键的时候,退回桌面,同时程序转入后台,一定时间后程序再从后台转入前台。关键代码正下:

class HomeKeyEventBroadCastReceiver extends BroadcastReceiver {static final String SYSTEM_REASON = "reason";static final String SYSTEM_HOME_KEY = "homekey"; // home keystatic final String SYSTEM_RECENT_APPS = "recentapps"; // long home key@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {String reason = intent.getStringExtra(SYSTEM_REASON);if (reason != null) {if (reason.equals(SYSTEM_HOME_KEY)) {// 从桌面启动app(利用RestartService过渡)Intent newIntent = new Intent();newIntent.setClass(context, RestartService.class);context.startService(newIntent);showToastByHome();} else if (reason.equals(SYSTEM_RECENT_APPS)) {hideToastByHome();}}}}}

点击Home键后,弹出全屏的Toast.5秒后又自动消失:

private void showToastByHome() {showForeverToast(); // 显示全屏的Toastif (mThread == null || !mThread.isAlive() || mThread.isInterrupted()) {mThread = new Thread() {@Overridepublic void run() {try {sleep(5000);hide(mLayout);} catch (InterruptedException e) {e.printStackTrace();}}};mThread.start();}}

看上面的第一段代码,可以很容易地发现我是在退回桌面的同时,跳转到一个RestartService,这个Service会在5秒后再进行一次跳转(从Service跳转程序的前台Activity),这样就实现了假的拦截Home了,如果亲们对这个拦截Home键的功能比较急,要求又不是很苛刻的话,可以先用这样的方法顶一下。而Service中的代码也很简单,几句话,如下:

public void onStart(Intent intent, int startId) {Intent newIntent = new Intent(getApplicationContext(), MainActivity.class);newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(newIntent);super.onStart(intent, startId);}

这里是本篇博客的工程连接: http://download.csdn.net/detail/u013761665/8015397

本博客参考博文:
Android开发技巧:永不关闭的Toast信息框

Android开发技巧:永不关闭的Toast信息框(修正版)android4.x

Toast的另类应用及另类“拦截”Home键相关推荐

  1. Flutter系列之showDialog拦截返回键

    Flutter中弹出对话框是使用showDialog函数,如果想拦截返回键,不想其点击返回键的时候消失, 就要嵌套一层WillPopScope,示例代码如下: showDialog(context: ...

  2. android4.2 拦截power键,Android 屏蔽Power键 Home键

    2014-04-18 17:22 1557人阅读 评论(0) 收藏 举报 分类: Android(46) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近正在处理工厂测试的功能,里面有个功能 ...

  3. Android变相拦截Home键,使app一直运行在前端

    首先,声明一下楼主不是流氓程序猿,也很痛恨流氓软件.主要是媳妇最近要考试,想让我写个程序把她手机锁一段时间,让她安心看书...好吧主观能动性太差的表现==.于是楼主就琢磨起来怎么能够实现这样的需求. ...

  4. android 拦截音量键,Android 音量键增大减小捕捉

    Android 音量键增大减小捕捉: @Override public boolean onKeyDown( int keyCode, KeyEvent event) { // TODO Auto-g ...

  5. Android拦截HOME键

    Android拦截按键 文章目录 Android拦截按键 Android拦截HOME按键 Android拦截BACK按键 Android拦截HOME按键 拦截HOME按键需要修改Android的fra ...

  6. ApiCloud拦截返回键

    api.addEventListener({name:"keyback" },function(ret,err){alert("点返回键了") })

  7. 另类架构师:在国企涂肥皂水、考研被调剂、在阿里跟十八罗汉当同事……

    导读:鲁迅曾说:这世上本没有路,走的人多了,也便成了路.作为一个非计算机专业的程序员,我的架构师成长之路也许有点另类,但是另类的路走的人多了,也就成了寻常的路. 因为,这世上本没有路. 作者:李智慧 ...

  8. 另类数据的全面解析与24种场景应用!

    什么是另类数据? 另类数据是投资过程中使用的非传统数据,它使得越来越多以前无法收集的信息变成了可以分析的数据 ,而从这些杂乱无章的信息中找到规律的能力也变得无比强大. 另类数据是用于金融交易的非传统性 ...

  9. 白鹭张晨樱:认知的边界,另类的独特

    量化投资与机器学习微信公众号,是业内垂直于量化投资.对冲基金.Fintech.人工智能.大数据等领域的主流自媒体.公众号拥有来自公募.私募.券商.期货.银行.保险.高校等行业30W+关注者,荣获202 ...

最新文章

  1. gitignore完整使用方法
  2. 建行优盾制单重要还是复核重要_注会成绩复核可行吗?纠结要不要申请!
  3. 中移动完成透镜天线远距覆盖和降本增效试点
  4. Nginx----进阶
  5. K linux 部署手机 centos6.5
  6. 母婴群如何引流?孕妈群如何引流?母婴群怎么运营好?
  7. 7-5 约分最简分式
  8. kubectl config 命令
  9. ICMPv6与NDP
  10. threejs 实现场景围绕鼠标缩放,而不是默认的场景缩放中心
  11. json文件的读与写
  12. 噩梦射手(SurvivalShooter)教程(五)
  13. Hadoop3.x端口变化
  14. 现代C++新特性 强枚举类型(PC浏览效果更佳)
  15. 移位运算(左移和右移)
  16. 二叉搜索树(平衡二叉搜索树)
  17. Exchange问题处理:Exchange server OAB 脱机地址簿下载失败常见解决方法
  18. C++基础:[enter] Ctrl+Z [enter] 问题及\n输入输出问题
  19. 南航计算机硬件实验,南航计硬实验四数据块移动实验报告.doc
  20. 基于JAVA的志愿者管理系统(最新)

热门文章

  1. 基于SpringBoot和Vue的个人博客系统
  2. 135. 分发糖果(贪心算法)
  3. 【Flask】创建一个蓝图
  4. HTML5中各种标签总结(多媒体标签)
  5. optee对std smc的处理的详解
  6. 查看mysql 内核_如何查看和更新数据库内核小版本
  7. 【模拟】P1067 多项式输出
  8. vi和vim的基础使用
  9. 项目: 用封装的方法实现飞机大战游戏
  10. MySQL之无限级分类表设计