모바일 개발자 LasseLindh

[안드로이드/Android] 서비스에서 keyEvent 받기 본문

Android

[안드로이드/Android] 서비스에서 keyEvent 받기

사용자 라쎄린드 2017.06.16 11:53

서비스에서 키이벤트를 받는 방법을 알아보겠습니다. 빠르고..간단하게..???


우선 UI가 하나도 없이는 이벤트를 받는건 불가능하므로 서비스에서 윈도우 매니저를 띄우는 방식으로 서비스를 띄웁니다.


첫째로 서비스자체에 이벤트를 등록할 수 없기 때문에 커스텀 루트뷰를 하나 만들어 줍니다. 제 경우엔 FrameLayout이네요.


아래 구현부를 보시면 알겠지만 뷰자체에 disPatchKeyEvent를 적용하고 인터페이스를 추가하여 해당키에 대한 콜백을 받도록 해놨습니다. 간단하게 백키를 감지해보죠..


public class CFrameLayout extends FrameLayout {
private MyKeyEventCallbackListener myKeyEventCallbackListener;

public CFrameLayout(@NonNull Context context) {
super(context);
}

public CFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}

public CFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

public CFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}

public interface MyKeyEventCallbackListener {
void onKeyEvent(KeyEvent event);
}

public void setMyKeyEventCallbackListener(MyKeyEventCallbackListener callback) {
this.myKeyEventCallbackListener = callback;
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN ) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
if(myKeyEventCallbackListener != null)
myKeyEventCallbackListener.onKeyEvent(event);
break;
default:
}
}

return super.dispatchKeyEvent(event);
}
}


두번째로 사용하고자 하는 뷰의 xml 의 ParentView를 커스텀뷰로 교체해줍니다.

<com.cestlavie.minialimi.utils.CFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/service_root_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >


세번째로는 서비스에 추가되는 부분입니다. 윈도우 매니저 추가시에 아래사항에 유의해주세요.

윈도우매니저의 param 설정에서 FLAG_NOT_FOCUSABLE 부분은 FLAG에서 제외하셔야 키이벤트를 받을 수 있습니다. 

NOT FOCUSABLE이 적용안되면 플로팅 영역 이외의 뷰는 터치가 되지 않으므로 주의하셔야합니다. 홈키도 안먹힙니다.. 몰래카톡에서는 사용하기 힘들겠네요..흑..

mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
PixelFormat.TRANSLUCENT);


마지막으로 커스텀뷰에 아래와같이 콜백을 등록하면 CFrameLayout에서 등록한대로 Backkey 시 이벤트를 받을 수 있습니다. 필터만 빼면 홈키빼고는 다 받을수 있네요

CFrameLayout cFrameLayout = (CFrameLayout) mView.findViewById(R.id.service_root_view);
cFrameLayout.setMyKeyEventCallbackListener(new CFrameLayout.MyKeyEventCallbackListener() {
@Override
public void onKeyEvent(KeyEvent event) {
// TODO is 뭔들
}
});


넘나잘되는것...그럼 즐코딩하세요!

1 Comments
댓글쓰기 폼