Android TV apk移植到Android 9彈框概率出現無法響應按鍵問題

在公司實際TV項目開發apk過程中,Activity的 dispatchKeyEventonKeyDown 響應遙控器按鍵彈出對話框(DialogFragment、Dialog、AlertDialog)時,出現概率性無法響應到遙控器按鍵的問題(除Home按鍵),打印日誌大致如下:

ViewRootImpl(27708): Dropping event due to no window focus: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x8, repeatCount=0, eventTime=24289753, downTime=24289753, deviceId=-1, source=0x101 }

按鍵響應:
@Override
public boolean dispatchKeyEvent(int keyCode, KeyEvent event) {
	if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN/ACTION_UP) {
		// showDialog()
		return true;
	}
}
或者
@Override
public boolean onKeyDown(int keyCode) {
	if (keyCode == KeyEvent.KEYCODE_BACK) {
		// showDialog
		return true;
	}
}

目前找到的解決方案是重寫Activity的 onKeyUp,不使用 dispatchKeyEventonKeyDown 響應彈出對話框(其他按鍵響應可以正常使用 dispatchKeyEventonKeyDown):

@Override
public boolean onKeyUp(int keyCode) {
	if (keyCode == KeyEvent.KEYCODE_BACK) {
		// showDialog()
		return true;
	}
}

兩個注意點:

1、跳轉Activity有響應相同的按鍵可能會出現衝突,比如從Activity A跳轉到 Activity B,跳轉界面響應的是按鍵 KeyEvent.KEYCODE_0,而Activity B的 onKeyUp 也有攔截該按鍵,出現的現象是Activity B的 onKeyUp 被響應了,這裏只使用一個標誌位延時判斷:

public ActivityA extends AppCompatActivity {
	@Override
	public boolean onKeyUp(int keyCode) {
		if (keyCode == KeyEvent.KEYCODE_0) {
			startActivity(new Intent(this, ActivityB.class);
			return true;
		}
	}
}

public ActivityB extends AppCompatActivity {
	private boolean keyUpReady;

	@Override
	public void onResume() {
		super.onResume();
		Log.i(TAG, "onResume");
		new Handler().postDelay(new Runnable() {
			keyUpReady = true;
		}, 300);
	}

	@Override
	public boolean onKeyUp(int keyCode) {
		if (!keyUpReady) return super.onKeyUp(keyCode); 
		
		if (keyCode == KeyEvent.KEYCODE_0) {
			Log.i(TAG, "onKeyUp");
			// ...
			return true;
		}
	}
}

日誌打印:
onResume
onKeyUp

2、彈出的對話框內部響應攔截的按鍵統一是按下事件 KeyEvent.ACTION_DOWN 不能使用 KeyEvent.ACTION_UP,防止與Activity的 onKeyUp 按鍵起衝突。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章