0
点赞
收藏
分享

微信扫一扫

关于设置全屏后与屏蔽Home键的冲突问题,盛传的几种做法,未解决!

鱼满舱 2022-05-16 阅读 44

(安卓4.2及以前版本)关于设置全屏后与屏蔽Home键的冲突问题,盛传的几种做法,未解决!现在分享给有兴趣的亲研究研究。


1、实现全屏下屏蔽Home键,代码如下


  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState)  
  3. {  
  4.     super.onCreate(savedInstanceState);  
  5.     requestWindowFeature(Window.FEATURE_NO_TITLE);  
  6.     this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  7.             WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  8.     setContentView(R.layout.path_main_layout);  
  9. }  



  1. public void onAttachedToWindow()  

  2. {  

  3.     this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  

  4.     super.onAttachedToWindow();  

  5. }  


  1. public boolean onKeyDown(int keyCode, KeyEvent event)  

  2. {  

  3.     LogUtils.log("MainActivity""onKeyDown: " + keyCode);  

  4.     switch (keyCode)  

  5.     {  

  6.         case KeyEvent.KEYCODE_HOME:  

  7.         {  

  8.             LogUtils.log("MainActivity""HOME");  

  9.             return true;  

  10.         }  

  11.         case KeyEvent.KEYCODE_BACK:  

  12.             LogUtils.log("MainActivity""BACK");  

  13.             return true;  

  14.         case KeyEvent.KEYCODE_CALL:  

  15.             return true;  

  16.         case KeyEvent.KEYCODE_SYM:  

  17.             return true;  

  18.         case KeyEvent.KEYCODE_STAR:  

  19.             return true;  

  20.         case KeyEvent.KEYCODE_POWER:  

  21.             LogUtils.log("MainActivity""POWER");  

  22.             return true;  

  23.     }  

  24.     return super.onKeyDown(keyCode, event);  

  25. }  





以上代码在点击Power键使屏幕进入睡眠状态,然后再次唤醒后,会是状态栏重新出现,全屏效果被破坏。


问题解决:

解决一、

通过分析,造成全屏被破坏的原因是以下代码,


  1. this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  

通过日志可以看到初始化时type为2,,再将Type设置为TYPE_KEYGUARD后,全屏效果就失效了,设想在onPause回调中把type设置成初始状态,然后唤醒时在onResume中重新setType();


  1. <span style="font-family:Arial,Helvetica,sans-serif">this.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION);</span>  

然后在onResume中重新设置



  1. this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  



以上操作实现的是在唤醒后,全屏依然存在,但是Home键没有被屏蔽掉,好像全屏和Home键之间是互相排斥的,可以破坏对方。


解决二、

测试使用onWindowFocusChanged()来取代onResume()和onPause()


  1. public void onWindowFocusChanged(boolean hasFocus)   
  2. {    
  3.     LogUtils.log("MainActivity",   
  4.             "onWindowFocusChanged(): " +hasFocus);  
  5.     WindowManager.LayoutParams lp = new WindowManager.LayoutParams();    
  6.     if(hasFocus)  
  7.     {  
  8.         lp.type = WindowManager.LayoutParams.TYPE_KEYGUARD ;    
  9.         lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;  
  10.     }  
  11.     this.getWindow().setAttributes(lp);    
  12.     LogUtils.log("MainActivity",   
  13.             "onWindowFocusChanged().type: " +getWindow().getAttributes().type);  
  14.     LogUtils.log("MainActivity",   
  15.             "onWindowFocusChanged().flags: " +getWindow().getAttributes().flags);  
  16. }  

结果依然无效。两者还是冲突。



解决三、

使用新的方式来屏蔽Home键。

1).首先添加权限


  1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  
  2. <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />  

2).在Activity类中声明函数和成员


  1. Runnable mDisableHomeKeyRunnable = new Runnable() {  
  2. @Override  
  3. public void run() {  
  4. disableHomeKey();  
  5. }  
  6. };  
  7. Handler mHandler = new Handler();  
  8. public  void  disableHomeKey()  
  9. {  
  10. this.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);  
  11. }  

3).在onCreate中调用


  1. mHandler.postDelayed(mDisableHomeKeyRunnable,200);  

以上的实现方法还是没有解决根本问题,唤醒后依然出现冲突。



解决四、  

