美文网首页
为特定app拦截android物理按键功能

为特定app拦截android物理按键功能

作者: Ed_Lannister | 来源:发表于2019-06-24 17:33 被阅读0次

    1.首先在

    xref: /frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
    

    中的private int interceptKeyBeforeQueueing接口中进行BACK分发事件的拦截

     if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
                if(Settings.System.getInt(mContext.getContentResolver(),"vr_htc_wave_apk_running_state",0) == 1){
                    if(event.getAction() == KeyEvent.ACTION_DOWN){
                        Slog.i(TAG," htc wave apk is running, process back key down!!!");
                        Settings.System.putInt(mContext.getContentResolver(),"vr_to_htc_wave_oem_key_event",101);
                    }
                    if(event.getAction() == KeyEvent.ACTION_UP){
                        Slog.i(TAG," htc wave apk is running, process back key up!!!");
                        Settings.System.putInt(mContext.getContentResolver(),"vr_to_htc_wave_oem_key_event",100);
                    }
                    return 0;
                }
            }
    

    此时按键事件会出储存在Setting中ContentResolver中

    2.然后做个服务接收这个事件,主要是创建一个class SettingsValueChangeContentObserver extends ContentObserver 对象,然后在对象的onChange函数里面对事件进行处理

    package com.qiyi.vr.wave.oemservice;
    
    import android.app.ActivityManager;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.Looper;
    import android.os.RemoteException;
    import android.util.Log;
    
    import vive.wave.vr.oem.lib.IVROEMService;
    import android.view.KeyEvent;
    import android.app.Instrumentation;
    import android.provider.Settings;
    import android.os.Handler;
    import android.database.ContentObserver;
    import android.net.Uri;
    import android.widget.Toast;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class WaveOEMService extends Service {
        private static final String TAG = "WaveOEMService";
        private static final int HEADSET_BACK_KEY_UP_EVENT                  = 100;
        private static final int HEADSET_BACK_KEY_DOWN_EVENT                = 101;
        private WaveOEMServiceApi mServiceApi;
        private SettingsValueChangeContentObserver mContentOb;
    
        private static final boolean DEBUG = true;
        volatile private static int mTimeCount = 0;
        
        public WaveOEMService() {
            Log.d(TAG,"Constructor");
            mServiceApi = new WaveOEMServiceApi(this);
            mContentOb = new SettingsValueChangeContentObserver();
        }
        
        //observer headset key event: 100: back key up; 101:back key down; 
        class SettingsValueChangeContentObserver extends ContentObserver {
            public SettingsValueChangeContentObserver() {
                super( new Handler());
            }
            public void onChange(boolean selfChange, Uri uri) {
                super.onChange(selfChange, uri);
                int headsetKeyEvent = (Settings.System.getInt(getContentResolver(), "vr_to_htc_wave_oem_key_event",0));
                if(DEBUG) {
                    Log.d(TAG, "headsetKeyEvent keyevent = " + headsetKeyEvent);
                }
                if(headsetKeyEvent == HEADSET_BACK_KEY_DOWN_EVENT){
                    //process headset back key down
                }else if(headsetKeyEvent == HEADSET_BACK_KEY_UP_EVENT){
                        //mTimeCount +=1;这里的mTimeCount作为一个计数器,类似强指针,来根据3秒内进入次数来进行不同的逻辑
                        if (mTimeCount == 0) {
                            mTimeCount += 1;
                            Toast mtoast = Toast.makeText(getApplicationContext() ,"再按一次BACK键即退出当前应用", Toast.LENGTH_LONG);
                            showMyToast(mtoast, 3*1000);
                            new ThreadSetmTimeCount().start();
                        } else if (mTimeCount >= 1) {
                            mServiceApi.finishVRAP(false);
                            mTimeCount = 0;
                        }
                }
            }
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            getContentResolver().registerContentObserver(Settings.System.getUriFor("vr_to_htc_wave_oem_key_event"),false, mContentOb);
        }
        @Override
        public void onDestroy() {
            super.onDestroy();
            getContentResolver().unregisterContentObserver(mContentOb);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            boolean ret = super.onUnbind(intent);
            return ret;
        }
    //service中控制toast持续时间的函数
        public void showMyToast(final Toast toast, final int cnt) {
            final Timer timer =new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    toast.show();
                }
            },0,3000);
    
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    toast.cancel();
                    timer.cancel();
                }
            }, cnt );
        }
    //三秒后重置计数器的线程,这里如果不另起线程会出现很多异常现象
        public class ThreadSetmTimeCount extends Thread {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (Exception e){
                    Log.d(TAG, "Edward exception");
                }
                mTimeCount = 0;
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:为特定app拦截android物理按键功能

          本文链接:https://www.haomeiwen.com/subject/opgoqctx.html