我怎样才能得到所有组件和Widget目前Android窗口画面的标识编程?组件、标识、画面、目前

2023-09-07 04:40:16 作者:若、只如当初っ

我用Robotium框架Android的测试目的,采取手动或COMPONENT_ID索引ID或窗口小部件的其他部分从层次结构查看器将值在运行时为测试目的。

有没有办法采取COMPONENT_ID或索引ID或窗口小部件编程的其他部分?到目前为止,我能够获得包名称和包装的应用在所有的活动名称。

解决方案

 导入时,子进程,插座,再afttFile =打开(ApplicationPackage.DOC,R)文件名=的packageName =activityName =packageFile =无window_dump =无current_window =无窗户=无#Function执行的adb shell命令高清ADB(命令,输入=无):    如果不是isinstance(命令列表):命令= command.split()    返回subprocess.Popen(指挥,标准输出= subprocess.PIPE,                        标准错误= subprocess.STDOUT).communicate(输入=输入)[0]#Function获取当前窗口的哈希ID高清getWindowHash():    命令='亚行的shell    window_dump = subprocess.Popen(命令+'dumpsys窗口的窗口',壳=假,标准输出= subprocess.PIPE)    window_dump = window_dump.stdout.read()    正则表达式= re.compile(r'Window#\\ D +:\\ S \\ r \\ n]的?。+窗口\\ {(P<散> [AF \\ D] {8})(P<标题> *)暂停?= * \\}:\\ r \\ n] +(?P<&属性GT;(?:* [\\ r \\ n] +)+),re.MULTILINE)    WINDOWS = [m.groupdict()来米regexp.finditer(window_dump)    #取当前窗口    M = re.search('mCurrentFocus =窗口\\ {(P<&哈希GT; \\ S +)(P<标题> \\ S *)\\ S +',window_dump)    如果m:        current_window = m.groupdict()        #PRINT self.current_window    其他:        current_window =无    在Windows窗口:        如果窗口['散'] == current_window ['散']:            返回[窗口] [0] ['散']#阅读Packag名称和放大器;从提供的文件中都有相应活动名称在afttFile行:    #PRINT线    如果len(line.split(。))== 3:        如果packageFile =无!            packageFile.flush()            packageFile.close()            #PRINT文件名称为:+文件名+封闭        的packageName = line.strip(\\ n)        打印包名:+的packageName        文件名= line.split(。)[2] .strip(\\ n)+。TXT        #PRINT文件名        与相应的软件包名称#​​创建文件        packageFile =打开(文件名,A)        #packageFile.flush()        #packageFile.close()    其他:        activityName = line.strip(\\ n)        打印活动名称:+ activityName        ##,如果的packageName ==com.android.browser:             ## #PRINT的packageName             ## ommand =ADB -s模拟器-5554外壳上午开始-a -n android.intent.MAIN+的packageName +/+ activityName             ##打印命令             ## ##结果= subprocess.Popen(指挥,外壳=假,标准输出= subprocess.PIPE)             ## ##结果= result.stdout.read()        #PRINT的packageName        如果的packageName ==com.android.mms:            命令=亚行外壳上午开始-n+的packageName +/+ activityName            打印命令            结果= subprocess.Popen(指挥,外壳=假,标准输出= subprocess.PIPE)            结果= result.stdout.read()            time.sleep(10)            打印分析已经开始            F =打开(AFTT.txt,W)            命令='亚行的shell            COMM ='亚'            对于端口范围(5939,5979,2):                尝试:                    S = socket.socket(socket.AF_INET,socket.SOCK_STREAM)                    subprocess.Popen(命令+'服务呼叫窗口2',壳=假,标准输出= subprocess.PIPE)                    time.sleep(0.5)                    subprocess.Popen(命令+'服务呼叫窗口1 I32 4939',壳=假,标准输出= subprocess.PIPE)                    time.sleep(0.5)                    亚洲开发银行(COMM +'转发TCP:%d个TCP:4939'%端口)                    打印转发做过                    s.connect((127.0.0.1,口))                    #PRINT作了                    打印用于通信的端口:%的端口%                    hashId = getWindowHash()                    打印窗口Hash_Id:%的%ha​​shId                    s.sendall('DUMP%S \\ n'%hashId)                    打印命令发送                    s.settimeout(360)                    数据=''                    I = 0                    T0 =​​选定了time.time()                    打印启动循环                    而真正的:                        基准= s.recv(32 * 1024)                        #PRINT基准                        #PRINT收到%d字节'%LEN(基准面)                        #PRINT\\ n                        打印数据包+基准                        f.write(基准面)                        如果(datum.endswith('\\ nDONE。\\ n)或datum.endswith('DONE。\\ n)或datum.endswith('\\ nDONE。\\ nDONE \\ n')或datum.endswith('DONE。\\ nDONE \\ n')):                            #PRINT包转让(BOT)的终结                            打破                        如果数据=='':                            #PRINT关闭套接字                            提高socket.error('插座关闭)                        数据+ =基准                        如果选定了time.time() -  T 0> 360:                            #PRINT超时                            提高socket.error(超时)                        I = I + 1                    打破                除了socket.error:                    #PRINT检查另一个端口                    subprocess.Popen(命令+'服务呼叫窗口2',壳=假,标准输出= subprocess.PIPE)                    time.sleep(0.5)                    subprocess.Popen(命令+'服务呼叫窗口1 I32 4939',壳=假,标准输出= subprocess.PIPE)                    time.sleep(0.5)                    #f.close()                    S.CLOSE()                    #PRINT服务器重新启动            为了解析UI元素#Open文件            F =打开(AFTT.txt,R)            #包=打开(Package.txt,W)            在F线:                widg_id = re.compile(r'mID = \\ S *',re.MULTILINE).findall(行)                widg_text = re.compile(r'mText = \\ D *,[A-ZA-Z \\ W \\ D] *',re.MULTILINE).findall(行)                如果len(widg_id)= 0或LEN(widg_text)!= 0!                    ################################################## ################                    #Parse小部件ID                    如果len(widg_id)= 0!                        widg_id = widg_id [0]                        widg_id = STR(widg_id)                        widg_id = widg_id.strip([]')                        如果widg_idID:                            widg_id = widg_id.split(,)[1] .split(/)[1]                        其他:                            widg_id = widg_id.split(,)[1]                        packageFile.write(widg_id + - >中)                    其他:                        packageFile.write(无 - >中)                    ################################################## ################                    #Parse文字的Widget                    如果len(widg_text)= 0!                        widg_text = STR(widg_text)                        #Remove从字符串unncessary字符                        widg_text = widg_text.strip([]')                        #获取即不包括多行文字的第二个元素                        widg_text = widg_text.split(,)[1]                        对空间的基础上#SPlit文本                        widg_text_ls = widg_text.split()                        widg_text =                        #Remove从上一个元素                        widg_text_ls.pop()                        #创建新的字符串通过加入列表                        widg_text =。加入(widg_text_ls)                        如果len(widg_text)== 0:                            packageFile.write(无 - >中)                        其他:                            packageFile.write(widg_text + - >中)                    其他:                        packageFile.write(无 - >中)                    ################################################## ################                    #Parse小部件类型                    widg_type = STR(line.split(@)[0])                    widg_type = widg_type.strip()                    packageFile.write(widg_type)                    packageFile.write(\\ n)            f.close()afttFile.close() 

