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

本文详细介绍了如何在Android应用中实现全屏下屏蔽Home键的效果,并解决了唤醒后全屏效果被破坏的问题。通过自定义Application、监听日志、使用BroadcastReceiver等方法,实现了在唤醒后全屏依然存在的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

	@Override
 protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.path_main_layout);

	}
	public void onAttachedToWindow()
	{
		this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
		super.onAttachedToWindow();
	}
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		LogUtils.log("MainActivity", "onKeyDown: " + keyCode);
		switch (keyCode)
		{
			case KeyEvent.KEYCODE_HOME:
			{
				LogUtils.log("MainActivity", "HOME");
				return true;
			}
			case KeyEvent.KEYCODE_BACK:
				LogUtils.log("MainActivity", "BACK");
				return true;
			case KeyEvent.KEYCODE_CALL:
				return true;
			case KeyEvent.KEYCODE_SYM:
				return true;
			case KeyEvent.KEYCODE_STAR:
				return true;
			case KeyEvent.KEYCODE_POWER:
				LogUtils.log("MainActivity", "POWER");
				return true;
		}
		return super.onKeyDown(keyCode, event);
	}



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


问题解决:

解决一、

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

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

然后在onResume中重新设置

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

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


解决二、

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

	public void onWindowFocusChanged(boolean hasFocus) 
	{  
		LogUtils.log("MainActivity", 
				"onWindowFocusChanged(): " +hasFocus);
		WindowManager.LayoutParams lp = new WindowManager.LayoutParams();  
	    if(hasFocus)
	    {
	    	lp.type = WindowManager.LayoutParams.TYPE_KEYGUARD ;  
	    	lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
	    }
	    this.getWindow().setAttributes(lp);  
	    LogUtils.log("MainActivity", 
	    		"onWindowFocusChanged().type: " +getWindow().getAttributes().type);
	    LogUtils.log("MainActivity", 
	    		"onWindowFocusChanged().flags: " +getWindow().getAttributes().flags);
	}

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


解决三、

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

1).首先添加权限

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

2).在Activity类中声明函数和成员
Runnable mDisableHomeKeyRunnable = new Runnable() {

@Override
public void run() {
disableHomeKey();

}
};

Handler mHandler = new Handler();

public  void  disableHomeKey()
{
this.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}

3).在onCreate中调用
mHandler.postDelayed(mDisableHomeKeyRunnable,200);

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


解决四、  

1).自定义Application

 package com.houny.testhomekey.application;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import android.app.Activity;
  import android.app.Application;
  
 public class ManageApplication extends Application {
     private HashMap<String, Boolean> mapActivity = new HashMap<String, Boolean>();// 用于存储activity对应的激活状态
     private static ManageApplication application = null;
 
     @Override
     public void onCreate() {
         super.onCreate();
         application = this;
     }
 
     /**
      * 把Activity和状态放到List中管理
      * 
      * @param activity
      * @param isActivitied
      */
     public void addActivityStatus(Activity activity, boolean isAlive) {
 
         if (mapActivity.containsKey(activity.getClass().getName())) {
             mapActivity.remove(activity.getClass().getName());
             mapActivity.put(activity.getClass().getName(), isAlive);
         } else {
             mapActivity.put(activity.getClass().getName(), isAlive);
         }
 
     }
 
     /**
      * 判断是否有Activity是活动状态
      * 
      * @return
      */
     public boolean isAllActivityAlive() {
         boolean res = false;
         Iterator iter = mapActivity.entrySet().iterator();
         while (iter.hasNext()) {
             Map.Entry entry = (Map.Entry) iter.next();
             Object key = entry.getKey();
             boolean value = (Boolean) entry.getValue();
             if (value) {
                 return true;
             }
         }
 
         return res;
     }
 
     public static ManageApplication getInstance() {
         return application;
     }
 }

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

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

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

   (1)、在OnCreat()中getApplication

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        application = (ManageApplication) this.getApplication();
        setContentView(R.layout.activity_main);

        Log.e("Status", "OnCreate");
        findViewsById();
        setViewsListener();
    }
   (2)、重写OnResume(),增加当前Activity的状态为true激活状态
@Override
    protected void onResume() {
        Log.e("Status", "onResume");
        application.addActivityStatus(MainActivity.this, true);
        super.onResume();
    }
   (3)、重写OnStop(),更改当前Activity的状态为false非激活状态并判断所有的Activity是否都处于非激活状态
@Override
    protected void onStop() {
        Log.e("Status", "onStop");
        application.addActivityStatus(MainActivity.this, false);
        boolean alived = application.isAllActivityAlive();
        
        Log.e("All Activity Status", alived + "");
        
        if(!alived){
            //TODO 想要进行的操作
        }
        super.onStop();
    }

解决五、

1).监听日志来屏蔽home

 protected void onResume()
    {
        super.onResume();
        isTesting=true;
        new CatchLogThread().start();
    }
class CatchLogThread extends Thread {  
     @Override  
      public void run() {  
          Process mLogcatProc = null;  
          BufferedReader reader = null;  
           String line;  
           while (isTesting) {  
               try {  
                 // 获取logcat日志信息   
                   mLogcatProc = Runtime.getRuntime().exec(new String[] { "logcat", "ActivityManager:I *:S" });  
                   reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()),2*1024);  
                   while ((line = reader.readLine()) != null) {  
                       if (line.indexOf("android.intent.category.HOME") > 0) {  
                           isTesting = false;  
                           System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDD");
                           handler.sendMessage(handler.obtainMessage());   
                         Runtime.getRuntime().exec("logcat -c");//删除日志   
                          break;  
                      }   
                  }  
               } catch (Exception e) {  
                   e.printStackTrace();  
               }  
           }  
      }  
    };  
Handler handler = new Handler() {  
       public void handleMessage(android.os.Message msg) {
           
           startActivity(new Intent(MainActivity.this,MainActivity.class));
           Toast.makeText(MainActivity.this, "I Have Home is pressed!!!!!",Toast.LENGTH_LONG).show();
           System.out.println("Home is Pressed+++++++++++++++++");
        };   
   };  

2).添加权限

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

解决六、

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

public class HomeButtonReceiver extends BroadcastReceiver
{
	@Override
	public void onReceive(Context context, Intent intent)
	{
		if(intent.getAction().equals(Intent.CATEGORY_HOME))
		{
			Log.i("HomeButtonReceiver", "onReceive");
			//操作
		}
	}

}

未实现。。。。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值