您的位置:首页 > 移动开发 > Android开发

Android发送模拟按键的方法,以及模拟音量键长按功能的实现。

2017-07-28 11:10 716 查看
这两天找模拟长按音量键的方法,都没有找到合适的,后来发现音量键的长按显示连续加减,其实也是单次按键快速连续的响应事件达到的效果。

所以思路就换了,不再纠结keyaction = KeyEvent.FLAG_LONG_PRESS ,而是想办法在按下按键的时候开始计时发送消息,现在设置为100ms发送一次按键消息。

效果就出现了。直接贴上源码,功能也不复杂。布局文件就不贴了,很简单,就是几张图片的布局监听。需要注意的是,千万不要在onKeyUp中去做耗时的操作,因为,代码会先响应松开事件,如果耗时操作的话,可能会执行不到,明智的做法当然都是在按键处理监听时发送消息出来,然后接下来就随意操作了!

package com.cultraview.onekeysetting;

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;

import android.hardware.input.InputManager;

public class OneKeySettingMainActivity extends Activity implements
OnClickListener {
private static final String TAG = "OneKeySettingMainActivity";
private boolean bLongPress = false;
private ImageView iv_power_key, iv_channel_up, iv_channel_down,
iv_volume_plus, iv_volume_minus, iv_exit;
private LinearLayout ll_main_menu;
private int mSelectIndex = 0;
private static final int LONG_PRESS_MSG = 101;
private static final int SHORT_PRESS_MSG = 100;
private static final int TIMES_OVER_MSG = 102;
private int mTotalNums = 0;
private Context mContext;
private long mKeyRemappingSendFakeKeyDownTime;
private int mRepeatCount = 0;
private boolean isTimesUp = false;
private int mCurrentSendKeyCode = 0;
private Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int status = (int) msg.what;
switch (status) {
case LONG_PRESS_MSG:
Log.d(TAG, "-------------long press");
onLongPress();
break;
case SHORT_PRESS_MSG:
Log.d(TAG, "-------------short press");
onShortPress();
break;
case TIMES_OVER_MSG:
longPressTimesOver();
break;
}

}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu_list);
initView();
initData();
}

private void initView() {
ll_main_menu = (LinearLayout) findViewById(R.id.ll_main_menu);
iv_power_key = (ImageView) findViewById(R.id.iv_power_key);
iv_channel_up = (ImageView) findViewById(R.id.iv_channel_up);
iv_channel_down = (ImageView) findViewById(R.id.iv_channel_down);
iv_volume_plus = (ImageView) findViewById(R.id.iv_volume_plus);
iv_volume_minus = (ImageView) findViewById(R.id.iv_volume_minus);
iv_exit = (ImageView) findViewById(R.id.iv_exit);
iv_power_key.setOnClickListener(this);
iv_channel_up.setOnClickListener(this);
iv_channel_down.setOnClickListener(this);
iv_volume_plus.setOnClickListener(this);
iv_volume_minus.setOnClickListener(this);
iv_exit.setOnClickListener(this);

}

private void initData() {
mContext = OneKeySettingMainActivity.this;
iv_power_key.requestFocus();
mTotalNums = ll_main_menu.getChildCount();
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_1) {
bLongPress = true;
Log.d(TAG, "-----------onKeyLongPress long");
/*此处已经可以监听到是否是超过2秒的长按时间了,如果已经判断是长按,则可以发送消息进行事件处理*/
handler.sendEmptyMessage(LONG_PRESS_MSG);
return true;
}
// Just return false because the super call does always the same
// (returning false)
return false;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_1) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
event.startTracking();
if (event.getRepeatCount() == 0) {
Log.d(TAG, "-----------onKeyDown short");
bLongPress = false;
}
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_1) {
if (bLongPress) {
bLongPress = true;
//times over!/*长按按键松开结束的时候需要发送时间到的消息传递给计时器*/
handler.sendEmptyMessage(TIMES_OVER_MSG);
return true;
} else {
bLongPress = false;
handler.sendEmptyMessage(SHORT_PRESS_MSG);
return true;
}
}
return super.onKeyUp(keyCode, event);
}

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.d(TAG, "-------onClick");
onLongPress();
}

private void onShortPress() {
mSelectIndex++;
if (mSelectIndex > mTotalNums - 1) {
mSelectIndex = 0;
}
getFocusView(mSelectIndex).requestFocus();

}

private void onLongPress() {
int keycode = KeyEvent.KEYCODE_POWER;
switch (getCurrentFocus().getId()) {
case R.id.iv_power_key:
keycode = KeyEvent.KEYCODE_POWER;
break;
case R.id.iv_channel_up:
keycode = KeyEvent.KEYCODE_CHANNEL_UP;
break;
case R.id.iv_channel_down:
keycode = KeyEvent.KEYCODE_CHANNEL_DOWN;
break;
case R.id.iv_volume_plus:
keycode = KeyEvent.KEYCODE_VOLUME_UP;
break;
case R.id.iv_volume_minus:
keycode = KeyEvent.KEYCODE_VOLUME_DOWN;
break;
case R.id.iv_exit:
keycode = KeyEvent.KEYCODE_BACK;
break;
}
Log.d(TAG, "-------------keycode:" + keycode);
mCurrentSendKeyCode = keycode;
if(keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_BACK){
keyRemappingSendFakeKeyEvent(keycode);
}else{
/*因为频道和音量需要连续调整,所以需要连续长按发送键值,此时启动计时器,每100ms发送一次键值,可以有视觉连续的效果*/
timerHandler.postDelayed(runnable, 100);
}
}

private void longPressTimesOver(){
timerHandler.removeCallbacks(runnable);
}
private View getFocusView(int index) {
View view = null;
switch (index) {
case 0:
view = iv_power_key;
break;
case 1:
view = iv_channel_up;
break;
case 2:
view = iv_channel_down;
break;
case 3:
view = iv_volume_plus;
break;
case 4:
view = iv_volume_minus;
break;
case 5:
view = iv_exit;
break;
}
return view;
}

private void keyRemappingSendFakeKeyEvent(int keyCode) {
long eventTime = SystemClock.uptimeMillis();
int action = KeyEvent.ACTION_DOWN;
if (action == KeyEvent.ACTION_DOWN) {
mKeyRemappingSendFakeKeyDownTime = eventTime;
}
KeyEvent keyEvent = new KeyEvent(mKeyRemappingSendFakeKeyDownTime,
eventTime, action, keyCode, 0);
InputManager inputManager = (InputManager) mContext
.getSystemService(Context.INPUT_SERVICE);
inputManager.injectInputEvent(keyEvent,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}

private Handler timerHandler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
keyRemappingSendFakeKeyEvent(mCurrentSendKeyCode);
timerHandler.postDelayed(this, 100);
}

};

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息