appium移動自動化詳解
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的時候還會開啟一個黑框,這個黑框別關)
第二步,開啟你的虛擬器或者真機中的需要測試的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 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座標點值越大。
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):
這個方法跟前面的方法類似,第一個引數可以傳入一個找到的元素,第二個和第三個元素可以傳入座標點,選擇哪種方法都可以。
假如想要更改解鎖圖案為如圖的樣子:
程式碼可以如下:
# 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工具找各個點的座標找不到,這時候要用什麼找呢?可以開啟手機的開發者模式,用手機自帶的指標位置功能。
開啟方式:
進入設定->關於手機->多次點選版本號,就打開了開發者模式,找到”開發者選項”,按照圖示開啟:
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 |