appium移动自动化详解

栏目: IT技术 · 发布时间: 4年前

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 import webdriver

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 的时候还会打开一个黑框,这个黑框别关)

appium移动自动化详解

第二步,打开你的虚拟器或者真机中的需要测试的 APP ,比如我现在测试设置,我就打开设置,如图:

appium移动自动化详解

第三步:点击第一步图示的圈红按钮,点击后等待一会,会出来如下图:

appium移动自动化详解

第四步,出来上图后,想要哪个按钮的 id 或者 name ,就用鼠标点到哪个按钮上,比如我想要看更多按钮的信息,点击“更多”,就在右面界面中出来了 text id class 等信息,其中的 resourse-id 就是 id 名。

appium移动自动化详解

第五步:这个工具还可以保存当前页面,这样方便以后多次查看当前页面的控件内容,而不用每次去打开 APP ,操作步骤,点击保存按钮,工具栏里面的第四个按钮,保存后,会同时保存两个文件,一个 png 文件,一个 uix 文件。保存后怎么打开呢?点击工具上的第一个按钮, open ,点击后会弹出一个框,如图:

appium移动自动化详解

上面那个路径是刚才保存的 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 import webdriver
import time

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 import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time

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 坐标点值越大。

appium移动自动化详解

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.1 swipe :从 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.3 drag 拖拽事件

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 import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time

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)

while True:
    try:
        about_button = driver.find_element_by_xpath("//*[contains(@text, '关于')]")
        about_button.click()
        time.sleep(2)
        break
    except Exception:
        # 向下翻页
        # 这里还要注意,翻完页之后,上一页的最下面的元素还应该在页面上,以免丢失元素
        driver.swipe(320,1081,320,500,3000)
        # 判断关于我们页面是否有5.1.1
        eles = driver.find_elements_by_id("android:id/summary")
        for i in eles:
            # 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 import webdriver

from 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)

这个方法跟前面的方法类似,第一个参数可以传入一个找到的元素,第二个和第三个元素可以传入坐标点,选择哪种方法都可以。

假如想要更改解锁图案为如图的样子:

appium移动自动化详解

代码可以如下:

# encoding=utf-8

from appium import webdriver

from appium.webdriver.common.touch_action import TouchAction

from selenium.webdriver.support.wait import WebDriverWait

 

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 工具找各个点的坐标找不到,这时候要用什么找呢?可以打开手机的开发者模式,用手机自带的指针位置功能。

打开方式:

进入设置 -> 关于手机 -> 多次点击版本号,就打开了开发者模式,找到开发者选项,按照图示打开:

appium移动自动化详解

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Computer Vision with Python

Programming Computer Vision with Python

Jan Erik Solem / O'Reilly Media / 2012-6-22 / USD 39.99

If you want a basic understanding of computer vision's underlying theory and algorithms, this hands-on introduction is the ideal place to start. As a student, researcher, hacker, or enthusiast, you'll......一起来看看 《Programming Computer Vision with Python》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具