在android中检测主页按钮按下

Dea*_*ild 87 android android-homebutton

这让我坚持了一段时间.

有没有办法可靠地检测是否在Android应用程序中按下了主页按钮?

如果不这样做,是否有一种强有力的方式来告诉导致活动进入onPause的原因?即我们可以检测它是由新活动启动还是按回/ home引起的.

我看到的一个建议是覆盖onPause()并调用isFinishing(),但是当按下主页按钮时,这将返回false,就像新活动开始时一样,因此无法区分这两者.

任何帮助非常感谢.

**更新**:感谢@ android-hungry这个链接:http://nisha113a5.blogspot.com/

覆盖以下方法:

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);           
}
Run Code Online (Sandbox Code Playgroud)

然后,以下事件将被触发按下主页按钮:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

    if(keyCode == KeyEvent.KEYCODE_HOME)
    {
       //The Code Want to Perform. 
    }
});
Run Code Online (Sandbox Code Playgroud)

我不确定这条线是否有任何副作用:

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);   
Run Code Online (Sandbox Code Playgroud)

因此,与普遍的看法相反,您实际上可以听取主键.令人担忧的是,您可以返回false并让home键不执行任何操作.

更新:正如预期的那样,这有一些副作用 - 在启用此模式的情况下,嵌入式视频和谷歌地图似乎不可见.

更新:据说这个hack不再适用于Android 4.0以上版本

小智 130

以下代码适合我:)

HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
    @Override
    public void onHomePressed() {
        // do something here...
    }
    @Override
    public void onHomeLongPressed() {
    }
});
mHomeWatcher.startWatch();
Run Code Online (Sandbox Code Playgroud)
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

public class HomeWatcher {

    static final String TAG = "hg";
    private Context mContext;
    private IntentFilter mFilter;
    private OnHomePressedListener mListener;
    private InnerReceiver mReceiver;

    public HomeWatcher(Context context) {
        mContext = context;
        mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
    }

    public void setOnHomePressedListener(OnHomePressedListener listener) {
        mListener = listener;
        mReceiver = new InnerReceiver();
    }

    public void startWatch() {
        if (mReceiver != null) {
            mContext.registerReceiver(mReceiver, mFilter);
        }
    }

    public void stopWatch() {
        if (mReceiver != null) {
            mContext.unregisterReceiver(mReceiver);
        }
    }

    class InnerReceiver extends BroadcastReceiver {
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
        final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    Log.e(TAG, "action:" + action + ",reason:" + reason);
                    if (mListener != null) {
                        if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                            mListener.onHomePressed();
                        } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                            mListener.onHomeLongPressed();
                        }
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
public interface OnHomePressedListener {
    void onHomePressed();
    void onHomeLongPressed();
}
Run Code Online (Sandbox Code Playgroud)

  • 您的`onHomeLongPressed`实际上似乎对应于"最近"系统活动的开放.在我的手机上,通过按下主页按钮旁边的"最近"按钮触发,因此您的代码假设它是主页长按并不总是正确的. (3认同)

AL̲*_*̲̳I 48

这是一个古老的问题,但它可能对某人有所帮助.

@Override
protected void onUserLeaveHint()
{
    Log.d("onUserLeaveHint","Home button pressed");
    super.onUserLeaveHint();
}
Run Code Online (Sandbox Code Playgroud)

根据文档,当用户单击主页按钮或某些内容中断您的应用程序(如来电)时,将调用onUserLeaveHint()方法.

这对我有用.. :)

  • 不正确 !!!这是按下主页按钮,但它也适用于Swiching Activity with Intent !! (26认同)
  • 这应该标记为正确答案+1 (2认同)

Jav*_*ave 7

从Android应用程序中检测和/或拦截HOME按钮是不可能的.这内置于系统中以防止无法退出的恶意应用程序.


Bla*_*hex 7

当第一个活动打开和关闭,或者当主页按钮暂停任何活动然后从任务管理器恢复时,我需要在我的应用程序中启动/停止背景音乐.纯播放停止/恢复Activity.onPause()Activity.onResume()中断音乐一段时间,所以我不得不写下面的代码:

@Override
public void onResume() {
  super.onResume();

  // start playback here (if not playing already)
}

@Override
public void onPause() {
  super.onPause();

  ActivityManager manager = (ActivityManager) this.getSystemService(Activity.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(Integer.MAX_VALUE);
  boolean is_finishing = this.isFinishing();
  boolean is_last = false;
  boolean is_topmost = false;
  for (ActivityManager.RunningTaskInfo task : tasks) {
    if (task.topActivity.getPackageName().startsWith("cz.matelier.skolasmyku")) {
      is_last = task.numRunning == 1;
      is_topmost = task.topActivity.equals(this.getComponentName());
      break;
    }
  }

  if ((is_finishing && is_last) || (!is_finishing && is_topmost && !mIsStarting)) {
    mIsStarting = false;
    // stop playback here
  }
}
Run Code Online (Sandbox Code Playgroud)

仅在应用程序(其所有活动)关闭或按下主页按钮时才会中断播放.可惜的是我并没有设法改变通话的顺序onPause()启动活动和方法onResume()的开始actvity的时候Activity.startActivity()被调用(或在检测onPause()该活动推出的另一项活动等方式),所以这种情况下,必须特殊处理:

private boolean mIsStarting;

@Override
public void startActivity(Intent intent) {
  mIsStarting = true;
  super.startActivity(intent);
}
Run Code Online (Sandbox Code Playgroud)

另一个缺点是需要将GET_TASKS权限添加到AndroidManifest.xml:

<uses-permission
  android:name="android.permission.GET_TASKS"/>
Run Code Online (Sandbox Code Playgroud)

修改此代码仅对主页按钮按下有反应是直截了当的.