美文网首页
为特定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