Android2.3 Home-Key、Activity

阅读博客声明:


1) 实例是在 Activity 里面完成,不是 View 或者其它 android 组件。


2) 实例是在 android2.3 下验证的,没有考虑其它版本。


3) 这种方法在 android4.0 上可能不正确,4.0 的改动比较大,鬼才知道 google 怎么想的?!


4) 寻找一种学习方法,不要单纯为了问题而ctrl-cv,过几天你自己都不知道问题是怎么解决的!


你在网上搜索 "屏蔽 Home 按键",能搜索出很多优秀的文章,但是我个人还是有点其它的看法。


项目里面的确有这个需求,可以借鉴一下。


屏蔽 Home 按键,至少做到两点:


1) 重写 onAttachedToWindow


2)重写 onKeyDown


实例代码:


package mark.zhang;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.widget.Toast;

public class Main extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d("mark", "onCreate-- ");
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
        Log.d("mark", "onAttachedToWindow-- ");
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d("mark", "onDetachedFromWindow-- ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("mark", "onDestroy-- ");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_HOME:
                    Toast.makeText(this, "home key is pressed", 1).show();
                    break;
            }
        }
        return super.onKeyDown(keyCode, event);
    }
}


思考问题:


a) 这些回调方法调用顺序,如何?


b) 为什么要重写 onAttachedToWindow 方法,在 onCreate 中怎么样?


c) 为什么要使用 WindowManager.LayoutParams.TYPE_KEYGUARD,神马意思?


解答问题:


a) 直接运行程序之后退出,你会看到




如果你有兴趣,可以把 activity 的 7 个生命周期方法都加上,然后一探究竟:




b) 很遗憾的告诉你,不行!不信,你可以试一试!


onAttachedToWindow 调用时机:

activity 的主窗口连接或者附属到 window manager,就会去调用该方法。


文档原文描述:

Called when the main window associated with the activity has been attached to the window manager.


从另一个角度说明,onCreate方法(或者 onStart、onResume,已试过)结束时候,activity 的主窗口还没有附属到 window manager。


如果你想知道,onAttachedToWindow 方法被谁调用了,究竟是怎么调用的,教你几个方法,用哪个随你:


方法1) 在源码里面搜索,呵呵,这是噩梦!


方法2) 自己写个方法去观察,这里,我给出自己的实现代码:


 public void findCaller() {
        final Throwable mThrowable = new Throwable();
        final StackTraceElement[] elements = mThrowable.getStackTrace();
        final int len = elements.length;
        StackTraceElement item = null;
        for (int i = 0; i < len; i++) {
            item = elements[i];
            System.out.println("Position: " + 
                    item.getClassName() + "." + item.getMethodName()
                    + " ---" + item.getLineNumber() + " line");
        }
 }

那麽在 onAttachedToWindow 方法里面调用 findCaller 就可以看出端倪。




没错,与 PhoneWindow 有关系,请参考:

http://blog.csdn.net/androidbluetooth/article/details/6692770

Android杂谈--Activity、Window、View的关系


c) 这个问题要从源码着手


2.3/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWidowManager.java


在 interceptKeyBeforeDispatching 方法里面出现两个常量:


indowManager.LayoutParams.TYPE_KEYGUARD

indowManager.LayoutParams.TYPE_KEYGUARD_DIALOG


那麽,是不是使用 indowManager.LayoutParams.TYPE_KEYGUARD_DIALOG

可以替代 indowManager.LayoutParams.TYPE_KEYGUARD_DIALOG ?????


答案是肯定的。


注意:


1. 这里我没有使用任何权限,有些地方说需要权限(估计是 android2.3 之前版本):

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


2. 如果你是做系统开发的,就根本没有必要这麽做。

你可以修改源码,在用户点击 Home 按键的时候,发送一条广播就可以了。

需要捕获这个按键信息的时候,注册一个 BroadcastReceiver 即可。


附录---src


package mark.zhang;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.widget.Toast;

public class Main extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
        setContentView(R.layout.main);

        Log.d("mark", "onCreate-- ");
    }

    @Override
    protected void onStart() {
        Log.d("mark", "onStart-- ");
        super.onStart();
    }

    @Override
    protected void onResume() {
        Log.d("mark", "onResume-- ");
        super.onResume();
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        Log.d("mark", "onAttachedToWindow-- ");
        findCaller();
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d("mark", "onDetachedFromWindow-- ");
    }

    @Override
    protected void onPause() {
        Log.d("mark", "onPause-- ");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d("mark", "onStop-- ");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("mark", "onDestroy-- ");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_HOME:
                    Toast.makeText(this, "home key is pressed", 1).show();
                    break;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    public void findCaller() {
        final Throwable mThrowable = new Throwable();
        final StackTraceElement[] elements = mThrowable.getStackTrace();
        final int len = elements.length;
        StackTraceElement item = null;
        for (int i = 0; i < len; i++) {
            item = elements[i];
            System.out.println("Position: " + item.getClassName() + "." + item.getMethodName()
                    + " ---" + item.getLineNumber() + " line");
        }
    }
}







©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页