How to determine whether softkeyboard is shown on

2019-03-31 09:04发布

I am trying to automate few screen clicks and entries using monkeyrunner(using AndroidViewClient )

Whenever there is a edittext in the screen, the soft keyboard is popping up, and if I want to press a button though findViewById, (assuming that this particular button is behind the soft keyboard) fails. Instead of clicking this button, it clicks on some button in the soft keyboard. So as a work around I need to press back key through monkey runner, to hide the soft keyboard.

My question is how to determine whether soft keyboard is shown in the screen or not while running from monkeyrunner.

When I looked at the logcat, I see this following while showing up the soft keyboard

I/SurfaceFlinger( 2045): id=143(28) createSurf 0x4326743c (720x593),1 flag=0, InputMethod

and displays this while softkeyboard is removed

I/SurfaceFlinger( 2045): id=142 Removed InputMethod idx=4 MapSz=3
I/SurfaceFlinger( 2045): id=142 Removed InputMethod idx=-2 MapSz=3

If someone can provide an example of how to parse the adb logcat output from the monkeyrunner script, I can use that as a last option, if there is any suitable alternative solution found.

4条回答
Fickle 薄情
2楼-- · 2019-03-31 09:15

I found a way to overcome this problem. When I looked in the adb shell dumpsys input_method, I could see "mInputShown=true". So based on that I wrote the following function.

def isKeyboardShown():                                                                                                                                                                                          
     return "mInputShown=true" in call_shell_cmd("adb shell dumpsys input_method")
查看更多
混吃等死
3楼-- · 2019-03-31 09:16

What you mentioned in your answer could be a great addition to AndroidViewClient and I'll try to incorporate it soon.

Anyway, there is a method of getting the same info, though in a more convoluted way:

...
from com.dtmilano.android.viewclient import ViewClient

vc = ViewClient(*ViewClient.connectToDeviceOrExit())
view = vc.findViewByIdOrRaise('id/no_id/1')
view.getXY() # getXY() calls __dumpsWindowsInformation()
for w in view.windows:
    if view.windows[w].activity == 'InputMethod':
        print view.windows[w].visibility

Update on 11-FEB-15

Latest AndroidViewClient/culebra versions support isKeyboardShown() method. Use like this:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
Copyright (C) 2013-2014  Diego Torres Milano
Created on 2015-02-11 by Culebra v10.0.8
                      __    __    __    __
                     /  \  /  \  /  \  /  \ 
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \   \___
                   |/   \_/   \_/   \_/   \    o \ 
                                           \_____/--<
@author: Diego Torres Milano
@author: Jennifer E. Swofford (ascii art snake)
'''


import re
import sys
import os


try:
    sys.path.insert(0, os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
    pass

from com.dtmilano.android.viewclient import ViewClient

TAG = 'CULEBRA'

_s = 5
_v = '--verbose' in sys.argv


kwargs1 = {'ignoreversioncheck': False, 'verbose': False, 'ignoresecuredevice': False}
device, serialno = ViewClient.connectToDeviceOrExit(**kwargs1)
print "Is keyboard shown:", device.isKeyboardShown()
查看更多
聊天终结者
4楼-- · 2019-03-31 09:20
def isKeyboardShown(self):
#Whether the keyboard is displayed.
   return self.device.isKeyboardShown()

LinkRefer

We can use isKeyboardShown() function by importing view-client to
validate whether the soft Keyboard is displayed or not .
查看更多
甜甜的少女心
5楼-- · 2019-03-31 09:28

There is a way of doing what you want using the adb shell from monkeyrunner and it doesn't require a separate third-party library.

if ('mInputShown=true' in device.shell('dumpsys input_method')):
    <conditional code for when soft keyboard is showing goes here>

or

if ('mInputShown=false' in device.shell('dumpsys input_method')):
    <conditional code for when soft keyboard is not showning goes here>

where device is the instance of MonkeyDevice for the attached device.

I've found that applications that usually show a soft keyboard for input upon manual launch don't reliably show one when launched with monkeyrunner. If script logic depends on wehther the soft keyboard is showing or not, I use the above tests in the script to check if the soft keyboard is showing or not.

The following explanation includes some thinking about how to solve problems of this type.

adb shell dumpsys

returns a very large and detailed dump of all services running on the device. The dumpsys dump may be requested for a single service, in our case, the input services. That usage is

adb shell dumpsys input_method

which will return a much smaller dump which is just the current input method manager state. That dump will include all curent InputMethod instances, input method manager clients with general parameters for input method manager clients, input method client state, and input method server state. One set of general parameters for input method manager clients relates to whether an input method is shown (e.g. soft keyboard) and some parameters about whether the input method show was requested, explicitly requested or forced and whether it is being shown.

Whether the input method is shown is the one of interest since it is true when the soft keyboard is showing and false when the soft keyboard is not showing. That parameter's name is

mInputShown

and will look like

mInputShown=true

or

mInputShown=false

depending on whether the soft keyboard is showing or not.

The next step is making use of this information in a monkeyrunner script. The MonkeyDevice class includes a method for running an ADB shell command from within monkeyrunner's use of the bridge and which returns an object which is the return value to the ADB shell from executing the ADB shell command. Within a monkeyrunner script, that looks like

shell_cmd_return_stuff = device.shell('dumpsys input_method')

where device is the instance of the MonkeyDevice class for the attached device and shell_cmd_return_stuff is variable holding all the shell command's output -- in this case the dump output. Finally, since we are looking for a specific parameter/value pair in the text and know what it looks like, we can use standard Jython to look for that string within the output returned without saving it in a variable and using the Jython string in boolean operator

if ('mInputShown=true' in device.shell('dumpsys input_method')):
    <conditional code for when soft keyboard is showing goes here>

or

if ('mInputShown=false' in device.shell('dumpsys input_method')):
    <conditional code for when soft keyboard is not showning goes here>

depending on wehther we want to know if the soft keyboard is currently showing or not showing.

Enjoy!

查看更多
登录 后发表回答