1移动自动化简介
移动自动化就是通过代码来控制手机,模拟人的动作,对手机进行一些点击,输入等操作,那python代码如何能控制到手机呢?目前的思路应该是python代码->Appium-python库->Appium服务->手机。也就是通过appium的库来调用appium服务,让appium服务对手机进行操作。
基于上面的思路,我们环境安装好之后,运行代码之前,需要先将环境开起来,appium服务开启,安卓模拟器开启,就可以运行安卓自动化代码了。如果运行报错没有找到安卓设备的话,试试看在cmd里面输入adb connect设备名,比如adb connect 127.0.0.1:62001
1.1连接手机的代码
写自动化代码之前,首先写一段下面的代码,用来连接上手机,并且连接上你需要测试的APP,如果报错没有找到设备的话,按照上面说的运行adb connect设备名试试看。
#encoding=utf-8
from appium importwebdriver
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities ={'platformName': 'Android', #平台
#需替换成你的driverName,如果不知 道自己的设备名,用adb命令去查看一下
'driverName': '127.0.0.1:62001','platformVersion': '5.1.1', #安卓版本
'appPackage': 'com.android.settings', #APP包名
'appActivity': '.Settings' #APP启动名
'unicodeKeyboard': True #这句和下面那句是避免中文问题的
'resetKeyboard': True
}
driver= webdriver.Remote(server, desired_capabilities) #连接手机和APP
driver.find_element_by_id("com.android.settings:id/title").click() #后面讲
driver.quit() #退出driver
在上面的代码driver.quit()之前加入下面的代码,获取当前APP的包名和启动名
# 获取APP的包名
print(driver.current_package)
#获取APP的启动名
print(driver.current_activity)
打印的结果:
com.android.settings
.SubSettings
2 UIAutomatorViewer使用
在讲元素定位之前,首先说一个很有用的工具 UIAutomatorViewer,这个工具在\android-sdk-windows\tools文件夹下面,uiautomatorviewer.bat这个文件,双击打开。
第一步:打开之后看到的界面应该是:
(这里提示一下:如果打开的时候报错了,“Error obtaining UI hierarchy”错误,不能找到ui,一般就是因为adb被占用了,那么可以试着关闭adb,去cmd里面输入adb kill-server,再输入adb start-server,重启后等会再去点,如果还是不行,多等会,再不行就把appium的服务关掉)
(再提示:打开uiantomatorviewer的时候还会打开一个黑框,这个黑框别关)
第二步,打开你的虚拟器或者真机中的需要测试的APP,比如我现在测试设置,我就打开设置,如图:
第三步:点击第一步图示的圈红按钮,点击后等待一会,会出来如下图:
第四步,出来上图后,想要哪个按钮的id或者name,就用鼠标点到哪个按钮上,比如我想要看更多按钮的信息,点击“更多”,就在右面界面中出来了text,id,class等信息,其中的resourse-id就是id名。
第五步:这个工具还可以保存当前页面,这样方便以后多次查看当前页面的控件内容,而不用每次去打开APP,操作步骤,点击保存按钮,工具栏里面的第四个按钮,保存后,会同时保存两个文件,一个png文件,一个uix文件。保存后怎么打开呢?点击工具上的第一个按钮,open,点击后会弹出一个框,如图:
上面那个路径是刚才保存的png路径,下面是uix路径,原来保存的名字可能是dump开头的,改一下名字,png和uix可以改成一样的,这样再次打开的时候比较容易找。这样打开跟之前的方法打开出来的结果一样。
3 appium自动化测试代码编写
3.1定位元素
做自动化测试最重要的是要先定位到元素,appium定位元素和selenium类似,准确的说appium也是继承了selenium的方法。
3.1.1通过id定位元素
driver.find_element_by_id("com.android.settings:id/title")
这个方法的参数写的是id名,也就是resourse-id的值。这样就找到id为"com.android.settings:id/title"的控件了,可以对它进行click等操作。
3.1.2通过class定位元素
接着上面的代码:driver.find_element_by_id("com.android.settings:id/title").click(),再写一句:
driver.find_element_by_class_name("android.widget.ImageButton").click()
参数为“class”的值。
通过class name找到返回按钮,点击返回按钮。
3.1.3通过xpath定位元素
driver.find_element_by_xpath("//*[contains(@text, '更多')]").click()
driver.find_element_by_xpath("//*[contains(@content-desc, '向上')]").click()
全部的测试代码为:
#encoding=utf-8
from appium importwebdriverimporttime
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities ={'platformName': 'Android','driverName': '127.0.0.1:62001', #需替换成你的driverName
'platformVersion': '5.1.1','appPackage': 'com.android.settings','appActivity': '.Settings'}
driver= webdriver.Remote(server, desired_capabilities) #连接手机和APP
driver.find_element_by_id("com.android.settings:id/title").click() #点击wlan#time.sleep(2)
driver.find_element_by_class_name("android.widget.ImageButton").click() #点击返回#time.sleep(2)
driver.find_element_by_xpath("//*[contains(@text, '更多')]").click() #点击更多#time.sleep(2)
driver.find_element_by_xpath("//*[contains(@content-desc, '向上')]").click() #点击返回#time.sleep(2)
driver.quit()
3.2定位多个元素
上面那些方法可以定位到一个元素,那么find_elements_by_XXX可以找到多个元素,然后通过下标找你需要的元素。
比如上面那段代码中的这句话:
driver.find_element_by_id("com.android.settings:id/title").click()
这里的id其实并不是唯一的,仔细看看设置页面的其他的元素id,id值也都是这些。
所以可以像下面这样写:
eles = driver.find_elements_by_id("com.android.settings:id/title")
print(type(eles))
eles[0].click() # 点击eles这个列表的第一个元素
eles的类型是list。
3.3 WebDriverWait显示等待
在一个超时时间范围内,每隔一段时间去搜索一次元素是否存在,一旦找到,就返回,没有找到就每隔一段时间找一次,直到超时后报错。
代码编写如下:
# 创建一个WebDriverWait类的对象,传三个参数,第一个参数为driver,第二个参数是总共查找的时间,单位秒,第三个参数为每隔1秒的时间查找一次,如果查找时间超过10秒还没找到,就报超时错误。
wdw = WebDriverWait(driver, 10, 1)
# wdw对象的方法有一个until()方法,这个方法的参数是一个匿名函数,这里的匿名函数,形参x传入的是driver,后面的表达式就是通过xpath找到更多这个按钮。
ele = wdw.until(lambda x:x.find_element_by_xpath("//*[contains(@text, '更多')]"))
ele.click()
使用前需要导入包:
from selenium.webdriver.support.ui import WebDriverWait
3.4元素操作
3.4.1点击元素
click() # 上面已经使用过
3.4.2发送数据到输入框
send_keys(value):
ele.send_keys(“test”)
3.4.3清空输入框的元素
clear():
ele.clear
代码示例:
#encoding=utf-8
from appium importwebdriverfrom selenium.webdriver.support.ui importWebDriverWaitimporttime
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities ={'platformName': 'Android','driverName': '127.0.0.1:62001', #需替换成你的driverName
'platformVersion': '5.1.1','appPackage': 'com.android.settings','appActivity': '.Settings'}
driver=webdriver.Remote(server, desired_capabilities)
wdw= WebDriverWait(driver, 10, 1)#点击搜索
serach = wdw.until(lambda x:x.find_element_by_xpath("//*[contains(@content-desc, '搜索')]"))
serach.click()#输入搜索内容
serach_text = wdw.until(lambda x : x.find_element_by_id("android:id/search_src_text"))
serach_text.send_keys("设置")#清空搜索内容
serach_text.clear()
time.sleep(3)
driver.quit()
3.4.4获取元素的文本内容
text:
wlan_button = driver.find_element_by_id("com.android.settings:id/title")
print(wlan_button.text)
3.4.5获取元素的属性值
get_attribute(“属性名称”):
value的值可以是name,text,className,resourceId
name:首先返回content-desc的值,如果没有content-desc,就返回text属性
text:返回text的属性值
className:返回class属性值,只有API在18版本以上才支持
resourceId:返回resource-id属性值,只有API在18版本以上才支持
wdw = WebDriverWait(driver, 10, 1)
serach = wdw.until(lambda x:x.find_element_by_xpath("//*[contains(@content-desc, '搜索')]"))
print("className:%s"%serach.get_attribute("className"))
print("resourceId:%s"%serach.get_attribute("resourceId"))
print("name:%s"%serach.get_attribute("content-desc")) # 上面那段写的是输入”name”,首先返回content-desc的值,但是现在新版本输入“name”就只返回text的值,所以如果输入name没有得到想要的,就试试看这样写get_attribute("content-desc")
print("name:%s"%serach.get_attribute("checked")) # 返回True或者Flase,还有别的属性也类似使用即可。
3.4.6获取元素的位置
location:
想要获取元素的位置,首先理解一下坐标点,APP的每个控件元素都有一个坐标点,比如下面的左上角的设置控件,左上角的坐标点是(24,59),右下角的坐标点是(84,100)。
越往右,x坐标点越大,越往下,y坐标点值越大。
wdw = WebDriverWait(driver, 10, 1)
serach = wdw.until(lambda x:x.find_element_by_xpath("//*[contains(@content-desc, '搜索')]"))
print(serach.location) # 返回一个字典:{'x': 648, 'y': 44}
3.4.7获取控件的class
tag_name:
driver.find_element_by_name(u"菜单").tag_name
3.4.8判断该控件是否对用户可见
is_displayed:
driver.find_element_by_id("xxx").is_displayed() 返回True或False
3.4.9获取控件的大小
size:
driver.find_element_by_id("xxx").size
3.5滑动和拖拽
3.5.1swipe:从A点滑动至B点,滑动时间为毫秒
driver.swipe(279,1081,320,354)
前面两个值是A点的x,y坐标,后面两个值是B点的x,y坐标,上面那个意思就是从下面的某个点滑动到上面某个点,模拟手机从下往上滑,第五个参数也可以写,是个可选参数,意思是滑动总共花费的时间,单位是毫秒,有一个默认时间大约0.8s左右,比如:
driver.swipe(279,1081,320,354,5000)意思就是说从A点滑动到B点总共花费5s,可以和上面的比较一下,可以看出5s滑动的速度慢了,惯性小了。
还有一个类似的方法,按住A点后快速滑动至B点:
driver.flick(start_x, start_y, end_x, end_y):传入的也是AB点的坐标,
3.5.2 scroll滑动事件:从一个元素滑动到另一个元素
# 找到应用元素
ying_yong = driver.find_element_by_xpath("//*[contains(@text, '应用')]")
# 找到蓝牙元素
lan_ya = driver.find_element_by_xpath("//*[contains(@text, '蓝牙')]")
从应用元素滑动到蓝牙元素
driver.scroll(ying_yong, lan_ya)
3.5.3drag拖拽事件
ying_yong = driver.find_element_by_xpath("//*[contains(@text, '应用')]")
lan_ya = driver.find_element_by_xpath("//*[contains(@text, '蓝牙')]")
driver.drag_and_drop(ying_yong, lan_ya)
drag和scroll的区别:drag是没有惯性的,所谓没有惯性的意思是每次滑动,滑动停止的位置都是一样的,scroll从同一个元素滑动到另一个元素,多次运行的结果可能会不一样。swipe
方法的最后一个参数时间设置的长一些,效果会等同于drag,如果不设置时间,那效果就等同于scroll。
多次滑动,可以参考下面的代码,要注意的是,find_element_by_xxx这个方法只找显示在当前页面的元素,不会找没有显示在当前页面的元素。
ying_yong = driver.find_element_by_xpath("//*[contains(@text, '应用')]")
lan_ya= driver.find_element_by_xpath("//*[contains(@text, '蓝牙')]")
driver.drag_and_drop(ying_yong, lan_ya)#下面这个按钮不可以放到上面去,因为上句话是滑动,备份和重置按钮只有在滑动后才能看到
bei_fen = driver.find_element_by_xpath("//*[contains(@text, '备份')]")
driver.drag_and_drop(bei_fen, ying_yong)
3.5.4综合应用1
如果页面上有”关于手机”元素,就点击,否则就向下翻页,直到找到”关于手机”元素,点击它,,再判断关于手机页面是否有“5.1.1”。
#encoding=utf-8
from appium importwebdriverfrom selenium.webdriver.support.ui importWebDriverWaitimporttime
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities ={'platformName': 'Android','deviceName': '127.0.0.1:62001', #需替换成你的deviceName
'platformVersion': '5.1.1','appPackage': 'com.android.settings','appActivity': '.Settings'}
driver=webdriver.Remote(server, desired_capabilities)whileTrue:try:
about_button= driver.find_element_by_xpath("//*[contains(@text, '关于')]")
about_button.click()
time.sleep(2)break
exceptException:#向下翻页
#这里还要注意,翻完页之后,上一页的最下面的元素还应该在页面上,以免丢失元素
driver.swipe(320,1081,320,500,3000)#判断关于我们页面是否有5.1.1
eles = driver.find_elements_by_id("android:id/summary")for i ineles:#if "5.1" in i.text: # 判断只要包含5.1就可以
if i.text == "5.1.1": #判断i.text必须等于5.1.1
print("有5.1.1")break
else:print("没有")
driver.quit()
for...else...语法:for循环正常执行完毕的情况下(没有执行break语句),继续执行else语法,如果不是正常执行完毕的,即执行了break语言,就不执行else语句了。
3.6高级手势TouchAction
TouchAction是AppiumDriver的辅助类,主要针对手势操作,比如滑动、长按、拖动等,原理是将一系列动作放在一个链条中发送到服务器,服务器接收到该链条后,解析各个动作,逐个执行。
3.6.1手指轻敲
模拟手机轻轻点击一下屏幕的操作方法为:
tap(element=None, x=None, y=None, count=1)
其中element是被定位到的元素,x,y是敲击的坐标点
然后使用perform()方法发送命令到服务器执行
from appium importwebdriverfrom appium.webdriver.common.touch_action import TouchAction #导包
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities={'platformName': 'Android','deviceName': '127.0.0.1:62001', #需替换成你的deviceName
'platformVersion': '5.1.1','appPackage': 'com.android.settings','appActivity': '.Settings'}
driver=webdriver.Remote(server, desired_capabilities)
tc= TouchAction(driver) #创建TouchAction类对象
#more_button = driver.find_element_by_xpath("//*[contains(@text, '更多')]")
#tc.tap(more_button).perform() # 可以直接传入找到的元素
tc.tap(x=108, y=445).perform() #也可以不找元素,直接传入坐标
3.6.2手指按下和抬起
# 前面的代码都一样
driver =webdriver.Remote(server, desired_capabilities)
more_button= driver.find_element_by_xpath("//*[contains(@text, '更多')]")
tc=TouchAction(driver)
tc.tap(more_button).perform()#tc.press(x=24, y=478).perform() # 按下某个点,不松开
tc.press(x=24, y=478).wait(5000).release().perform() #按下某个点,等待5秒钟后,松开。可以理解为长按
用到的方法:
press(element=None, x=None, y=None, count=1):长按
wait(time):等待多少毫秒
release():释放
3.6.3长按long_press
方法:
TouchAction(driver).long_presss(el=None, x=None, y=None, duration=1000)
el意思是可以传入一个查找到的元素,
x,y意思是传入坐标点
duration,是长按的时间,单位毫秒,默认1s
driver=webdriver.Remote(server, desired_capabilities)
tc=TouchAction(driver)
driver.find_element_by_xpath("//*[contains(@text, 'WLAN')]").click()
time.sleep(2)
tc.long_press(driver.find_element_by_xpath("//*[contains(@text, 'SSID')]")).perform()
3.6.4移动move_to()方法
move_to(el=None, x=None, y=None):
这个方法跟前面的方法类似,第一个参数可以传入一个找到的元素,第二个和第三个元素可以传入坐标点,选择哪种方法都可以。
假如想要更改解锁图案为如图的样子:
代码可以如下:
#encoding=utf-8
from appium importwebdriverfrom appium.webdriver.common.touch_action importTouchActionfrom selenium.webdriver.support.wait importWebDriverWait
server= r'http://localhost:4723/wd/hub' #Appium Server, 端口默认为4723
desired_capabilities={'platformName': 'Android','deviceName': '127.0.0.1:62001', #需替换成你的deviceName
'platformVersion': '5.1.1','appPackage': 'com.android.settings','appActivity':'.ChooseLockPattern' #活动名,解锁图案的页面
}
driver=webdriver.Remote(server, desired_capabilities)
wdw= WebDriverWait(driver, 10, 1)
tc=TouchAction(driver)
tc.press(x=120, y=418)\
.move_to(x=360, y=418)\
.move_to(x=601, y=418)\
.move_to(x=600, y=656)\
.move_to(x=360, y=665)\
.move_to(x=360, y=895)\
.move_to(x=120, y=650)\
.release()\
.perform()
ps:这里需要注意一点,用UIAutomatorViewer工具找各个点的坐标找不到,这时候要用什么找呢?可以打开手机的开发者模式,用手机自带的指针位置功能。
打开方式:
进入设置->关于手机->多次点击版本号,就打开了开发者模式,找到”开发者选项”,按照图示打开:
move_to需要注意:
tc.press(x=120, y=418).wait(1000).move_to(x=360, y=418).release().perform()
tc.press(x=120, y=418).move_to(x=360, y=418).wait(1000).release().perform()
上面这两种写法,wait放置的地方不同,move_to出来的结果有可能不一样,上面这种写法就可以,下面那个就会滑偏,原因:第一个写法是因为脚本直接转换成了swipe的操作,认为是从哪里滑动到哪里,坐标点都是绝对坐标。
第二种写法会被认为是相对坐标,第二个坐标点就被appium改成相对于前面的坐标点的坐标了。
appium1.8版本以上的应该就不会这样了,两种写法都是按照绝对坐标去滑动。
3.7针对手机操作的API
3.7.1获取手机时间
device_time:
print(driver.device_time)
返回时间:2020-01-31T22:04:54+08:00
3.7.2获取手机分辨率
get_window_size():
print(driver.get_window_size())
返回一个字典:{'width': 720, 'height': 1280}
3.7.3打开通知栏
open_notifications():
driver.open_notifications()
关闭的话点击手机的返回就可以
3.7.4返回网络的连接类型
network_connection:
'''返回一个指定网络连接类型的整数位掩码(android)''',即下面的方法里面提到的数字
用法:driver.network_connection
3.7.5设置网络的连接(android)
set_network_connection(connectionType):
这个方法的参数可以直接写,0、1、2、4、6这几个数字,也可以写具体名如下:
NO_CONNECTION = 0
AIRPLANE_MODE = 1
WIFI_ONLY = 2
DATA_ONLY = 4
ALL_NETWORK_ON = 6
比如:
driver.set_network_connection(1)
等同于
driver.set_network_connection(ConnectionType.ALL_NETWORK_ON)
3.7.6截图
get_screenshot_as_file(路径):
把当前的页面截图放到对应路径中。
截图的方法:
driver.get_screenshot_as_file(“../xxx.png”)
比如出现bug的时候可以截图,或者有一些输入需要确认是否输入正确等都可以截图等case执行完毕后确认。
3.7.7检查app是否已安装
is_app_installed:
driver.is_app_installed("com.android.xxx")
3.7.8安装app
install_app:
driver.install_app(app_path)
3.7.9删除app
remove_app:
driver.remove_app(app_path)
3.7.10关掉app
close_app:
driver.close_app ()
3.7.11 keyevent()方法,通过keycode操作手机
keyevent(keycode):
driver.keyevent(24) # 音量加
如果在连接手机的代码里面,有automationName=’Uiautomator2’这样的配置,则应该使用下面这个指令:
press_keycode(keycode)
driver.press_keycode(24) # 音量加
3.7.12 keycode列表
基本按键
KEYCODE名称
按键
keycode
KEYCODE_0
按键'0'
7
KEYCODE_1
按键'1'
8
KEYCODE_2
按键'2'
9
KEYCODE_3
按键'3'
10
KEYCODE_4
按键'4'
11
KEYCODE_5
按键'5'
12
KEYCODE_6
按键'6'
13
KEYCODE_7
按键'7'
14
KEYCODE_8
按键'8'
15
KEYCODE_9
按键'9'
16
KEYCODE_A
按键'A'
29
KEYCODE_B
按键'B'
30
KEYCODE_C
按键'C'
31
KEYCODE_D
按键'D'
32
KEYCODE_E
按键'E'
33
KEYCODE_F
按键'F'
34
KEYCODE_G
按键'G'
35
KEYCODE_H
按键'H'
36
KEYCODE_I
按键'I'
37
KEYCODE_J
按键'J'
38
KEYCODE_K
按键'K'
39
KEYCODE_L
按键'L'
40
KEYCODE_M
按键'M'
41
KEYCODE_N
按键'N'
42
KEYCODE_O
按键'O'
43
KEYCODE_P
按键'P'
44
KEYCODE_Q
按键'Q'
45
KEYCODE_R
按键'R'
46
KEYCODE_S
按键'S'
47
KEYCODE_T
按键'T'
48
KEYCODE_U
按键'U'
49
KEYCODE_V
按键'V'
50
KEYCODE_W
按键'W'
51
KEYCODE_X
按键'X'
52
KEYCODE_Y
按键'Y'
53
KEYCODE_Z
按键'Z'
54
手柄按键
KEYCODE_BUTTON_1
通用游戏手柄按钮#1
188
KEYCODE_BUTTON_2
通用游戏手柄按钮 #2
189
KEYCODE_BUTTON_3
通用游戏手柄按钮 #3
190
KEYCODE_BUTTON_4
通用游戏手柄按钮 #4
191
KEYCODE_BUTTON_5
通用游戏手柄按钮 #5
192
KEYCODE_BUTTON_6
通用游戏手柄按钮 #6
193
KEYCODE_BUTTON_7
通用游戏手柄按钮 #7
194
KEYCODE_BUTTON_8
通用游戏手柄按钮 #8
195
KEYCODE_BUTTON_9
通用游戏手柄按钮 #9
196
KEYCODE_BUTTON_10
通用游戏手柄按钮 #10
197
KEYCODE_BUTTON_11
通用游戏手柄按钮 #11
198
KEYCODE_BUTTON_12
通用游戏手柄按钮 #12
199
KEYCODE_BUTTON_13
通用游戏手柄按钮 #13
200
KEYCODE_BUTTON_14
通用游戏手柄按钮 #14
201
KEYCODE_BUTTON_15
通用游戏手柄按钮 #15
202
KEYCODE_BUTTON_16
通用游戏手柄按钮 #16
203
KEYCODE_BUTTON_A
游戏手柄按钮 A
96
KEYCODE_BUTTON_B
游戏手柄按钮 B
97
KEYCODE_BUTTON_C
游戏手柄按钮 C
98
KEYCODE_BUTTON_X
游戏手柄按钮 X
99
KEYCODE_BUTTON_Y
游戏手柄按钮 Y
100
KEYCODE_BUTTON_Z
游戏手柄按钮 Z
101
KEYCODE_BUTTON_L1
游戏手柄按钮 L1
102
KEYCODE_BUTTON_L2
游戏手柄按钮 L2
104
KEYCODE_BUTTON_R1
游戏手柄按钮 R1
103
KEYCODE_BUTTON_R2
游戏手柄按钮 R2
105
KEYCODE_BUTTON_MODE
游戏手柄按钮 Mode
110
KEYCODE_BUTTON_SELECT
游戏手柄按钮 Select
109
KEYCODE_BUTTON_START
游戏手柄按钮 Start
108
KEYCODE_BUTTON_THUMBL
Left Thumb Button
106
KEYCODE_BUTTON_THUMBR
Right Thumb Button
107
电话按键
KEYCODE_CALL
拨号键
5
KEYCODE_ENDCALL
挂机键
6
KEYCODE_HOME
按键Home
3
KEYCODE_MENU
菜单键
82
KEYCODE_BACK
返回键
4
KEYCODE_SEARCH
搜索键
84
KEYCODE_CAMERA
拍照键
27
KEYCODE_FOCUS
拍照对焦键
80
KEYCODE_POWER
电源键
26
KEYCODE_NOTIFICATION
通知键
83
KEYCODE_MUTE
话筒静音键
91
KEYCODE_VOLUME_MUTE
扬声器静音键
164
KEYCODE_VOLUME_UP
音量增加键
24
KEYCODE_VOLUME_DOWN
音量减小键
25
控制按键
KEYCODE_ENTER
回车键
66
KEYCODE_ESCAPE
ESC键
111
KEYCODE_DPAD_CENTER
导航键 确定键
23
KEYCODE_DPAD_UP
导航键 向上
19
KEYCODE_DPAD_DOWN
导航键 向下
20
KEYCODE_DPAD_LEFT
导航键 向左
21
KEYCODE_DPAD_RIGHT
导航键 向右
22
KEYCODE_MOVE_HOME
光标移动到开始键
122
KEYCODE_MOVE_END
光标移动到末尾键
123
KEYCODE_PAGE_UP
向上翻页键
92
KEYCODE_PAGE_DOWN
向下翻页键
93
KEYCODE_DEL
退格键
67
KEYCODE_FORWARD_DEL
删除键
112
KEYCODE_INSERT
插入键
124
KEYCODE_TAB
Tab键
61
KEYCODE_NUM_LOCK
小键盘锁
143
KEYCODE_CAPS_LOCK
大写锁定键
115
KEYCODE_BREAK
Break/Pause键
121
KEYCODE_SCROLL_LOCK
滚动锁定键
116
KEYCODE_ZOOM_IN
放大键
168
KEYCODE_ZOOM_OUT
缩小键
169
组合键
KEYCODE_ALT_LEFT
Alt+Left
57
KEYCODE_ALT_RIGHT
Alt+Right
58
KEYCODE_CTRL_LEFT
Control+Left
113
KEYCODE_CTRL_RIGHT
Control+Right
114
KEYCODE_SHIFT_LEFT
Shift+Left
59
KEYCODE_SHIFT_RIGHT
Shift+Right
60
符号
KEYCODE_PLUS
按键'+'
81
KEYCODE_MINUS
按键'-'
69
KEYCODE_STAR
按键'*'
17
KEYCODE_SLASH
按键'/'
76
KEYCODE_EQUALS
按键'='
70
KEYCODE_AT
按键'@'
77
KEYCODE_POUND
按键'#'
18
KEYCODE_APOSTROPHE
按键''' (单引号)
75
KEYCODE_BACKSLASH
按键'\'
73
KEYCODE_COMMA
按键','
55
KEYCODE_PERIOD
按键'.'
56
KEYCODE_LEFT_BRACKET
按键'['
71
KEYCODE_RIGHT_BRACKET
按键']'
72
KEYCODE_SEMICOLON
按键';'
74
KEYCODE_GRAVE
按键'`'
68
KEYCODE_SPACE
空格键
62
小键盘
KEYCODE_NUMPAD_0
小键盘按键'0'
144
KEYCODE_NUMPAD_1
小键盘按键'1'
145
KEYCODE_NUMPAD_2
小键盘按键'2'
146
KEYCODE_NUMPAD_3
小键盘按键'3'
147
KEYCODE_NUMPAD_4
小键盘按键'4'
148
KEYCODE_NUMPAD_5
小键盘按键'5'
149
KEYCODE_NUMPAD_6
小键盘按键'6'
150
KEYCODE_NUMPAD_7
小键盘按键'7'
151
KEYCODE_NUMPAD_8
小键盘按键'8'
152
KEYCODE_NUMPAD_9
小键盘按键'9'
153
KEYCODE_NUMPAD_ADD
小键盘按键'+'
157
KEYCODE_NUMPAD_SUBTRACT
小键盘按键'-'
156
KEYCODE_NUMPAD_MULTIPLY
小键盘按键'*'
155
KEYCODE_NUMPAD_DIVIDE
小键盘按键'/'
154
KEYCODE_NUMPAD_EQUALS
小键盘按键'='
161
KEYCODE_NUMPAD_COMMA
小键盘按键','
159
KEYCODE_NUMPAD_DOT
小键盘按键'.'
158
KEYCODE_NUMPAD_LEFT_PAREN
小键盘按键'('
162
KEYCODE_NUMPAD_RIGHT_PAREN
小键盘按键')'
163
KEYCODE_NUMPAD_ENTER
小键盘按键回车
160
功能键
KEYCODE_F1
按键F1
131
KEYCODE_F2
按键F2
132
KEYCODE_F3
按键F3
133
KEYCODE_F4
按键F4
134
KEYCODE_F5
按键F5
135
KEYCODE_F6
按键F6
136
KEYCODE_F7
按键F7
137
KEYCODE_F8
按键F8
138
KEYCODE_F9
按键F9
139
KEYCODE_F10
按键F10
140
KEYCODE_F11
按键F11
141
KEYCODE_F12
按键F12
142
多媒体键
KEYCODE_MEDIA_PLAY
多媒体键 播放
126
KEYCODE_MEDIA_STOP
多媒体键 停止
86
KEYCODE_MEDIA_PAUSE
多媒体键 暂停
127
KEYCODE_MEDIA_PLAY_PAUSE
多媒体键 播放/暂停
85
KEYCODE_MEDIA_FAST_FORWARD
多媒体键 快进
90
KEYCODE_MEDIA_REWIND
多媒体键 快退
89
KEYCODE_MEDIA_NEXT
多媒体键 下一首
87
KEYCODE_MEDIA_PREVIOUS
多媒体键 上一首
88
KEYCODE_MEDIA_CLOSE
多媒体键 关闭
128
KEYCODE_MEDIA_EJECT
多媒体键 弹出
129
KEYCODE_MEDIA_RECORD
多媒体键 录音
130
其他
KEYCODE_NUM
按键Number modifier
78
KEYCODE_INFO
按键Info
165
KEYCODE_APP_SWITCH
按键App switch
187
KEYCODE_BOOKMARK
按键Bookmark
174
KEYCODE_AVR_INPUT
按键A/V Receiver input
182
KEYCODE_AVR_POWER
按键A/V Receiver power
181
KEYCODE_CAPTIONS
按键Toggle captions
175
KEYCODE_CHANNEL_DOWN
按键Channel down
167
KEYCODE_CHANNEL_UP
按键Channel up
166
KEYCODE_CLEAR
按键Clear
28
KEYCODE_DVR
按键DVR
173
KEYCODE_ENVELOPE
按键Envelope special function
65
KEYCODE_EXPLORER
按键Explorer special function
64
KEYCODE_FORWARD
按键Forward
125
KEYCODE_FORWARD_DEL
按键Forward Delete
112
KEYCODE_FUNCTION
按键Function modifier
119
KEYCODE_GUIDE
按键Guide
172
KEYCODE_HEADSETHOOK
按键Headset Hook
79
KEYCODE_META_LEFT
按键Left Meta modifier
117
KEYCODE_META_RIGHT
按键Right Meta modifier
118
KEYCODE_PICTSYMBOLS
按键Picture Symbols modifier
94
KEYCODE_PROG_BLUE
按键Blue “programmable”
186
KEYCODE_PROG_GREEN
按键Green “programmable”
184
KEYCODE_PROG_RED
按键Red “programmable”
183
KEYCODE_PROG_YELLOW
按键Yellow “programmable”
185
KEYCODE_SETTINGS
按键Settings
176
KEYCODE_SOFT_LEFT
按键Soft Left
1
KEYCODE_SOFT_RIGHT
按键Soft Right
2
KEYCODE_STB_INPUT
按键Set-top-box input
180
KEYCODE_STB_POWER
按键Set-top-box power
179
KEYCODE_SWITCH_CHARSET
按键Switch Charset modifier
95
KEYCODE_SYM
按键Symbol modifier
63
KEYCODE_SYSRQ
按键System Request / Print Screen
120
KEYCODE_TV
按键TV
170
KEYCODE_TV_INPUT
按键TV input
178
KEYCODE_TV_POWER
按键TV power
177
KEYCODE_WINDOW
按键Window
171
KEYCODE_UNKNOWN
未知按键
0