I use Robotium Framework for Android testing purpose and manually take component_id or index id or else part of Widgets from Hierarchy Viewer to put value at runtime for testing purpose.

Android Widget设计指南 1

Is there any way to take component_id or index id or else part of Widgets Programmatically? So far I'm able to get package name and all activity names under that package application.

解决方案

import time, subprocess, socket, re

afttFile=open("ApplicationPackage.DOC", "r")

fileName=""
packageName=""
activityName=""
packageFile=None

window_dump=None
current_window=None
windows=None


#Function for executing adb shell command
def adb(command, input=None):
    if not isinstance(command,list): command=command.split()
    return subprocess.Popen(command, stdout=subprocess.PIPE, 
                        stderr=subprocess.STDOUT).communicate(input=input)[0]


#Function for getting current window hash id
def getWindowHash():
    command='adb shell ' 

    window_dump=subprocess.Popen(command+'dumpsys window windows', shell=False, stdout=subprocess.PIPE)
    window_dump=window_dump.stdout.read()

    regexp=re.compile(r'Window #\d+[:\s\r\n]+Window\{(?P<hash>[a-f\d]{8}) (?P<title>.*) paused=.*\}:?[\r\n]+(?P<attributes>(?:    .*[\r\n]+)+)', re.MULTILINE)

    windows=[ m.groupdict() for m in regexp.finditer(window_dump) ]

    # fetch current window
    m=re.search('mCurrentFocus=Window\{(?P<hash>\S+) (?P<title>\S*) \S+', window_dump)
    if m:
        current_window=m.groupdict()
        #print self.current_window
    else:
        current_window=None

    for window in windows:
        if window['hash']==current_window['hash']:
            return [window][0]['hash']


