Android中捕获Home事件的终极解决方案
本文转自http://www.alnton.com/?p=128
Android设计者处于安全考虑,那个home键在应用层是捕获不到的,只有修改底层的代码才可以获取其事件监听,但是修改底层对于应用开发者来说有点麻烦,那如何在Activity层监听到home键哪?
先禁止Home键,再在onKeyDown里或者dispatchKeyEvent处理按键值,点击Home键的时候就把程序最小化,或者随你的需求。
首先第一步:
加权限禁止Home键
<uses-permission android:name=”android.permission.DISABLE_KEYGUARD” />
大家不要以为添加这个权限后,所有的Activity的Home键都不可以用了,反而添加这个权限后,跟不添加是一样的效果,就是所有的Activity的Home键都没有禁止,如果你想对某个Activity禁止Home的事件,那么你只需要在某个Activity中加上此方法:
@Override public void onAttachedToWindow() { this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); super.onAttachedToWindow(); }
这个时候,此Activity的Home键才被禁止掉,那么在此Activity中做如下操作,即可最小化应用,或者你自己添加需求的代码。
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_HOME) { // 最小化应用 Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_HOME); startActivity(intent); return true; } return super.onKeyDown(keyCode, event); }
呵呵,至此,我高兴的很,屁颠屁颠的去测试了,先用模拟器测试没有问题,再用真机测试,我去,问题又出现了,Home事件截获不到,这是为什么啊?大家不要急,听我慢慢道来。在2.2以前的模拟器用上述方法是没有问题,但是从3.0开始后的模拟器就不行了包括真机。反正我用了几款机子测试是不行的,哪如何解决此问题哪?
大家都知道点击Home触发onPause、onStop这两个方法,在模拟器测试都触发,但是一旦到真机测试有些机子都触发,但是有些机子就不触发onStop,或者如果你安装了360软件后,一般都不触发,当你从通知栏拉下后在点击又触发了onStop所以我们一般在onPause方法里截获Home事件然后处理,这种截获方式用Logcat。没错就是用Logcat.
终极解决方案开始:
1.首先你要在AndroidManifest.xml添加一项读取系统Log的权限
<!– 允许程序读取系统日志 –> <uses-permission android:name=”android.permission.READ_LOGS” />
2.
/** * “logcat”不用说了吧,我们就是要监听它 * “ActivityManager” 表示监听的Tag 这里以上面点击按钮输出的LOG信息为例。 * “I”表示监听的Log类型,当然这里还可以写其它类型 。VERBOSE(v) 、DEBUG(d)、 INFO(i)、 WARN(w)、 ERROR(e), 不过须要与监听的与Tag一一对称才可以。 * “*:s”表示监听所有的信息,这里表示只要tag是ActivityManager ,Logcat类型为i 的 所有Log都会被获取到。 * 点击Home时会触发OnPause、onStop但是在某些手机上可能触发onStop延迟或者不触发 */ new Thread(new Runnable() { @Override public void run() { Process logcatProcess = null; BufferedReader bufferedReader = null; try { /** 获取系统logcat日志信息 */ logcatProcess = Runtime.getRuntime().exec(new String[] {“logcat”, “ActivityManager:I *:S”}); bufferedReader = new BufferedReader(new InputStreamReader(logcatProcess.getInputStream())); String line; while ((line = bufferedReader.readLine()) != null) { if (line.indexOf(“cat=[android.intent.category.HOME]“) > 0) { /** 这里可以处理你对点击Home的操作哦 我这里是完全退出应用*/ Session.exit(); } } } catch (Exception e) { e.printStackTrace(); } } }).start();
到这里大家看明白了没。就是监听系统日志。
手机点击HOme的日志是:
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0×10200000 cmp=com.dianxinos.dxhome/com.dianxinos.launcher2.Launcher } from pid 1277
模拟器是:
Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0×10200000 cmp=com.android.launcher/com.android.launcher2.Launcher }
他们的
Level:I
PID:59
Application:system process
Tag:ActivityManager
他们都有一个共同点都有:cat=[android.intent.category.HOME]
呵呵。。。。结束了哦
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端