长按按键执行某个APK如何实现?

时间:2022-09-07 18:00:47
比如长按ESC,执行触摸屏校准。

我的思路:

让触摸屏校准在后台运行,当检测到ESC长按时,开始执行校准。

可是如何检测ESC长按呢?按下ESC,会执行Activity的哪个函数?onDestroy finish onStop三个都不对。

哪位指点指点。

10 个解决方案

#1


常摁button事件参考


public class RepeatingImageButton extends ImageButton { 
private long mStartTime; //记录长按开始 
private int mRepeatCount; //重复次数计数 
private RepeatListener mListener; 
private long mInterval = 500; //Timer触发间隔,即每0.5秒算一次按下 
public RepeatingImageButton(Context context) { 
this(context, null); 

public RepeatingImageButton(Context context, AttributeSet attrs) { 
this(context, attrs, android.R.attr.imageButtonStyle); 

public RepeatingImageButton(Context context, AttributeSet attrs, int defStyle) { 
super(context, attrs, defStyle); 
setFocusable(true); //允许获得焦点 
setLongClickable(true); //启用长按事件 

public void setRepeatListener(RepeatListener l, long interval) { //实现重复按下事件listener 
mListener = l; 
mInterval = interval; 

@Override 
public boolean performLongClick() { 
mStartTime = SystemClock.elapsedRealtime(); 
mRepeatCount = 0; 
post(mRepeater); 
return true; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
if (event.getAction() == MotionEvent.ACTION_UP) {  //   本方法原理同onKeyUp的一样,这里处理屏幕事件,下面的onKeyUp处理Android手机上的物理按键事件 
removeCallbacks(mRepeater); 
if (mStartTime != 0) { 
doRepeat(true); 
mStartTime = 0; 


return super.onTouchEvent(event); 

//处理导航键事件的中键或轨迹球按下事件 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
switch (keyCode) { 
case KeyEvent.KEYCODE_DPAD_CENTER: 
case KeyEvent.KEYCODE_ENTER: 
super.onKeyDown(keyCode, event); 
return true; 

return super.onKeyDown(keyCode, event); 

//当按键弹起通知长按结束 
@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) { 
switch (keyCode) { 
case KeyEvent.KEYCODE_DPAD_CENTER: 
case KeyEvent.KEYCODE_ENTER: 
removeCallbacks(mRepeater); //取消重复listener捕获 
if (mStartTime != 0) { 
doRepeat(true); //如果长按事件累计时间不为0则说明长按了 
mStartTime = 0; //重置长按计时器 


return super.onKeyUp(keyCode, event); 

private Runnable mRepeater = new Runnable() {  //在线程中判断重复 
public void run() { 
doRepeat(false); 
if (isPressed()) { 
postDelayed(this, mInterval); //计算长按后延迟下一次累加 


}; 
private  void doRepeat(boolean last) { 
long now = SystemClock.elapsedRealtime(); 
if (mListener != null) { 
mListener.onRepeat(this, now – mStartTime, last ? -1 : mRepeatCount++); 




#2


OnCreate 和 OnRe

#3


我不是要实现长按,而是要检测是否有长按

我正在override onKeyDown 貌似有点进展了

#4


现在的问题是如何让一个activity开机自启动,并且在后台运行。

#5


好像没有提供长按的处理,不过应该是有相应的函数

#6


@Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && ent.getRepeatCount()>0) {
           //返回键按下后,你要做的事情。。。
   return true;
    }
  return false;
 }

#7


这个应该在应用层是没法实现的,
按键消息是会被传递到处于焦点状态的应用程序里的
只有些少数案件消息如长按power,menu等在framework被处理的,
如果按照楼主的思路的话应该在framework里做修改检测ESC键然后启动APK,具体检测代码可以参考系统怎么检测长按power键的。

#8


@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            Log.d("demo","Long Press the back");
        }
        return true;
    }
在一个应用程序中运行新的APK方法:
    Intent mIntent = new Intent( ); 
  ComponentName comp = new ComponentName("包名", "类名");     
  mIntent.setComponent(comp); 
  mIntent.setAction("android.intent.action.VIEW");
  startActivity(mIntent);
现在的问题是如何让一个activity开机自启动,并且在后台运行!!!你仔细去看下activity的功能,就是service做的,开机自启动可以在配置文件中注册开机的广播,接收到广播后启动该service.

#9


引用 8 楼 majaw 的回复:
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
  // TODO Auto-generated method stub
  if(keyCode == KeyEvent.KEYCODE_BACK) {
  Log.d("demo","Long Press the back");
  }
  ……


大概思路就是这么的,我现在卡在了监听的activity在后台,没有焦点,无法接收按键消息

#10


引用 7 楼 ljp1205 的回复:
这个应该在应用层是没法实现的,
按键消息是会被传递到处于焦点状态的应用程序里的
只有些少数案件消息如长按power,menu等在framework被处理的,
如果按照楼主的思路的话应该在framework里做修改检测ESC键然后启动APK,具体检测代码可以参考系统怎么检测长按power键的。


您说的很对,我现在就无法获取按键消息,因为没有焦点。
长按power。。。   这是个思路

#1


常摁button事件参考


public class RepeatingImageButton extends ImageButton { 
private long mStartTime; //记录长按开始 
private int mRepeatCount; //重复次数计数 
private RepeatListener mListener; 
private long mInterval = 500; //Timer触发间隔,即每0.5秒算一次按下 
public RepeatingImageButton(Context context) { 
this(context, null); 

public RepeatingImageButton(Context context, AttributeSet attrs) { 
this(context, attrs, android.R.attr.imageButtonStyle); 

public RepeatingImageButton(Context context, AttributeSet attrs, int defStyle) { 
super(context, attrs, defStyle); 
setFocusable(true); //允许获得焦点 
setLongClickable(true); //启用长按事件 

public void setRepeatListener(RepeatListener l, long interval) { //实现重复按下事件listener 
mListener = l; 
mInterval = interval; 

@Override 
public boolean performLongClick() { 
mStartTime = SystemClock.elapsedRealtime(); 
mRepeatCount = 0; 
post(mRepeater); 
return true; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
if (event.getAction() == MotionEvent.ACTION_UP) {  //   本方法原理同onKeyUp的一样,这里处理屏幕事件,下面的onKeyUp处理Android手机上的物理按键事件 
removeCallbacks(mRepeater); 
if (mStartTime != 0) { 
doRepeat(true); 
mStartTime = 0; 


return super.onTouchEvent(event); 

//处理导航键事件的中键或轨迹球按下事件 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
switch (keyCode) { 
case KeyEvent.KEYCODE_DPAD_CENTER: 
case KeyEvent.KEYCODE_ENTER: 
super.onKeyDown(keyCode, event); 
return true; 

return super.onKeyDown(keyCode, event); 

//当按键弹起通知长按结束 
@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) { 
switch (keyCode) { 
case KeyEvent.KEYCODE_DPAD_CENTER: 
case KeyEvent.KEYCODE_ENTER: 
removeCallbacks(mRepeater); //取消重复listener捕获 
if (mStartTime != 0) { 
doRepeat(true); //如果长按事件累计时间不为0则说明长按了 
mStartTime = 0; //重置长按计时器 


return super.onKeyUp(keyCode, event); 

private Runnable mRepeater = new Runnable() {  //在线程中判断重复 
public void run() { 
doRepeat(false); 
if (isPressed()) { 
postDelayed(this, mInterval); //计算长按后延迟下一次累加 


}; 
private  void doRepeat(boolean last) { 
long now = SystemClock.elapsedRealtime(); 
if (mListener != null) { 
mListener.onRepeat(this, now – mStartTime, last ? -1 : mRepeatCount++); 




#2


OnCreate 和 OnRe

#3


我不是要实现长按,而是要检测是否有长按

我正在override onKeyDown 貌似有点进展了

#4


现在的问题是如何让一个activity开机自启动,并且在后台运行。

#5


好像没有提供长按的处理,不过应该是有相应的函数

#6


@Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && ent.getRepeatCount()>0) {
           //返回键按下后,你要做的事情。。。
   return true;
    }
  return false;
 }

#7


这个应该在应用层是没法实现的,
按键消息是会被传递到处于焦点状态的应用程序里的
只有些少数案件消息如长按power,menu等在framework被处理的,
如果按照楼主的思路的话应该在framework里做修改检测ESC键然后启动APK,具体检测代码可以参考系统怎么检测长按power键的。

#8


@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            Log.d("demo","Long Press the back");
        }
        return true;
    }
在一个应用程序中运行新的APK方法:
    Intent mIntent = new Intent( ); 
  ComponentName comp = new ComponentName("包名", "类名");     
  mIntent.setComponent(comp); 
  mIntent.setAction("android.intent.action.VIEW");
  startActivity(mIntent);
现在的问题是如何让一个activity开机自启动,并且在后台运行!!!你仔细去看下activity的功能,就是service做的,开机自启动可以在配置文件中注册开机的广播,接收到广播后启动该service.

#9


引用 8 楼 majaw 的回复:
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
  // TODO Auto-generated method stub
  if(keyCode == KeyEvent.KEYCODE_BACK) {
  Log.d("demo","Long Press the back");
  }
  ……


大概思路就是这么的,我现在卡在了监听的activity在后台,没有焦点,无法接收按键消息

#10


引用 7 楼 ljp1205 的回复:
这个应该在应用层是没法实现的,
按键消息是会被传递到处于焦点状态的应用程序里的
只有些少数案件消息如长按power,menu等在framework被处理的,
如果按照楼主的思路的话应该在framework里做修改检测ESC键然后启动APK,具体检测代码可以参考系统怎么检测长按power键的。


您说的很对,我现在就无法获取按键消息,因为没有焦点。
长按power。。。   这是个思路