#Read Packag Name & Corresponding Activity Name from Provided file
for line in afttFile:
    #print line
    if len(line.split("."))==3:
        if packageFile!=None:
            packageFile.flush()
            packageFile.close()
            #print "File with name: "+fileName+" closed"

        packageName=line.strip("\n")
        print "Package Name: "+packageName
        fileName=line.split(".")[2].strip("\n")+".txt"
        #print fileName
        #Create file with corresponding package name
        packageFile=open(fileName, "a")

        #packageFile.flush()
        #packageFile.close()
    else:
        activityName=line.strip("\n")
        print "Activity Name: "+activityName
        ## if packageName=="com.android.browser":
             ## #print packageName
             ## ommand="adb -s emulator-5554 shell am start -a android.intent.MAIN -n "+packageName+"/"+activityName
             ## print command
             ## ## result=subprocess.Popen(command, shell=False, stdout=subprocess.PIPE)
             ## ## result=result.stdout.read()

        #print packageName
        if packageName=="com.android.mms":
            command="adb shell am start -n "+packageName+"/"+activityName
            print command
            result=subprocess.Popen(command, shell=False, stdout=subprocess.PIPE)
            result=result.stdout.read()
            time.sleep(10)

            print "Parsing has been started"
            f=open("AFTT.txt", "w")

            command='adb shell '      
            comm='adb '

            for port in range(5939,5979,2):   
                try:              
                    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
                    subprocess.Popen(command+'service call window 2', shell=False, stdout=subprocess.PIPE)
                    time.sleep(.5)
                    subprocess.Popen(command+'service call window 1 i32 4939', shell=False, stdout=subprocess.PIPE)
                    time.sleep(.5)

                    adb(comm+' forward tcp:%d tcp:4939' % port)
                    print "forwarding done"

                    s.connect(('127.0.0.1', port))
                    #print "Connection Made"
                    print "Port Used for Communication: %s" %port
                    hashId=getWindowHash()
                    print "Window Hash_Id: %s" %hashId

                    s.sendall('DUMP %s\n'%hashId)
                    print "Command sent"
                    s.settimeout(360)
                    data=''
                    i=0
                    t0 = time.time()            
                    print "Starting loop"
                    while True:
                        datum=s.recv(32*1024)
                        #print datum
                        #print 'Received %d bytes' % len(datum)        
                        #print "\n"
                        print "Packet: "+datum
                        f.write(datum)

                        if (datum.endswith('\nDONE.\n') or datum.endswith('DONE.\n') or datum.endswith('\nDONE.\nDONE\n') or datum.endswith('DONE.\nDONE\n')):
                            #print "End of Packet ransfer"
                            break 

                        if datum == '':
                            #print "Socket closed"
                            raise socket.error('Socket closed')

                        data+=datum

                        if time.time() - t0 > 360:
                            #print "Timeout"
                            raise socket.error('Timeout')                
                        i=i+1
                    break

                except socket.error:
                    #print "Checking for another port"
                    subprocess.Popen(command+'service call window 2', shell=False, stdout=subprocess.PIPE)
                    time.sleep(.5)
                    subprocess.Popen(command+'service call window 1 i32 4939', shell=False, stdout=subprocess.PIPE)
                    time.sleep(.5)
                    #f.close()
                    s.close()
                    #print "Server restarted"

            #Open File for Parsing UI Elements
            f=open("AFTT.txt", "r")
            #package=open("Package.txt", "w")
            for line in f:
                widg_id=re.compile(r'mID=\S*', re.MULTILINE).findall(line)
                widg_text=re.compile(r'mText=\d*,[a-zA-Z\W\d]*', re.MULTILINE).findall(line)

                if len(widg_id)!=0 or len(widg_text)!=0:
                    ##################################################################
                    #Parse Widget Id
                    if len(widg_id)!=0:
                        widg_id=widg_id[0]        
                        widg_id=str(widg_id) 
                        widg_id=widg_id.strip("[]'")
                        if 'id' in widg_id:
                            widg_id=widg_id.split(",")[1].split("/")[1]
                        else:
                            widg_id=widg_id.split(",")[1]   
                        packageFile.write(widg_id+"->")
                    else:
                        packageFile.write("None->")

                    ##################################################################    
                    #Parse Widget Text
                    if len(widg_text)!=0:
                        widg_text=str(widg_text)
                        #Remove unncessary characters from String
                        widg_text=widg_text.strip("[]'")

                        #Get the second element that is excluding 'mText'
                        widg_text=widg_text.split(",")[1]

                        #SPlit text on basis of space
                        widg_text_ls=widg_text.split(" ")

                        widg_text=""
                        #Remove one element from last
                        widg_text_ls.pop()        
                        #Create new STring by joining list
                        widg_text=" ".join(widg_text_ls)       

                        if len(widg_text)==0:
                            packageFile.write("None->")
                        else:
                            packageFile.write(widg_text+"->")
                    else:
                        packageFile.write("None->")

                    ##################################################################    
                    #Parse Widget Type
                    widg_type=str(line.split("@")[0])
                    widg_type=widg_type.strip(" ")
                    packageFile.write(widg_type)
                    packageFile.write("\n")
            f.close()    
afttFile.close()