最近正在处理工厂测试的功能,里面有个功能测试是前面板按键功能测试。需求中要求:在按每个前面板按键时,要修改UI中每个对应按键的颜色。其中有两个键Home键,和Power键,程序需要对这两个按键进行拦截,网上查了一些资料,现归纳一下常用的几种方式。

第一种方式:android 对home键的监听(针对2.3以前的版本有效)

1.在manifes文件中添加权限

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

2.重写onAttachedToWindow方法

    @Override    public void onAttachedToWindow()    {        this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);        super.onAttachedToWindow();    }

3.重写onkeyDown方法

@Override    public boolean onKeyDown(int keyCode, KeyEvent event)    {        switch (keyCode)        {            case KeyEvent.KEYCODE_HOME:                //TODO 1:home key                break;                        case KeyEvent.KEYCODE_POWER:                //TODO 2:power key                break;        }        return super.onKeyDown(keyCode, event);    }    

测试结果:2.3之前的版本没有去测试,在手中4.0版本中,程序无法运行。出错打印:

java.lang.IllegalArgumentException: Window type can not be changed after the window is added

与重写onAttachedToWindow方法有关,没有再去调试,放弃该方法。

第二种方法:通过检测log,根据log判断是否有点击Home键

此种方式只能判断是否点击Home键,不能真正的拦截Home的功能。

    private boolean isTesting = true;        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()));                    while ((line = reader.readLine()) != null)                    {                        if (line.indexOf("android.intent.category.HOME") > 0)                        {                            isTesting = false;                            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)        {            Log.i(TAG, "Home key press");            // do something here        };    };

第三种方法:修改Framework

这里需要修改的文件为PhoneWindowManager,

文件位置:frameworks\base\policy\src\com\android\internal\policy\impl

这里我们重点关注:public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn)这个方法,这里对Home键,Power键做了处理,使得我们在应用程序中无法获得两个键的键值,即使通过各种方法获得了键值,也无法屏蔽该功能。因此,决定将部分逻辑放在这个文件中处理。在方法中找到Power键对应的case,添加我的处理逻辑。

 case KeyEvent.KEYCODE_POWER: {                int powerStatus = 0;                try                {                    powerStatus = android.provider.Settings.System.getInt(                        mContext.getContentResolver(), "boot_default_channel_open");                }                catch (Exception e)                {                    powerStatus = 0;                    e.printStackTrace();                }                if(powerStatus ==1)                {//send power key broadcast.Intent powerIntent =new Intent("com.soctt.dvb.factorytest.keytest");mContext.sendBroadcast(powerIntent);                    // forbid power key function.                    return 0;                }……break

编译镜像,烧录镜像。好的,镜像完成了,下面就是测试修改的效果了。写一个测试程序。

public class MainActivity extends Activity{        private static final String TAG = "MainActivity";        public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                registReceiver();        // listenerHome();    }        @Override    protected void onStart()    {        super.onStart();        saveSettings();        echoSettings();    }        private void registReceiver()    {        IntentFilter filter = new IntentFilter();        filter.addAction("com.pbi.dvb.factorytest.keytest");        registerReceiver(keyReceiver, filter);    }        private BroadcastReceiver keyReceiver = new BroadcastReceiver()    {        public void onReceive(Context context, Intent intent)        {            Log.w(TAG, "-----Recevie the broadcast!!--------" + intent.getFlags());        }    };}
运行测试:

此时,我们在接收到广播后,就可以处理自己的业务逻辑了。


参考内容:http://blog.csdn.net/myarrow/article/details/8143717

http://blog.csdn.net/goleftgoright/article/details/7756111

更多相关文章

  1. Android软件推荐(1)
  2. Android(安卓)Studio实现一个点餐系统
  3. 如何透過Android模擬器刪除不要的ap程式!!
  4. Android打造通用的下拉刷新组件
  5. 没错,你没有看错,博客园Android客户端开源了!
  6. 为开发者摆平 Android(安卓)碎片化,TestObject 融资百万美元
  7. 解决:eclipse导入android时工程下没有R文件的问题,以及style.xml文
  8. Android中app卡顿原因分析(ios顺滑)
  9. Android(安卓)OOM介绍及分析方法

随机推荐

  1. Android(安卓)Studio引用另一个模块modul
  2. android 数据封装类-Parcelable 使用和学
  3. Android的SurfaceView使用
  4. 关于EditText的android:maxLength属性的
  5. 【Android(安卓)音视频开发打怪升级:FFmpe
  6. Android设备上的简易备忘录(Memo) 具有闹
  7. 【Android每周专题】横竖屏切换和Activit
  8. Broadcast Receiver广播接收者详细解析
  9. Android(安卓)AndroidManifest 清单文件
  10. Kotlin在Android工程中的应用