preface
The company recently added a new business, applying the existing Flutter Android project to TV, and that’s where Asscre’s job came in.
This article describes two ways to implement Flutter for TV. There are limited capabilities of Flutter
That what, big brother, first click “like” + favorites! Hey hey
The development train of thought
Before development, let’s set our thinking.
That is, how to make the Settings for the least intrusive, best performance and higher playability of the original program code.
So, based on the Settings above, we find two things in the Flutter Widget:
- RawKeyboardListener
- InkWell and other Android TV configurations
The first effect
More playable and malleableRawKeyboardListenerSolution effect
Minimal modification to the original programInkWellAnd other Android TV configuration solutions
The development details
More playable and malleableRawKeyboardListenerThe solution
Using RawKeyboardListener
RawKeyboardListener(
focusNode: d.focusNode, / / configuration focusNode
onKey: (RawKeyEvent event) =>
context.read<HomePageContentWidgetProvider>().focusEventHandler(event, context, d), // Monitor and handle special events
child: Container(
height: 190,
width: 190,
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: d.focusNode.hasFocus ? Colors.blue : Colors.transparent),
borderRadius: BorderRadius.circular(20),
color: Colors.white.withAlpha(20),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
d.img,
height: 80,
),
SizedBox(height: 20),
Text(
d.name,
style: TextStyle(
color: Colors.white,
fontSize: 32() [() [() [() [()Copy the code
The Provider layer handles events
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tv_test/pages/memory_page/memory_page.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class HomePageContentWidgetProvider
with ChangeNotifier {
bool init = false;
double maxWScreen = 0; // The maximum distance from the button to the right of the screen
double minWScreen = 60.w; // The button is far from the left edge of the screen
final List<HomePageMakeBtn> makeBtnList = [
HomePageMakeBtn('lib/assets/img/youtube.png'.'You Tube'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/apple.png'.'Apple'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/facebook.png'.'Facebook'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/douyin.png'.'Tik Tok'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/mi.png'.'MI'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/huawei.png'.'Hua Wei'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/youtube.png'.'TTT'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/apple.png'.'DDDD'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/facebook.png'.'FFFF'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/douyin.png'.'AAAA'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/mi.png'.'QQQQQ'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/huawei.png'.'WWWW'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/youtube.png'.'EEEEE'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/apple.png'.'RRRRR'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/facebook.png'.'YYYYYY'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/douyin.png'.'UUUUUU'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/mi.png'.'SSSSS'.' ', FocusNode()),
HomePageMakeBtn('lib/assets/img/huawei.png'.'VVVV'.' ', FocusNode()),
];
HomePageContentWidgetProvider(BuildContext context) {
maxWScreen = MediaQuery.of(context).size.width - 246.w;
// setMakeFocusAddListener();
if(! init) { makeBtnList.first.focusNode.requestFocus(); init =true;
}
}
setMakeFocusAddListener() {
for (int i = 0; i < makeBtnList.length; i++) {
makeBtnList[i].focusNode.addListener(() {
if (makeBtnList[i].focusNode.hasFocus) {
// notifyListeners();
print(
'= = = =${makeBtnList[i].name} : ${makeBtnList[i].focusNode.hasFocus}'); }}); } } setMakeFocusDispose() {for (var item in makeBtnList) {
item.focusNode.removeListener(() {});
item.focusNode.dispose();
}
}
focusEventHandler(
RawKeyEvent event, BuildContext context, HomePageMakeBtn param) async {
/// Handles only events when a key is pressed
if (event.data is RawKeyEventDataAndroid &&
event.runtimeType.toString() == 'RawKeyDownEvent') {
CustomRawKeyEventDataAndroid _d =
CustomRawKeyEventDataAndroid.format(event.data);
/// Handles pressing the OK key and the center key
if (_d.keyCode == 23 || _d.keyCode == 66) {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => MemoryPage(title: param.name)));
} else {
// for (var e in makeBtnList) {
// print('${e.name} : ${e.focusNode.hasFocus}');
// }
/// The left key is processed
if (_d.keyCode == 21) {
await keyCodeDpadLeft(context, param);
}
/// Right click processing
if (_d.keyCode == 22) {
awaitkeyCodeDpadRight(context, param); } notifyListeners(); }}}/// The left key is processed
keyCodeDpadLeft(BuildContext context, HomePageMakeBtn param) async {
/// Primary boundary processing
final int _idx = makeBtnList.indexWhere((e) => e == param);
if (_idx == 0) return;
final int _nextIndex = _idx + 1;
if ((_nextIndex % 7) = =1) {
HomePageMakeBtn _nextNode = makeBtnList[_idx - 1];
print(_nextNode.name);
await Future.delayed(const Duration(milliseconds: 20)); _nextNode.focusNode.requestFocus(); }}/// Right click processing
keyCodeDpadRight(BuildContext context, HomePageMakeBtn param) async {
final int _idx = makeBtnList.indexWhere((e) => e == param);
/// Last bit boundary processing
if (_idx == (makeBtnList.length - 1)) return;
final int _nextIndex = _idx + 1;
if ((_nextIndex % 7) = =0) {
HomePageMakeBtn _nextNode = makeBtnList[_nextIndex];
await Future.delayed(const Duration(milliseconds: 20)); _nextNode.focusNode.requestFocus(); }}@override
void dispose() {
setMakeFocusDispose();
super.dispose(); }}class HomePageMakeBtn {
final String img;
final String name;
final String routerName;
final FocusNode focusNode;
HomePageMakeBtn(this.img, this.name, this.routerName, this.focusNode);
}
class CustomRawKeyEventDataAndroid {
final int flags;
final int codePoint;
final int plainCodePoint;
/// case 19: KEY_UP
/// case 20: KEY_DOWN
/// case 21: KEY_LEFT
/// case 22: KEY_RIGHT
/// case 23: KEY_CENTER
final int keyCode;
final int scanCode;
final int metaState;
CustomRawKeyEventDataAndroid(this.flags, this.codePoint, this.plainCodePoint,
this.keyCode, this.scanCode, this.metaState);
static CustomRawKeyEventDataAndroid format(d) {
returnCustomRawKeyEventDataAndroid(d.flags, d.codePoint, d.plainCodePoint, d.keyCode, d.scanCode, d.metaState); }}Copy the code
Pay attention to
We can see that we use it for left and right keys
Why is that?
This is because the Flutter mechanism will first trigger the requestFocus once and then the requestFocus twice, which conflicts with our expectation.
Such as:
- When using the end of the button to the right, the system triggers focus to UUUUU this button, our actual expectation is to YYYYY.
- When using the key head to the left, it will also cross two focuses.
So far Asscre has not found a good solution, but using await Future Delayed can relieve the inhuman operation.
Minimal modification to the original programInkWellAnd other Android TV configuration solutions
First, we need to set up in androidmanifest.xmlLEANBACK_LAUNCHERTell the platform that our application is a TV application
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>// Add this sentence<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
Copy the code
We then add in the Main entry fileShortcutsFor our program to respond to our remote control commands.
returnShortcuts( shortcuts: <LogicalKeySet, Intent>{ LogicalKeySet(LogicalKeyboardKey.select): ActivateIntent(), }, child: MaterialApp( ... ) ;Copy the code
Finally, useInkWellTo get the focus setting user remote click effect, whichfocusColorHelp us remind the user of the location of the button at this time.
return Material(
color: Colors.white.withAlpha(20),
child: InkWell(
focusColor: Colors.deepOrange.withAlpha(80),
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => MemoryPage(title: d.name))),
child: SizedBox(
height: 190,
width: 190,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
d.img,
height: 80,
),
SizedBox(height: 20),
Text(
d.name,
style: TextStyle(
color: Colors.white,
fontSize: 32,),),),),),),);Copy the code
conclusion
You can choose one of the two solutions according to your own (boss) preferences or business needs.
The RawKeyboardListener solution is recommended for complex customizations. For example, when a key event is triggered, the focus widget can zoom in, fade out, and so on, which can help improve the user experience.
However, with existing business logic, InkWell’s solution described above could be used with a few adjustments.
File reference
TV keyCode,
name | keycode | instructions |
---|---|---|
KEYCODE_UNKNOWN | 0 | |
————————————— | —– | ————– |
KEYCODE_SOFT_LEFT | 1 | |
KEYCODE_SOFT_RIGHT | 2 | |
KEYCODE_HOME | 3 | HOME button |
KEYCODE_BACK | 4 | Return key |
KEYCODE_CALL | 5 | dial |
KEYCODE_ENDCALL | 6 | Hang up the key |
KEYCODE_0 | 7 | |
KEYCODE_1 | 8 | |
KEYCODE_2 | 9 | |
KEYCODE_3 | 10 | |
KEYCODE_4 | 11 | |
KEYCODE_5 | 12 | |
KEYCODE_6 | 13 | |
KEYCODE_7 | 14 | |
KEYCODE_8 | 15 | |
KEYCODE_9 | 16 | |
KEYCODE_STAR | 17 | Keys * |
KEYCODE_POUND | 18 | Button # |
KEYCODE_DPAD_UP | 19 | upward |
KEYCODE_DPAD_DOWN | 20 | down |
KEYCODE_DPAD_LEFT | 21 | To the left |
KEYCODE_DPAD_RIGHT | 22 | To the right |
KEYCODE_DPAD_CENTER | 23 | Identify key |
KEYCODE_VOLUME_UP | 24 | Volume increase key |
KEYCODE_VOLUME_DOWN | 25 | Volume reduction button |
KEYCODE_POWER | 26 | Power key |
KEYCODE_CAMERA | 27 | Camera button |
KEYCODE_CLEAR | 28 | |
KEYCODE_A | 29 | |
KEYCODE_B | 30 | |
KEYCODE_C | 31 | |
KEYCODE_D | 32 | |
KEYCODE_E | 33 | |
KEYCODE_F | 34 | |
KEYCODE_G | 35 | |
KEYCODE_H | 36 | |
KEYCODE_I | 37 | |
KEYCODE_J | 38 | |
KEYCODE_K | 39 | |
KEYCODE_L | 40 | |
KEYCODE_M | 41 | |
KEYCODE_N | 42 | |
KEYCODE_O | 43 | |
KEYCODE_P | 44 | |
KEYCODE_Q | 45 | |
KEYCODE_R | 46 | |
KEYCODE_S | 47 | |
KEYCODE_T | 48 | |
KEYCODE_U | 49 | |
KEYCODE_V | 50 | |
KEYCODE_W | 51 | |
KEYCODE_X | 52 | |
KEYCODE_Y | 53 | |
KEYCODE_Z | 54 | |
KEYCODE_COMMA | 55 | The key, |
KEYCODE_PERIOD | 56 | Buttons. |
KEYCODE_ALT_LEFT | 57 | |
KEYCODE_ALT_RIGHT | 58 | |
KEYCODE_SHIFT_LEFT | 59 | |
KEYCODE_SHIFT_RIGHT | 60 | |
KEYCODE_TAB | 61 | The Tab key |
KEYCODE_SPACE | 62 | The blank space key |
KEYCODE_SYM | 63 | |
KEYCODE_EXPLORER | 64 | |
KEYCODE_ENVELOPE | 65 | |
KEYCODE_ENTER | 66 | The enter key |
KEYCODE_DEL | 67 | backspace |
KEYCODE_GRAVE | 68 | The key ` |
KEYCODE_MINUS | 69 | The key – |
KEYCODE_EQUALS | 70 | Key = |
KEYCODE_LEFT_BRACKET | 71 | The key [ |
KEYCODE_RIGHT_BRACKET | 72 | The key] |
KEYCODE_BACKSLASH | 73 | Button \ |
KEYCODE_SEMICOLON | 74 | The key, |
KEYCODE_APOSTROPHE | 75 | Key ” single quotes |
KEYCODE_SLASH | 76 | The key / |
KEYCODE_AT | 77 | Button @ |
KEYCODE_NUM | 78 | |
KEYCODE_HEADSETHOOK | 79 | |
KEYCODE_FOCUS | 80 | Photo focus button |
KEYCODE_PLUS | 81 | Keys + |
KEYCODE_MENU | 82 | menu |
KEYCODE_NOTIFICATION | 83 | Inform the key |
KEYCODE_SEARCH | 84 | |
KEYCODE_MEDIA_PLAY_PAUSE | 85 | Multimedia key Play/pause |
KEYCODE_MEDIA_STOP | 86 | Multimedia key pause |
KEYCODE_MEDIA_NEXT | 87 | Multimedia key next |
KEYCODE_MEDIA_PREVIOUS | 88 | Multimedia key on a song |
KEYCODE_MEDIA_REWIND | 89 | The multimedia key resets quickly |
KEYCODE_MEDIA_FAST_FORWARD | 90 | Multimedia key fast forward |
KEYCODE_MUTE | 91 | Microphone mute button |
KEYCODE_PAGE_UP | 92 | Page up key |
KEYCODE_PAGE_DOWN | 93 | Scroll down key |
KEYCODE_PICTSYMBOLS | 94 | |
KEYCODE_SWITCH_CHARSET | 95 | |
KEYCODE_BUTTON_A | 96 | |
KEYCODE_BUTTON_B | 97 | |
KEYCODE_BUTTON_C | 98 | |
KEYCODE_BUTTON_X | 99 | |
KEYCODE_BUTTON_Y | 100 | |
KEYCODE_BUTTON_Z | 101 | |
KEYCODE_BUTTON_L1 | 102 | |
KEYCODE_BUTTON_R1 | 103 | |
KEYCODE_BUTTON_L2 | 104 | |
KEYCODE_BUTTON_R2 | 105 | |
KEYCODE_BUTTON_THUMBL | 106 | |
KEYCODE_BUTTON_THUMBR | 107 | |
KEYCODE_BUTTON_START | 108 | |
KEYCODE_BUTTON_SELECT | 109 | |
KEYCODE_BUTTON_MODE | 110 | |
KEYCODE_ESCAPE | 111 | ESC |
KEYCODE_FORWARD_DEL | 112 | The delete key |
KEYCODE_CTRL_LEFT | 113 | |
KEYCODE_CTRL_RIGHT | 114 | |
KEYCODE_CAPS_LOCK | 115 | Caps lock key |
KEYCODE_SCROLL_LOCK | 116 | |
KEYCODE_META_LEFT | 117 | |
KEYCODE_META_RIGHT | 118 | |
KEYCODE_FUNCTION | 119 | |
KEYCODE_SYSRQ | 120 | |
KEYCODE_BREAK | 121 | Break/Pause button |
KEYCODE_MOVE_HOME | 122 | The cursor moves to the Start key |
KEYCODE_MOVE_END | 123 | Move the cursor to the end key |
KEYCODE_INSERT | 124 | |
KEYCODE_FORWARD | 125 | |
KEYCODE_MEDIA_PLAY | 126 | Multimedia Key Play |
KEYCODE_MEDIA_PAUSE | 127 | Multimedia key pause |
KEYCODE_MEDIA_CLOSE | 128 | Multimedia Key Off |
KEYCODE_MEDIA_EJECT | 129 | Multimedia key pop up |
KEYCODE_MEDIA_RECORD | 130 | Multimedia key recording |
KEYCODE_F1 | 131 | |
KEYCODE_F2 | 132 | |
KEYCODE_F3 | 133 | |
KEYCODE_F4 | 134 | |
KEYCODE_F5 | 135 | |
KEYCODE_F6 | 136 | |
KEYCODE_F7 | 137 | |
KEYCODE_F8 | 138 | |
KEYCODE_F9 | 139 | |
KEYCODE_F10 | 140 | |
KEYCODE_F11 | 141 | |
KEYCODE_F12 | 142 | |
KEYCODE_NUM_LOCK | 143 | Keypad lock |
KEYCODE_NUMPAD_0 | 144 | |
KEYCODE_NUMPAD_1 | 145 | |
KEYCODE_NUMPAD_2 | 146 | |
KEYCODE_NUMPAD_3 | 147 | |
KEYCODE_NUMPAD_4 | 148 | |
KEYCODE_NUMPAD_5 | 149 | |
KEYCODE_NUMPAD_6 | 150 | |
KEYCODE_NUMPAD_7 | 151 | |
KEYCODE_NUMPAD_8 | 152 | |
KEYCODE_NUMPAD_9 | 153 | |
KEYCODE_NUMPAD_DIVIDE | 154 | |
KEYCODE_NUMPAD_MULTIPLY | 155 | |
KEYCODE_NUMPAD_SUBTRACT | 156 | |
KEYCODE_NUMPAD_ADD | 157 | |
KEYCODE_NUMPAD_DOT | 158 | |
KEYCODE_NUMPAD_COMMA | 159 | |
KEYCODE_NUMPAD_ENTER | 160 | |
KEYCODE_NUMPAD_EQUALS | 161 | |
KEYCODE_NUMPAD_LEFT_PAREN | 162 | |
KEYCODE_NUMPAD_RIGHT_PAREN | 163 | |
KEYCODE_VOLUME_MUTE | 164 | Speaker mute button |
KEYCODE_INFO | 165 | |
KEYCODE_CHANNEL_UP | 166 | |
KEYCODE_CHANNEL_DOWN | 167 | |
KEYCODE_ZOOM_IN | 168 | Zoom in key |
KEYCODE_ZOOM_OUT | 169 | Narrowing the key |
KEYCODE_TV | 170 | |
KEYCODE_WINDOW | 171 | |
KEYCODE_GUIDE | 172 | |
KEYCODE_DVR | 173 | |
KEYCODE_BOOKMARK | 174 | |
KEYCODE_CAPTIONS | 175 | |
KEYCODE_SETTINGS | 176 | |
KEYCODE_TV_POWER | 177 | |
KEYCODE_TV_INPUT | 178 | |
KEYCODE_STB_POWER | 179 | |
KEYCODE_STB_INPUT | 180 | |
KEYCODE_AVR_POWER | 181 | |
KEYCODE_AVR_INPUT | 182 | |
KEYCODE_PROG_RED | 183 | |
KEYCODE_PROG_GREEN | 184 | |
KEYCODE_PROG_YELLOW | 185 | |
KEYCODE_PROG_BLUE | 186 | |
KEYCODE_APP_SWITCH | 187 | |
KEYCODE_BUTTON_1 | 188 | |
KEYCODE_BUTTON_2 | 189 | |
KEYCODE_BUTTON_3 | 190 | |
KEYCODE_BUTTON_4 | 191 | |
KEYCODE_BUTTON_5 | 192 | |
KEYCODE_BUTTON_6 | 193 | |
KEYCODE_BUTTON_7 | 194 | |
KEYCODE_BUTTON_8 | 195 | |
KEYCODE_BUTTON_9 | 196 | |
KEYCODE_BUTTON_10 | 197 | |
KEYCODE_BUTTON_11 | 198 | |
KEYCODE_BUTTON_12 | 199 | |
KEYCODE_BUTTON_13 | 200 | |
KEYCODE_BUTTON_14 | 201 | |
KEYCODE_BUTTON_15 | 202 | |
KEYCODE_BUTTON_16 | 203 | |
KEYCODE_LANGUAGE_SWITCH | 204 | |
KEYCODE_MANNER_MODE | 205 | |
KEYCODE_3D_MODE | 206 | |
KEYCODE_CONTACTS | 207 | |
KEYCODE_CALENDAR | 208 | |
KEYCODE_MUSIC | 209 | |
KEYCODE_CALCULATOR | 210 | |
KEYCODE_ZENKAKU_HANKAKU | 211 | |
KEYCODE_EISU | 212 | |
KEYCODE_MUHENKAN | 213 | |
KEYCODE_HENKAN | 214 | |
KEYCODE_KATAKANA_HIRAGANA | 215 | |
KEYCODE_YEN | 216 | |
KEYCODE_RO | 217 | |
KEYCODE_KANA | 218 | |
KEYCODE_ASSIST | 219 | |
KEYCODE_BRIGHTNESS_DOWN | 220 | |
KEYCODE_BRIGHTNESS_UP | 221 | |
KEYCODE_MEDIA_AUDIO_TRACK | 222 | |
KEYCODE_SLEEP | 223 | |
KEYCODE_WAKEUP | 224 | |
KEYCODE_PAIRING | 225 | |
KEYCODE_MEDIA_TOP_MENU | 226 | |
KEYCODE_11 | 227 | |
KEYCODE_12 | 228 | |
KEYCODE_LAST_CHANNEL | 229 | |
KEYCODE_TV_DATA_SERVICE | 230 | |
KEYCODE_VOICE_ASSIST | 231 | |
KEYCODE_TV_RADIO_SERVICE | 232 | |
KEYCODE_TV_TELETEXT | 233 | |
KEYCODE_TV_NUMBER_ENTRY | 234 | |
KEYCODE_TV_TERRESTRIAL_ANALOG | 235 | |
KEYCODE_TV_TERRESTRIAL_DIGITAL | 236 | |
KEYCODE_TV_SATELLITE | 237 | |
KEYCODE_TV_SATELLITE_BS | 238 | |
KEYCODE_TV_SATELLITE_CS | 239 | |
KEYCODE_TV_SATELLITE_SERVICE | 240 | |
KEYCODE_TV_NETWORK | 241 | |
KEYCODE_TV_ANTENNA_CABLE | 242 | |
KEYCODE_TV_INPUT_HDMI_1 | 243 | |
KEYCODE_TV_INPUT_HDMI_2 | 244 | |
KEYCODE_TV_INPUT_HDMI_3 | 245 | |
KEYCODE_TV_INPUT_HDMI_4 | 246 | |
KEYCODE_TV_INPUT_COMPOSITE_1 | 247 | |
KEYCODE_TV_INPUT_COMPOSITE_2 | 248 | |
KEYCODE_TV_INPUT_COMPONENT_1 | 249 | |
KEYCODE_TV_INPUT_COMPONENT_2 | 250 | |
KEYCODE_TV_INPUT_VGA_1 | 251 | |
KEYCODE_TV_AUDIO_DESCRIPTION | 252 | |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP | 253 | |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN | 254 | |
KEYCODE_TV_ZOOM_MODE | 255 | |
KEYCODE_TV_CONTENTS_MENU | 256 | |
KEYCODE_TV_MEDIA_CONTEXT_MENU | 257 | |
KEYCODE_TV_TIMER_PROGRAMMING | 258 | |
KEYCODE_HELP | 259 | |
KEYCODE_NAVIGATE_PREVIOUS | 260 | |
KEYCODE_NAVIGATE_NEXT | 261 | |
KEYCODE_NAVIGATE_IN | 262 | |
KEYCODE_NAVIGATE_OUT | 263 | |
KEYCODE_STEM_PRIMARY | 264 | |
KEYCODE_STEM_1 | 265 | |
KEYCODE_STEM_2 | 266 | |
KEYCODE_STEM_3 | 267 | |
KEYCODE_DPAD_UP_LEFT | 268 | |
KEYCODE_DPAD_DOWN_LEFT | 269 | |
KEYCODE_DPAD_UP_RIGHT | 270 | |
KEYCODE_DPAD_DOWN_RIGHT | 271 | |
KEYCODE_MEDIA_SKIP_FORWARD | 272 | |
KEYCODE_MEDIA_SKIP_BACKWARD | 273 | |
KEYCODE_MEDIA_STEP_FORWARD | 274 | |
KEYCODE_MEDIA_STEP_BACKWARD | 275 | |
KEYCODE_SOFT_SLEEP | 276 | |
KEYCODE_CUT | 277 | |
KEYCODE_COPY | 278 | |
KEYCODE_PASTE | 279 | |
KEYCODE_SYSTEM_NAVIGATION_UP | 280 | |
KEYCODE_SYSTEM_NAVIGATION_DOWN | 281 | |
KEYCODE_SYSTEM_NAVIGATION_LEFT | 282 | |
KEYCODE_SYSTEM_NAVIGATION_RIGHT | 283 |