1).自定义Application


  1. package com.houny.testhomekey.application;  
  2.  import java.util.HashMap;  
  3.  import java.util.Iterator;  
  4.  import java.util.Map;  
  5.  import android.app.Activity;  
  6.  import android.app.Application;  
  7. public class ManageApplication extends Application {  
  8.     private HashMap<String, Boolean> mapActivity = new HashMap<String, Boolean>();// 用于存储activity对应的激活状态  
  9.     private static ManageApplication application = null;  
  10.     @Override  
  11.     public void onCreate() {  
  12.         super.onCreate();  
  13.         application = this;  
  14.     }  
  15.     /** 
  16.      * 把Activity和状态放到List中管理 
  17.      *  
  18.      * @param activity 
  19.      * @param isActivitied 
  20.      */  
  21.     public void addActivityStatus(Activity activity, boolean isAlive) {  
  22.         if (mapActivity.containsKey(activity.getClass().getName())) {  
  23.             mapActivity.remove(activity.getClass().getName());  
  24.             mapActivity.put(activity.getClass().getName(), isAlive);  
  25.         } else {  
  26.             mapActivity.put(activity.getClass().getName(), isAlive);  
  27.         }  
  28.     }  
  29.     /** 
  30.      * 判断是否有Activity是活动状态 
  31.      *  
  32.      * @return 
  33.      */  
  34.     public boolean isAllActivityAlive() {  
  35.         boolean res = false;  
  36.         Iterator iter = mapActivity.entrySet().iterator();  
  37.         while (iter.hasNext()) {  
  38.             Map.Entry entry = (Map.Entry) iter.next();  
  39.             Object key = entry.getKey();  
  40.             boolean value = (Boolean) entry.getValue();  
  41.             if (value) {  
  42.                 return true;  
  43.             }  
  44.         }  
  45.         return res;  
  46.     }  
  47.     public static ManageApplication getInstance() {  
  48.         return application;  
  49.     }  
  50. }  

  2).在 Mainfest中把Application设成自定义的Application


  1. <application  
  2.         android:name="com.houny.testhomekey.application.ManageApplication"  
  3.         android:allowBackup="true"  
  4.         android:icon="@drawable/ic_launcher"  
  5.         android:label="@string/app_name"  
  6.         android:theme="@style/AppTheme" >  

 3).在每一个Activity中都做如下操作


   (1)、在OnCreat()中getApplication


  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     application = (ManageApplication) this.getApplication();  
  5.     setContentView(R.layout.activity_main);  
  6.     Log.e("Status""OnCreate");  
  7.     findViewsById();  
  8.     setViewsListener();  
  9. }  

   (2)、重写OnResume(),增加当前Activity的状态为true激活状态


  1. @Override  
  2.     protected void onResume() {  
  3.         Log.e("Status""onResume");  
  4.         application.addActivityStatus(MainActivity.thistrue);  
  5.         super.onResume();  
  6.     }  

   (3)、重写OnStop(),更改当前Activity的状态为false非激活状态并判断所有的Activity是否都处于非激活状态


  1. @Override  
  2.     protected void onStop() {  
  3.         Log.e("Status""onStop");  
  4.         application.addActivityStatus(MainActivity.thisfalse);  
  5.         boolean alived = application.isAllActivityAlive();  
  6.         Log.e("All Activity Status", alived + "");  
  7.         if(!alived){  
  8.             //TODO 想要进行的操作  
  9.         }  
  10.         super.onStop();  
  11.     }  


解决五、

1).监听日志来屏蔽home


  1.  protected void onResume()  
  2.     {  
  3.         super.onResume();  
  4.         isTesting=true;  
  5.         new CatchLogThread().start();  
  6.     }  
  7. class CatchLogThread extends Thread {    
  8.      @Override    
  9.       public void run() {    
  10.           Process mLogcatProc = null;    
  11.           BufferedReader reader = null;    
  12.            String line;    
  13.            while (isTesting) {    
  14.                try {    
  15.                  // 获取logcat日志信息     
  16.                    mLogcatProc = Runtime.getRuntime().exec(new String[] { "logcat""ActivityManager:I *:S" });    
  17.                    reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()),2*1024);    
  18.                    while ((line = reader.readLine()) != null) {    
  19.                        if (line.indexOf("android.intent.category.HOME") > 0) {    
  20.                            isTesting = false;    
  21.                            System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDD");  
  22.                            handler.sendMessage(handler.obtainMessage());     
  23.                          Runtime.getRuntime().exec("logcat -c");//删除日志     
  24.                           break;    
  25.                       }     
  26.                   }    
  27.                } catch (Exception e) {    
  28.                    e.printStackTrace();    
  29.                }    
  30.            }    
  31.       }    
  32.     };    
  33. Handler handler = new Handler() {    
  34.        public void handleMessage(android.os.Message msg) {  
  35.            startActivity(new Intent(MainActivity.this,MainActivity.class));  
  36.            Toast.makeText(MainActivity.this"I Have Home is pressed!!!!!",Toast.LENGTH_LONG).show();  
  37.            System.out.println("Home is Pressed+++++++++++++++++");  
  38.         };     
  39.    };    

2).添加权限


  1. <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>  


解决六、

1).还有使用broadcastreceiver来监听Home按钮的



  1. public class HomeButtonReceiver extends BroadcastReceiver  

  2. {  

  3.     @Override  

  4.     public void onReceive(Context context, Intent intent)  

  5.     {  

  6.         if(intent.getAction().equals(Intent.CATEGORY_HOME))  

  7.         {  

  8.             Log.i("HomeButtonReceiver""onReceive");  

  9.             //操作  

  10.         }  

  11.     }  

  12. }  





举报

相关推荐

0 条评论