Android에서 홈 버튼 누름 감지
이것은 한동안 나를 미치게 만들었다.
Android 애플리케이션에서 홈 버튼을 눌렀는지 확실하게 감지 할 수있는 방법이 있습니까?
실패하면 활동이 onPause로 들어가는 원인을 알 수있는 강력한 방법이 있습니까? 즉, 새로운 활동이 시작되거나 뒤로 / 홈을 눌러서 발생했는지 감지 할 수 있습니까?
내가 본 한 가지 제안은 onPause ()를 재정의하고 isFinishing ()을 호출하는 것이지만 새 활동이 시작되는 것처럼 홈 버튼을 누르면 false를 반환하므로 둘을 구분하지 못합니다.
많은 도움을 주셔서 감사합니다.
** 업데이트 ** : http://nisha113a5.blogspot.com/ 링크에 대한 @ android-hungry 감사합니다.
다음 방법을 재정의합니다.
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
}
그런 다음 홈 버튼 누름에 대해 다음 이벤트가 시작됩니다.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
이 줄에 부작용이 있는지 확실하지 않습니다.
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
따라서 대중적인 믿음과는 달리 실제로 홈 키를들을 수 있습니다. 걱정스럽게도 false를 반환하고 홈 키가 아무것도하지 않도록 할 수 있습니다.
업데이트 : 예상대로 이로 인해 약간의 부작용이 있습니다.이 모드를 사용하면 삽입 된 동영상과 Google지도가 보이지 않는 것 같습니다.
업데이트 : 아마도이 해킹은 Android 4.0 이상에서 더 이상 작동하지 않습니다.
다음 코드는 나를 위해 작동합니다. :)
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
@Override
public void onHomePressed() {
// do something here...
}
@Override
public void onHomeLongPressed() {
}
});
mHomeWatcher.startWatch();
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();
}
}
}
}
}
}
}
public interface OnHomePressedListener {
void onHomePressed();
void onHomeLongPressed();
}
이것은 오래된 질문이지만 누군가에게 도움이 될 수 있습니다.
@Override
protected void onUserLeaveHint()
{
Log.d("onUserLeaveHint","Home button pressed");
super.onUserLeaveHint();
}
문서에 따르면 onUserLeaveHint () 메서드는 사용자가 홈 버튼을 클릭하거나 무언가가 애플리케이션을 중단 할 때 (예 : 수신 전화) 호출됩니다.
이것은 나를 위해 작동합니다 .. :)
Android 앱 내에서 홈 버튼을 감지 및 / 또는 가로채는 것은 불가능합니다. 종료 할 수없는 악성 앱을 방지하기 위해 시스템에 내장되어 있습니다.
첫 번째 활동이 열리고 닫힐 때 또는 홈 버튼으로 활동을 일시 중지 한 다음 작업 관리자에서 다시 시작할 때 애플리케이션에서 배경 음악을 시작 / 중지해야했습니다. 순수 재생에 다시 시작 / 중지 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
}
}
응용 프로그램 (모든 활동)이 닫히거나 홈 버튼을 누를 때만 재생을 중단합니다. Unfortunatelly 난의 통화의 변화 순서로 관리하지 않은 onPause()
시작 활동 및 방법 onResume()
시작된 actvity의 Activity.startActivity()
호출 (또는에서 발견 onPause()
이 경우 특별히 처리 할 수 있도록 그 활동이 다른 활동에 다른 방법을 출시) :
private boolean mIsStarting;
@Override
public void startActivity(Intent intent) {
mIsStarting = true;
super.startActivity(intent);
}
또 다른 단점은 다음에 GET_TASKS
권한을 추가해야한다는 것입니다 AndroidManifest.xml
.
<uses-permission
android:name="android.permission.GET_TASKS"/>
홈 버튼 누를 때만 반응하는이 코드를 수정하는 것은 매우 어렵습니다.
onUserLeaveHint()
활동에서 재정의 합니다. 새로운 활동이 오거나 사용자가 뒤로 누를 때 활동에 대한 콜백이 없습니다.
각 화면에 대한 카운터를 만들어보십시오. 사용자가 홈을 터치하면 카운터는 0이됩니다.
public void onStart() {
super.onStart();
counter++;
}
public void onStop() {
super.onStop();
counter--;
if (counter == 0) {
// Do..
}
}
You might consider a solution by Andreas Shrade in his post on How-To Create a Working Kiosk Mode in Android. It's a bit hacky, but given the reasons that interception of the home button is prevented it has to be ;)
I had this problem, and since overriding the onKeyDown() method didn't accomplish anything because of the underlying android system didn't call this method, I solved this with overriding onBackPressed(), and I had a boolean value set there to false, because I pressed back, let me show you what I mean in code:
import android.util.Log;
public class HomeButtonActivity extends Activity {
boolean homePressed = false;
// override onCreate() here.
@Override
public void onBackPressed() {
homePressed = false; // simply set homePressed to false
}
@Overide
public void onResume() {
super.onResume();
homePressed = true; // default: other wise onBackPressed will set it to false
}
@Override
public void onPause() {
super.onPause();
if(homePressed) { Log.i("homePressed", "yay"); }
}
So the reason why this worked is because the only way to navigate outside this activity is by pressing back or home so if back was pressed then i know the cause wasn't home, but otherwise the cause was home, therefore i set the default boolean value for homePressed to be true. However this will only work with a single activity instance in your application because otherwise you have more possibilities to cause the onPause() method to be called.
Since API 14 you can use the function onTrimMemory()
and check for the flag TRIM_MEMORY_UI_HIDDEN
. This will tell you that your Application is going to the background.
So in your custom Application class you can write something like:
override fun onTrimMemory(level: Int) {
if (level == TRIM_MEMORY_UI_HIDDEN) {
// Application going to background, do something
}
}
For an in-depth study of this, I invite you to read this article: http://www.developerphil.com/no-you-can-not-override-the-home-button-but-you-dont-have-to/
onUserLeaveHint();
override this activity class method.This will detect the home key click . This method is called right before the activity's onPause() callback.But it will not be called when an activity is interrupted like a in-call activity comes into foreground, apart from that interruptions it will call when user click home key.
@Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
Log.d(TAG, "home key clicked");
}
An option for your application would be to write a replacement Home Screen using the android.intent.category.HOME Intent. I believe this type of Intent you can see the home button.
More details:
http://developer.android.com/guide/topics/intents/intents-filters.html#imatch
Since you only wish for the root activity to be reshown when the app is launched, maybe you can get this behavior by changing launch modes, etc. in the manifest?
For instance, have you tried applying the android:clearTaskOnLaunch="true" attribute to your launch activity, perhaps in tandem with android:launchMode="singleInstance"?
Tasks and Back Stack is a great resource for fine-tuning this sort of behavior.
It's a bad idea to change the behavior of the home key. This is why Google doesn't allow you to override the home key. I wouldn't mess with the home key generally speaking. You need to give the user a way to get out of your app if it goes off into the weeds for whatever reason.
I'd image any work around will have unwanted side effects.
override onUserLeaveHint method can catch the home press event, but you need also consider user click events. following codes works for me.
private boolean isUserClickToLeave = false;
private Handler mHandler = new Handler();
Runnable resetUserClickFlagRunnable = new Runnable() {
@Override
public void run() {
isUserClickToLeave = false;
}
};
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
isUserClickToLeave = true;
mHandler.removeCallbacks(resetUserClickFlagRunnable);
mHandler.postDelayed(resetUserClickFlagRunnable, 1000);
}
return super.dispatchTouchEvent(ev);
}
@Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
if (!isUserClickToLeave ) {
//user press home button case.
onHomePressed();
}
isUserClickToLeave = false;
}
private onHomePressed() {
//do something here.
}
Recently I was trying to detect the home press button, because I needed it to do the same as the method "onBackPressed()". In order to do this, I had to override the method "onSupportNavigateUp()" like this:
override fun onSupportNavigateUp(): Boolean {
onBackPressed()
return true
}
It worked perfectly. =)
Jack's answer is perfectly working for click
event while longClick
is considering is as menu
button click.
By the way, if anyone is wondering how to do via kotlin,
class HomeButtonReceiver(private var context: Context,private var listener: OnHomeButtonClickListener) {
private val mFilter: IntentFilter = IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
private var mReceiver: InnerReceiver = InnerReceiver()
fun startWatch() {
context.registerReceiver(mReceiver, mFilter)
}
fun stopWatch() {
context.unregisterReceiver(mReceiver)
}
inner class InnerReceiver: BroadcastReceiver() {
private val systemDialogReasonKey = "reason"
private val systemDialogReasonHomeKey = "homekey"
override fun onReceive(context: Context?, intent: Intent?) {
val action = intent?.action
if (action == Intent.ACTION_CLOSE_SYSTEM_DIALOGS) {
val reason = intent.getStringExtra(systemDialogReasonKey)
if (reason != null && reason == systemDialogReasonHomeKey) {
listener.onHomeButtonClick()
}
}
}
}
}
Android Home Key handled by the framework layer you can't able to handle this in the application layer level. Because the home button action is already defined in the below level. But If you are developing your custom ROM, then It might be possible. Google restricted the HOME BUTTON override functions because of security reasons.
참고URL : https://stackoverflow.com/questions/8881951/detect-home-button-press-in-android
'program story' 카테고리의 다른 글
JavaScript : 값으로 객체를 전달하는 방법? (0) | 2020.09.18 |
---|---|
Git의 파일에 대한 변경 사항을 선택적으로 되돌 리거나 체크 아웃 하시겠습니까? (0) | 2020.09.18 |
명령 출력에 쉘 스크립트의 특정 문자열이 포함되어 있는지 확인 (0) | 2020.09.18 |
미국 달러 금액을 나타내는 데 사용하는 가장 좋은 장고 모델 필드는 무엇입니까? (0) | 2020.09.18 |
Json.NET 변환기를 사용하여 속성 역 직렬화 (0) | 2020.09.18 |