package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiObjectNotFoundException; import io.appium.android.bootstrap.*; import org.json.JSONException; /** * This handler is used to get the text of elements that support it. * */ public class GetName extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { if (!command.isElementCommand()) { return getErrorResult("Unable to get name without an element."); } try { final AndroidElement el = command.getElement(); return getSuccessResult(el.getContentDesc()); } catch (final UiObjectNotFoundException e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } catch (final Exception e) { // handle NullPointerException return getErrorResult("Unknown error"); } } }
最终会调用UiObject.getContentDescription()方法获得控件当描述信息
package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiObjectNotFoundException; import io.appium.android.bootstrap.*; import io.appium.android.bootstrap.exceptions.NoAttributeFoundException; import org.json.JSONException; import java.util.Hashtable; /** * This handler is used to get an attribute of an element. * */ public class GetAttribute extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { if (command.isElementCommand()) { // only makes sense on an element final Hashtable<String, Object> params = command.params(); try { final AndroidElement el = command.getElement(); final String attr = params.get("attribute").toString(); if (attr.equals("name") || attr.equals("text") || attr.equals("className")) { return getSuccessResult(el.getStringAttribute(attr)); } else { return getSuccessResult(String.valueOf(el.getBoolAttribute(attr))); } } catch (final NoAttributeFoundException e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } catch (final UiObjectNotFoundException e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } catch (final Exception e) { // el is null return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } } else { return getErrorResult("Unable to get attribute without an element."); } } }
该事件是为获取控件相关信息设置的,来看看可以获取哪些信息,其实就是uiautomatorviewer里的信息。
public String getStringAttribute(final String attr) throws UiObjectNotFoundException, NoAttributeFoundException { String res; if (attr.equals("name")) { res = getContentDesc(); if (res.equals("")) { res = getText(); } } else if (attr.equals("text")) { res = getText(); } else if (attr.equals("className")) { res = getClassName(); } else { throw new NoAttributeFoundException(attr); } return res; }
文本值:content-desc、text、className.
public boolean getBoolAttribute(final String attr) throws UiObjectNotFoundException, NoAttributeFoundException { boolean res; if (attr.equals("enabled")) { res = el.isEnabled(); } else if (attr.equals("checkable")) { res = el.isCheckable(); } else if (attr.equals("checked")) { res = el.isChecked(); } else if (attr.equals("clickable")) { res = el.isClickable(); } else if (attr.equals("focusable")) { res = el.isFocusable(); } else if (attr.equals("focused")) { res = el.isFocused(); } else if (attr.equals("longClickable")) { res = el.isLongClickable(); } else if (attr.equals("scrollable")) { res = el.isScrollable(); } else if (attr.equals("selected")) { res = el.isSelected(); } else if (attr.equals("displayed")) { res = el.exists(); } else { throw new NoAttributeFoundException(attr); } return res; }
boolean类型的值:如上等等。
package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiDevice; import io.appium.android.bootstrap.AndroidCommand; import io.appium.android.bootstrap.AndroidCommandResult; import io.appium.android.bootstrap.CommandHandler; import org.json.JSONException; import org.json.JSONObject; /** * This handler is used to get the size of the screen. * */ public class GetDeviceSize extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) { if (!command.isElementCommand()) { // only makes sense on a device final UiDevice d = UiDevice.getInstance(); final JSONObject res = new JSONObject(); try { res.put("height", d.getDisplayHeight()); res.put("width", d.getDisplayWidth()); } catch (final JSONException e) { getErrorResult("Error serializing height/width data into JSON"); } return getSuccessResult(res); } else { return getErrorResult("Unable to get device size on an element."); } } }
获取屏幕的长和宽,调用的是UiDevice的方法:getDisplayHeight()和getDisplayWidth()
package io.appium.android.bootstrap.handler; import android.graphics.Rect; import com.android.uiautomator.core.UiObjectNotFoundException; import io.appium.android.bootstrap.*; import org.json.JSONException; import org.json.JSONObject; /** * This handler is used to get the size of elements that support it. * */ public class GetSize extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { if (command.isElementCommand()) { // Only makes sense on an element final JSONObject res = new JSONObject(); try { final AndroidElement el = command.getElement(); final Rect rect = el.getBounds(); res.put("width", rect.width()); res.put("height", rect.height()); } catch (final UiObjectNotFoundException e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } catch (final Exception e) { // handle NullPointerException return getErrorResult("Unknown error"); } return getSuccessResult(res); } else { return getErrorResult("Unable to get text without an element."); } } }
获取控件的宽和高,调用的是UiObject的getBounds()。得到一个矩形,然后获得其宽和高。
package io.appium.android.bootstrap.handler; import android.graphics.Rect; import io.appium.android.bootstrap.*; import org.json.JSONException; import org.json.JSONObject; /** * This handler is used to get the text of elements that support it. * */ public class GetLocation extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { if (!command.isElementCommand()) { return getErrorResult("Unable to get location without an element."); } try { final JSONObject res = new JSONObject(); final AndroidElement el = command.getElement(); final Rect bounds = el.getBounds(); res.put("x", bounds.left); res.put("y", bounds.top); return getSuccessResult(res); } catch (final Exception e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } } }
获取控件的起始点坐标。调用的也是getBounds,然后得到其起始点的x,y 坐标
package io.appium.android.bootstrap.handler; import android.os.Environment; import io.appium.android.bootstrap.AndroidCommand; import io.appium.android.bootstrap.AndroidCommandResult; import io.appium.android.bootstrap.CommandHandler; /** * This handler is used to get the data dir. * */ public class GetDataDir extends CommandHandler { /* * @param command The {@link AndroidCommand} used for this handler. * * @return {@link AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) { return getSuccessResult(Environment.getDataDirectory()); } }
获取data的根目录。调用的是android的api:Environment.getDataDirectory()