Release 2.0.1Beta

This commit is contained in:
hyb1996
2017-03-19 16:21:07 +08:00
parent 85affed538
commit dd787236e7
110 changed files with 2428 additions and 4710 deletions

View File

@@ -53,6 +53,11 @@
"title": "需要Root权限的自动操作函数",
"type": "markdown",
"path":"documentation"
},
{
"title": "调用Java API",
"type": "markdown",
"path":"documentation"
}
],
"EMCAScript教程": [

View File

@@ -27,6 +27,7 @@ if(result.code == 1){
* [应用包名](#应用包名)
* [pm命令](#pm命令)
* [其他命令](#其他命令)
* [Shell类](#Shell类)
## am命令
@@ -356,4 +357,41 @@ ls filepath
例如:
```
log(shell("ls /system/bin"));
```
```
## Shell类
当需要连续执行很多命令时每条命令都需要申请Root权限执行时间会大大增加。这时可以使用Shell类。
### new Shell(root = false)
* root \<Boolean\> 是否以root权限执行。默认为false。
Shell类的构造函数。
### Shell.execute(cmd)
* cmd \<String\> 要执行的命令
执行命令cmd例如
```
var sh = Shell(true);
sh.execute("rm /sdcard/1.txt"); //删除SD卡上的1.txt文件
```
### Shell.exitAndWaitFor()
退出Shell并等待所有命令执行完成。
一个完整的例子如下:
```
var sh = Shell(true);
sh.execute("rm /sdcard/1.txt");
sh.execute("input keyevent 26");
sh.exitAndWaitFor();
```
### Shell.waitFor()
等待当前所有命令执行完成。返回一个整数作为返回码1为执行成功其他数字为错误。
### Shell.exit()
退出Shell。调用该函数后再执行的命令无效。
除以上命令之外, Shell也包含自动操作的命令例如Shell.Tap参见《需要Root权限的自动操作函数》。

View File

@@ -20,10 +20,10 @@ launchPackage("com.tencent.mm");
launchApp("微信");
```
### getPackageName()
### currentPackage()
返回最近一次监测到的正在运行的应用的包名,一般可以认为就是当前正在运行的应用的包名。
### getActivityName()
### currentActivity()
返回最近一次监测到的正在运行的Activity的名称一般可以认为就是当前正在运行的Activity的名称。
### setClip(text)

View File

@@ -1,16 +1,21 @@
目录
* [没有root权限是否支持游戏](#没有root权限是否支持游戏)
* [如何重复做某些操作n次](#如何重复做某些操作n次)
* [如何循环做某些操作](#如何循环做某些操作)
* [某些有文字的按键点击无效怎么办](#某些有文字的按键点击无效怎么办)
* [如何点击图标按钮](#如何点击图标按钮)
* [如何支持Tasker调用](#如何支持Tasker调用)
### 没有root权限是否支持游戏
**游戏需要root权限!!!**
**游戏需要root权限!!!**
**游戏需要root权限!!!**
100%的游戏在没有root权限的情况下都不支持。
**游戏需要root权限!!!**
**游戏需要root权限!!!**
**游戏需要root权限!!!**
不管是录制脚本还是运行脚本在没有root权限的情况下都无法做到在游戏界面不使用root权限录制脚本录制出来的是空白的。
### 如何重复做某些操作n次
使用循环语句实现实现。例如每个1秒执行一个操作总共执行20次的代码如下:
```
for(var i = 1; i <= 20; i++){
@@ -19,10 +24,27 @@ for(var i = 1; i <= 20; i++){
}
```
### 如何循环做某些操作
使用while(true)语句实现。例如QQ无限发送消息的脚本如下
```
while(true){
input("测试");
click("发送");
}
```
### 某些有文字的按键点击无效怎么办
例如QQ下方的"联系人"按钮用click("联系人")是无效的。这是因为这些按钮上的文字并不是真正的文字,而是一个图标。参见[如何点击图标按钮](#如何点击图标按钮)。
### 如何点击图标按钮
有以下几种方法:
* 录制脚本
* 通过图标在屏幕上的位置来点击。要获取图标在屏幕上的位置,可以开启悬浮窗,选择布局范围查看,之后点击要点击的图标,在弹出的窗口中的"bounds"一栏即图标在屏幕上的区域。例如:
* 通过id, desc等选择器来定位图片
### 如何支持Tasker调用
新建任务时选择文件点击浏览找到要运行的脚本文件在MimeType处填入application/x-javascript。

View File

@@ -8,6 +8,9 @@
### log(text)
* text \<String\> | \<Object\> 要打印到控制台的信息
### print(text)
等同于log。
在控制台中输出日志,例如`log("Hello world");`。当text是一个对象时则会转换String以后再输出。
### err(error)

View File

@@ -0,0 +1,162 @@
以下内容来自[Rhino:Scripting Java](https://developer.mozilla.org/zh-CN/docs/Mozilla/Projects/Rhino/Scripting_Java)。
这个章节描述了如何在rhino中使用java。使用脚本调用Java有很多用途它使得我们可以利用Java中现有的库来帮助我们构建强大的脚本。我们可以通过编写脚本来对Java程序进行测试。可以通过脚本来进行探索式编程辅助Java的开发所谓探索式编程就是通过快速地编程调用库或API来探索这些库或API可以做什么显而易见脚本语言很适合探索式编程。
这里注意ECMA标准并没有包含和Java(或者其他任何对象系统)交互的标准。本文所描述的所有内容,应该被认为是一个扩展。
目录:
* [访问Java的包和类](#访问Java的包和类)
* [使用Java的类](#使用Java的类)
* [实现Java接口](#实现Java接口)
* [创建Java数组](#创建Java数组)
* [Java字符串与JavaScript字符串](#Java字符串与JavaScript字符串)
* [Java异常](#Java异常)
* [JavaImporter](#JavaImporter)
## 访问Java的包和类
Java的每段代码都是类的一部分每一个JAVA类都是包的一部分。在Javascript中脚本不属于任何package。我们可以访问Java包中的类么
Rhino定义了一个顶层的变量Packages。Packages的所有属性都是Java中顶层的包比如java和com。比如我们可以访问java包
```
Packages.java.util.Vector
```
还有一种更方便的方式Rhino定义了一个顶层的变量java等价于Packages.java。所以上面的例子可以更简介地写成
```
java.util.Vector
```
如果你的脚本需要访问很多的Java类每次都附带完整的包名会使得编程很麻烦。Rhino提供了一个顶层的方法importPackage它的功能和Java的import一样。比如我们可以导入java.io包中的所有类然后直接通过类名File来访问java.io.File:
```
importPackage(java.io)
```
这里importPackage(java.io)使得java.io包中的所有类(例如File)可以在顶层被访问。这和Java中的java.io.*;等价。
要注意Java会默认导入java.lang.*但是Rhino不会。因为JavaScript的顶层对象Boolean、Math、Number、Object和String和java.lang包中同名的类并不相同。因为这种冲突建议不要用importPackage来导入java.lang包。
有一点要注意的就是Rhino对于指定包名或类名时是如何处理错误的。如果java.Myclass是可访问的Rhino会试图加载名为java.MyClass的类如果加载失败它会假设java.MyClass是一个包名不会报错。只有在你试图将这个对象当作类使用时才会报错。
## 使用Java的类
现在我们可以访问Java类下一步就是要创建一个对象。方法就和在Java中一样 用new来创建对象
```
new java.util.Date();
```
如果我们将创建的对象存放在JavaScript变量中我们可以调用它的方法
```
var f = new java.io.File("test.text");
log(f.exists());
log(f.getName());
```
静态方法和属性可以直接通过类对象来访问:
```
log(java.lang.Math.PI);
```
不像Java在JavaScript里方法就是一个对象。它可以被评估也可以被调用。如果我们去查看这个方法我们可以看到这个方法所有重载的形式
```
log(f.listFiles);
```
输出:
```
function listFiles() {/*
java.io.File[] listFiles()
java.io.File[] listFiles(java.io.FilenameFilter)
java.io.File[] listFiles(java.io.FileFilter)
*/}
```
输出告诉我们File类有listFiles方法的三种重载一种不包含参数的另一种包含一个FilenameFilter类型的参数第三个包含一个FileFilter类型的参数。所有的方法都返回一个File对象数组。可以观察到Java方法的参数和返回类型在探索式编程中是非常有用的尤其是在对一个方法的参数和返回对象不确定的时候。
另一个有助于探索式编程的特性是可以看到对象中定义的所有方法和属性。用JavaScript的for..in , 我们可以打印这些值:
```
for (i in f) { log(i) }
```
注意这里不仅列出了File类中的所有方法也列出了从基类java.lang.Object中继承的方法例如wait。这使得我们可以更好地处理那些有复杂继承关系的对象因为我们可以看到对象中所有可用的方法。
Rhino可以通过属性名来方便地访问JavaBean的属性。一个JavaBean的属性foo被方法getFoo和setFoo定义另外一个也叫foo的boolean类型的属性可以被isFoo来定义。比如, 下面的代码实际上调用了File对象的getName和isDirectory方法。
## 实现Java接口
```
obj = { run: function () { log("\nrunning"); } };
r = new java.lang.Runnable(obj);
t = new java.lang.Thread(r);
t.start();
```
若一个接口只有一个方法,也可以用直接用函数代替:
```
t = java.lang.Thread(function () { print("\nrunning"); });
t.start();
```
## 创建Java数组、
Rhino没有提供特定的语法创建Java的数组只能通过反射来创建。
```
a = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2);
b = java.lang.reflect.Array.newInstance(java.lang.String, 5);
```
之后可以像JavaScript数组一样使用
```
a[0] = 'a';
a[1] = 'b';
```
## Java字符串与JavaScript字符串
Java字符串与JavaScript字符串并不等同但在某种程度上两者可以通用。例如你可以传递一个JavaScript的字符串给一个需要Java字符串参数的函数。
```
javaString = new java.lang.String("Java");
jsString = "JavaScript";
log(javaString.length());
log(jsString.length);
```
也可以对Java字符串调用了一个在java.lang.String中没有定义的JavaScript方法例如
```
log(javaString.match(/a.*/));
```
## Java异常
例如:
```
try {
java.lang.Class.forName("NonExistingClass");
} catch (e) {
if (e.javaException instanceof java.lang.ClassNotFoundException) {
print("Class not found");
}
}
```
或者
```
function classForName(name) {
try {
return java.lang.Class.forName(name);
} catch (e if e.javaException instanceof java.lang.ClassNotFoundException) {
print("Class " + name + " not found");
} catch (e if e.javaException instanceof java.lang.NullPointerException) {
print("Class name is null");
}
}
classForName("NonExistingClass");
classForName(null);
```
## JavaImporter
```
var SwingGui = JavaImporter(Packages.javax.swing,
Packages.javax.swing.event,
Packages.javax.swing.border,
java.awt.event,
java.awt.Point,
java.awt.Rectangle,
java.awt.Dimension);
...
with (SwingGui) {
var mybutton = new JButton(test);
var mypoint = new Point(10, 10);
var myframe = new JFrame();
...
}
```

View File

@@ -1,12 +1,15 @@
目录:
* [简介](#简介)
* [选择器](#选择器)
* [筛选条件](#筛选条件)
* [搜索](#搜索)
* [操作](#操作)
* [控件](#控件)
* [控件集合](#控件集合)
## 简介
选择器提供了更强大的定位界面控件与对进行操作的功能,可以用他们完成更多的自动操作。
选择器提供了更强大的定位界面控件与对进行操作的功能,可以用他们完成更多的自动操作和提取界面信息
选择器通过附加筛选条件,筛选出符合条件的控件或控件集合,之后可以对这些控件这些操作。
可供选择的筛选条件包括:
* id
@@ -17,21 +20,21 @@
* bounds 在屏幕上的范围
* drawingOrder 绘制顺序
* 各种属性,主要包括:
* clickable
* longClickable
* checkable
* checked
* scrollable
* selected
* editable
* visibleToUser
* enabled
* clickable 可点击
* longClickable 可长按
* checkable 可勾选
* checked 被勾选
* scrollable 可滑动
* selected 被选择
* editable 可编辑
* visibleToUser 可见
* enabled 已启用
要对选择器所确定的筛选条件对屏幕上的控件进行筛选调用方法find(), findOne(), untilFind(), untilFind()。其中find(), untilFind()返回控件的集合findOne(), untilFindOne()返回一个控件。until***函数会一直寻找知道屏幕上出现满足条件的控件为止。
要对选择器所确定的筛选条件对屏幕上的控件进行筛选调用方法find(), findOne(), untilFind()。其中find(), untilFind()返回控件的集合findOne()返回一个控件。untilFind和FindOne函数会一直寻找直到屏幕上出现满足条件的控件为止。
一个完整的选择器示例如下:
```
var emoj = id("name").packageName("com.tencent.mobileqq").clickable()
.className("ImageView").drawingOrder(5).untilFindOne();
.className("ImageView").drawingOrder(5).findOne();
emoj.click();
```
上述代码是找到QQ聊天界面下面的表情按钮(第5个按钮)并点击。也可以简化为:
@@ -42,9 +45,11 @@ id("name").packageName("com.tencent.mobileqq").clickable()
最后的click()函数相当于untilFind().click()。也就是如果只需要在找到控件以后立即进行操作只需要调用相应的操作函数而不需要先调用find等函数等到控件再操作。
要获取屏幕上的控件的信息(例如id, text, desc, bounds等),可以开启悬浮窗,使用界面层次查看和界面范围查看。
以下是具体的文档
因为选择器部分内容如果有安卓开发经验会更容易掌握因而更适合UI测试
## 选择器
# 选择器
## 筛选条件
### id(resId)
* resId \<String\> 控件的id以"包名:id/"开头,例如"com.tencent.mm:id/send_btn"。也可以不指定包名这时会以当前正在运行的应用的包名来补全id。例如id("send_btn"),在QQ界面想当于id("com.tencent.mobileqq:id/send_btn")。
@@ -56,6 +61,8 @@ id("name").packageName("com.tencent.mobileqq").clickable()
附加控件id包含字符串str的筛选条件。
> 控件的id属性通常是可以用来确定控件的唯一标识如果一个控件有id那么使用id来找到他是最好的方法。要查看屏幕上的控件的id可以开启悬浮窗并使用界面工具点击相应控件即可查看。若查看到的控件id为null, 表示该控件没有id。另外在列表中会出现多个控件的id相同的情况。例如微信的联系人列表每个头像的id都是一样的。此时不能用id来唯一确定控件。
### idStartsWith(prefix)
* prefix \<String\> id前缀
@@ -72,127 +79,358 @@ id("name").packageName("com.tencent.mobileqq").clickable()
附加id需要满足正则表达式。有关正则表达式可以查看[菜鸟教程](http://www.runoob.com/regexp/regexp-example.html)。
### text(str)
* str \<String\> 控件文本
附加控件文本等于字符串str的筛选条件。
> 控件的text(文本)属性是控件上的显示的文字,例如微信左上角的"微信"文本。对于图片或者其他控件通常text属性为null。
### textContains(str)
* str \<String\> 要包含的字符串
附加控件文本需要以prefix开头的筛选条件。
### textStartsWith(prefix)
* prefix \<String\> 前缀
附加控件文本需要以prefix开头的筛选条件。
### textEndsWith(suffix)
* suffix \<String\> 后缀
附加控件文本需要以suffix结束的筛选条件。
### textMatches(str)
* regex \<Regex\> 要满足的正则表达式
### desc(desc)
附加控件文本需要满足正则表达式的条件。
### desc(str)
* str \<String\> 控件描述
附加控件描述等于字符串str的筛选条件。
> 控件的desc(描述全称为Content-Description)属性是对一个控件的描述,例如网易云音乐右上角的放大镜图标的描述为搜索。要查看一个控件的描述,同样地可以借助悬浮窗查看。
### descContains(str)
* str \<String\> 要包含的字符串
附加控件描述需要以prefix开头的筛选条件。
### descStartsWith(prefix)
* prefix \<String\> 前缀
附加控件描述需要以prefix开头的筛选条件。
### descEndsWith(suffix)
* suffix \<String\> 后缀
附加控件描述需要以suffix结束的筛选条件。
### descMatches(str)
* regex \<Regex\> 要满足的正则表达式
### className(className)
附加控件描述需要满足正则表达式的条件。
### className(str)
* str \<String\> 控件类名
附加控件类名等于字符串str的筛选条件。
> 控件的className属性是一个控件的具体类型例如图片控件通常为ImageView文本控件通常为TextView, 输入框通常为EditText。(若一个控件是在android.widget包里的那么android.widget可以省略。但除此之外的其他控件必须是类的全名例如"com.stardust.theme.ThemeColorImageView")。
### classNameContains(str)
* str \<String\> 要包含的字符串
附加控件类名需要以prefix开头的筛选条件。
### classNameStartsWith(prefix)
* prefix \<String\> 前缀
附加控件类名需要以prefix开头的筛选条件。
### classNameEndsWith(suffix)
* suffix \<String\> 后缀
附加控件类名需要以suffix结束的筛选条件。
### classNameMatches(str)
* regex \<Regex\> 要满足的正则表达式
### packageName(packageName)
附加控件类名需要满足正则表达式的条件。
### packageName(str)
* str \<String\> 包名
附加包名等于字符串str的筛选条件。
> packageName属性也即控件所属的应用的包名(参见《shell命令:应用包名》),通常用来保证当前运行的应用是想要的应用。
### packageNameContains(str)
* str \<String\> 要包含的字符串
附加包名需要以prefix开头的筛选条件。
### packageNameStartsWith(prefix)
* prefix \<String\> 前缀
附加包名需要以prefix开头的筛选条件。
### packageNameEndsWith(suffix)
* suffix \<String\> 后缀
附加包名需要以suffix结束的筛选条件。
### packageNameMatches(str)
* regex \<Regex\> 要满足的正则表达式
附加包名需要满足正则表达式的条件。
### bounds(l, t, r, b)
* l, t, r, b 用来定位控件在屏幕上的范围的四个整数
### boundsInside(l, t, r, b)
### boundsContains(l, t, r, b)
### drawingOrder(order)
* order \<Number\> 控件在父视图中的绘制顺序,在一些
### checkable(b = true)
* b \<Boolean\> 表示控件是否可勾选, 默认为true
附加控件是否可勾选的条件。可勾选指的是例如QQ和微信发送图片时图片的勾选。
### selected(b = true)
* b \<Boolean\> 表示控件是否被选中默认为true
附加控件是否被选中的条件。被选中指的是例如QQ聊天界面点击下方的表情按钮时会出现自己收藏的表情这时表情按钮便处于选中状态。
### clickable(b = true)
* b \<Boolean\> 表示控件是否可点击, 默认为true
附加控件是否可点击的条件。但并非所有clickable为false的控件都真的不能点击这取决于控件的实现。因而要确定一个控件的clickable属性可以开启悬浮窗工具。
### longClickable(b = true)
* b \<Boolean\> 表示控件是否可长按, 默认为true
附加控件是否可长按的条件。
### enabled(b = true)
* b \<Boolean\> 表示控件是否已启用, 默认为true
### password(b = true)
附加控件是否已启用的条件。大多数控件都是启用的状态,处于“禁用”状态通常是灰色并且不可点击。
### scrollable(b = true)
* b \<Boolean\> 表示控件是否可滑动, 默认为true
附加控件是否可滑动的条件。
### editable(b = true)
* b \<Boolean\> 表示控件是否可编辑, 默认为true
附加控件是否可编辑的条件。一般来说可编辑的控件为输入框(EditText)。
### contentInvalid(b = true)
* b \<Boolean\> 表示控件是否是contentInvalid, 默认为true
我也不知道是什么,下次再补充吧。
### contextClickable(b = true)
* b \<Boolean\> 表示控件是否是contextClickable, 默认为true
我也不知道是什么,下次再补充吧。
### multiLine(b = true)
* b \<Boolean\> 表示文本或输入框控件是否是多行显示的, 默认为true
### dismissable(b = true)
附加控件是否文本或输入框控件是否是多行显示的条件。
## 搜索
### findOne()
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到屏幕上出现满足条件的一个控件为止,并返回该控件。如果找不到控件,当屏幕内容发生变化时会重新寻找,直至找到。参见[控件](#控件)。
### find()
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,找到所有满足条件的控件集合并返回。这个搜索只进行一次,并不保证一直会找到,因而会出现返回的控件集合为空的情况。参见[控件集合](#控件集合)。
### untilFind()
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到找到至少一个满足条件的控件为止,并返回所有满足条件的控件集合。参见[控件集合](#控件集合)。
## 操作
### click()
找到所有符合条件的控件并点击。相当于untilFind().click()。参见[click](#UiCollection.click)。
### longClick()
### accessibilityFocus()
### clearAccessibilityFocus()
### focus()
### clearFocus()
找到所有符合条件的控件并长按。相当于untilFind().longClick()。参见[longClick](#UiCollection.longClick)。
### copy()
找到所有符合条件的控件并复制其内容只对文本框或输入框控件有文字选中时有效。相当于untilFind().copy()。参见[copy](#UiCollection.copy)。
### paste()
找到所有符合条件的控件并粘贴只对输入框控件有效。相当于untilFind().paste()。参见[paste](#UiCollection.paste)。
### select()
找到所有符合条件的控件并选中。相当于untilFind().select()。参见[select](#UiCollection.select)。
### cut()
找到所有符合条件的控件并剪切其内容只对文本框或输入框控件有文字选中时有效。相当于untilFind().cut()。参见[cut](#UiCollection.cut)。
### collapse()
找到所有符合条件的控件并折叠。相当于untilFind().collapse()。参见[collapse](#UiCollection.collapse)。
### expand()
### dismiss()
找到所有符合条件的控件并展开。相当于untilFind().expand()。参见[expand](#UiCollection.expand)。
### show()
找到所有符合条件的控件并使其出现在屏幕上。相当于untilFind().show()。参见[show](#UiCollection.show)。
### scrollForward()
找到所有符合条件的控件并向前滑。相当于untilFind().scrollForward()。参见[scrollForward](#UiCollection.scrollForward)。
向前滑指的是,对于左右滑动的控件向右滑,上下滑动的控件向下滑。
### scrollBackward()
找到所有符合条件的控件并向后滑。相当于untilFind().scrollBackward()。参见[scrollBackward](#UiCollection.scrollBackward)。
向后滑指的是,对于左右滑动的控件向左滑,上下滑动的控件向上滑。
### scrollUp()
找到所有符合条件的控件并向上滑。相当于untilFind().scrollUp()。参见[scrollUp](#UiCollection.scrollUp)。
### scrollDown()
找到所有符合条件的控件并向下滑。相当于untilFind().scrollDown()。参见[scrollDown](#UiCollection.scrollDown)。
### scrollLeft()
找到所有符合条件的控件并向左滑。相当于untilFind().scrollLeft()。参见[scrollLeft](#UiCollection.scrollLeft)。
### scrollRight()
找到所有符合条件的控件并向右滑。相当于untilFind().scrollRight()。参见[scrollRight](#UiCollection.scrollRight)。
### contextClick()
### setSelection(start, end)
* start \<Number\> 文字选中开始位置
* end \<Number\> 文字选中结束位置
找到所有符合条件的控件并设置文字选中区域只对文本控件和输入框有效。相当于untilFind().setSelection()。参见[setSelection](#UiCollection.setSelection)。
### setText(text)
* text \<String\> 要设置的文本
找到所有符合条件的控件并设置文字只对输入框有效。相当于untilFind().setText()。参见[setText](#UiCollection.setText)。
### setProgress(value)
# 控件集合
UiCollection, 通过选择器的find(), untilFind()方法返回的对象。可以对其进行操作或者获取其信息。
### scrollTo(row, column)
### UiCollection.size()
返回集合中的控件数。
## 控件
### UiCollection.get(i)
* i \<Number\> 索引
## 控件集合
返回集合中第i+1个控件(UiObject)。
### UiCollection.each(func)
* func \<Function\> 遍历函数
遍历集合。例如:
```
var c = clickable();
c.each(function(o){
log(o.text());
});
```
### find(selector)
* selector \<UiSelector\> 选择器
根据selector所确定的条件在该控件集合中找到所有符合条件的控件并返回控件集合。例如
```
var names = id("name");
var clickableNames = names.find(clickable());
```
## findOne(selector)
* selector \<UiSelector\> 选择器
根据selector所确定的条件在该控件集合中找到一个符合条件的控件并返回控件。若找不到则返回null。
### UiCollection.click()
点击集合中所有控件,并返回是否全部点击成功。
### UiCollection.longClick()
长按集合中所有控件,并返回是否全部操作成功。
### UiCollection.copy()
对集合中所有控件执行复制操作,并返回是否全部操作成功。
### UiCollection.paste()
对集合中所有控件执行粘贴操作,并返回是否全部操作成功。
### UiCollection.select()
对集合中所有控件执行选中操作,并返回是否全部操作成功。
### UiCollection.cut()
对集合中所有控件执行剪切操作,并返回是否全部操作成功。
### UiCollection.collapse()
对集合中所有控件执行折叠操作,并返回是否全部操作成功。
### UiCollection.expand()
对集合中所有控件执行展开操作,并返回是否全部操作成功。
### UiCollection.show()
对集合中所有控件执行显示操作,并返回是否全部操作成功。
### UiCollection.scrollForward()
对集合中所有控件执行向前滑的操作,并返回是否全部操作成功。
### UiCollection.scrollBackward()
对集合中所有控件执行向后滑的操作,并返回是否全部操作成功。
### UiCollection.scrollUp()
对集合中所有控件执行向上滑的操作,并返回是否全部操作成功。
### UiCollection.scrollDown()
对集合中所有控件执行向下滑的操作,并返回是否全部操作成功。
### UiCollection.scrollLeft()
对集合中所有控件执行向左滑的操作,并返回是否全部操作成功。
### UiCollection.scrollRight()
对集合中所有控件执行向右滑的操作,并返回是否全部操作成功。
### UiCollection.contextClick()
### UiCollection.setSelection(start, end)
* start \<Number\> 文字选中开始位置
* end \<Number\> 文字选中结束位置
对集合中所有控件设置文字选中区域,并返回是否全部操作成功。
### UiCollection.setText(text)
* text \<String\> 要设置的文本
对集合中所有控件设置文本,并返回是否全部操作成功。
# 控件
UiObject, 选择器的findOne方法返回的对象。和UiCollection有相似的方法不再赘述。除此之外还有以下方法。
### child(i)
* i \<Number\> 子控件索引
返回第i+1个子控件(UiObject)。
### parent()
返回父控件(UiObject)。
### children()
返回该控件的所有子控件组成的控件集合。

View File

@@ -80,27 +80,11 @@ var select = function(a, b, c, d){
}, arguments);
}
var focus = function(a, b, c, d){
return performAction(function(target){
return droid.focus(target);
}, arguments);
}
var paste = function(a, b, c, d){
return performAction(function(target){
return droid.paste(target);
}, arguments);
}
var editable = function(i){
return droid.editable(i);
}
var input = function(a, b){
if(arguments.length == 1){
return droid.setText(editable(-1), a);
return droid.setText(droid.editable(-1), a);
}else{
return droid.setText(editable(a), b);
return droid.setText(droid.editable(a), b);
}
}
@@ -120,6 +104,8 @@ var log = function(str){
droid.log(str);
}
var print = log;
var err = function(e){
droid.err(e);
}
@@ -137,16 +123,12 @@ var shell = function(cmd, root){
return droid.shell(cmd, root);
}
var getTexts = function(){
return droid.getTexts();
var currentPackage = function(){
return droid.currentPackage();
}
var getPackageName = function(){
return droid.getPackageName();
}
var getActivityName = function(){
return droid.getActivityName();
var currentActivity = function(){
return droid.currentActivity();
}
var setClip = function(text){
@@ -229,6 +211,7 @@ for(var x in __selector__){
this[x] = (function(method) {
return function(){
var s = droid.selector();
//这里不知道怎么写。尴尬。只能写成这样。
if(arguments.length == 0){
return s[method]();
}else if(arguments.length == 1){

View File

@@ -0,0 +1,190 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
print("----------------------------------------");
// Use the XML constructor to parse an string into an XML object
var John = "<employee><name>John</name><age>25</age></employee>";
var Sue ="<employee><name>Sue</name><age>32</age></employee>";
var tagName = "employees";
var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
print("The employees XML object constructed from a string is:\n" + employees);
print("----------------------------------------");
// Use an XML literal to create an XML object
var order = <order>
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item>
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
</order>
// Construct the full customer name
var name = order.customer.firstname + " " + order.customer.lastname;
// Calculate the total price
var total = order.item.price * order.item.quantity;
print("The order XML object constructed using a literal is:\n" + order);
print("The total price of " + name + "'s order is " + total);
print("----------------------------------------");
// construct a new XML object using expando and super-expando properties
var order = <order/>;
order.customer.name = "Fred Jones";
order.customer.address.street = "123 Long Lang";
order.customer.address.city = "Underwood";
order.customer.address.state = "CA";
order.item[0] = "";
order.item[0].description = "Small Rodents";
order.item[0].quantity = 10;
order.item[0].price = 6.95;
print("The order custructed using expandos and super-expandos is:\n" + order);
// append a new item to the order
order.item += <item><description>Catapult</description><price>139.95</price></item>;
print("----------------------------------------");
print("The order after appending a new item is:\n" + order);
print("----------------------------------------");
// dynamically construct an XML element using embedded expressions
var tagname = "name";
var attributename = "id";
var attributevalue = 5;
var content = "Fred";
var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
print("The dynamically computed element value is:\n" + x.toXMLString());
print("----------------------------------------");
// Create a SOAP message
var message = <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</soap:Body>
</soap:Envelope>
// declare the SOAP and stocks namespaces
var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
var stock = new Namespace ("http://mycompany.com/stocks");
// extract the soap encoding style and body from the soap message
var encodingStyle = message.@soap::encodingStyle;
print("The encoding style of the soap message is specified by:\n" + encodingStyle);
// change the stock symbol
message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
var body = message.soap::Body;
print("The body of the soap message is:\n" + body);
print("----------------------------------------");
// create an manipulate an XML object using the default xml namespace
default xml namespace = "http://default.namespace.com";
var x = <x/>;
x.a = "one";
x.b = "two";
x.c = <c xmlns="http://some.other.namespace.com">three</c>;
print("XML object constructed using the default xml namespace:\n" + x);
default xml namespace="";
print("----------------------------------------");
var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item id="3456">
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
<item id = "56789">
<description>DVD Player</description>
<price>399.99</price>
<quantity>1</quantity>
</item>
</order>;
// get the customer element from the orderprint("The customer is:\n" + order.customer);
// get the id attribute from the order
print("The order id is:" + order.@id);
// get all the child elements from the order element
print("The children of the order are:\n" + order.*);
// get the list of all item descriptions
print("The order descriptions are:\n" + order.item.description);
// get second item by numeric index
print("The second item is:\n" + order.item[1]);
// get the list of all child elements in all item elements
print("The children of the items are:\n" + order.item.*);
// get the second child element from the order by index
print("The second child of the order is:\n" + order.*[1]);
// calculate the total price of the order
var totalprice = 0;
for each (i in order.item) {
totalprice += i.price * i.quantity;
}
print("The total price of the order is: " + totalprice);
print("----------------------------------------");
var e = <employees>
<employee id="1"><name>Joe</name><age>20</age></employee>
<employee id="2"><name>Sue</name><age>30</age></employee>
</employees>;
// get all the names in e
print("All the employee names are:\n" + e..name);
// employees with name Joe
print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
// employees with id's 1 & 2
print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
// name of employee with id 1
print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
print("----------------------------------------");
openConsole();

View File

@@ -0,0 +1 @@
shell("pm disable com.netease.cloudmusic", true);

View File

@@ -0,0 +1 @@
shell("am start -n com.tencent.mm/com.tencent.mm.plugin.scanner.ui.BaseScanUI", true);

View File

@@ -0,0 +1 @@
shell("am start -n com.eg.android.AlipayGphone/com.alipay.mobile.scan.as.main.MainCaptureActivity", true);

View File

@@ -0,0 +1 @@
shell("am kill-all", true);

View File

@@ -0,0 +1,2 @@
shell("pm enable com.netease.cloudmusic", true);
launchApp("网易云音乐");

View File

@@ -0,0 +1,2 @@
KeyCode("KEYCODE_POWER");
//或者 KeyCode(26);

View File

@@ -1,10 +1,10 @@
"ui";
importClass("android.widget.EditText");
importClass("android.widget.Button");
importClass("android.widget.LinearLayout");
importClass("android.content.Intent");
importClass("android.net.Uri");
importClass(android.widget.EditText);
importClass(android.widget.Button);
importClass(android.widget.LinearLayout);
importClass(android.content.Intent);
importClass(android.net.Uri);
var qq = new EditText(activity);
qq.setHint("请输入QQ号");

View File

@@ -1,6 +1,6 @@
"ui";
importClass("com.afollestad.materialdialogs.MaterialDialog");
importClass(com.afollestad.materialdialogs.MaterialDialog);
new MaterialDialog.Builder(activity)
.title("简单计算器")

View File

@@ -4,7 +4,7 @@ toast("出现红包时将会自动拆开并关闭");
while(!isStopped()){
if(click("点击拆开")){
//拆开红包后尝试10次关闭红包页面
for(var i = 0; i < 10; i++){
for(let i = 0; i < 10; i++){
sleep(300);
if(click("关闭"))
break;

View File

@@ -0,0 +1,16 @@
importClass(android.content.Intent);
importClass(android.net.Uri);
importClass(android.provider.Settings);
function 打开App设置(packageName){
var intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", packageName, null);
intent.setData(uri);
context.startActivity(intent);
}
打开App设置("com.tencent.mobileqq");
while(!currentPackage().equals("com.android.settings"));
while(!click("通知"));
while(!click("全部阻止"));

View File

@@ -1,5 +1,5 @@
function openRunningServices(){
function 打开正在运行的服务(){
launch("com.android.settings");
var i = 0;
while(!click("开发者选项")){
@@ -14,10 +14,10 @@ function openRunningServices(){
}
importClass("android.os.Build");
importClass(android.os.Build);
if(Build.VERSION.SDK_INT < 23){
toast("本代码只适用于Android6.0以上");
}else{
openRunningServices();
打开正在运行的服务();
}

View File

@@ -0,0 +1,26 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
*/
// Create a new StringBuffer. Note that the class name must be fully qualified
// by its package. Packages other than "java" must start with "Packages", i.e.,
// "Packages.javax.servlet...".
var sb = new java.lang.StringBuffer();
// Now add some stuff to the buffer.
sb.append("hi, mom");
sb.append(3); // this will add "3.0" to the buffer since all JS numbers
// are doubles by default
sb.append(true);
// Now print it out. (The toString() method of sb is automatically called
// to convert the buffer to a string.)
// Should print "hi, mom3.0true".
print(sb);
openConsole();

View File

@@ -0,0 +1,22 @@
function 下滑(){
className("AbsListView").scrollable().scrollForward();
}
function (){
className("ImageView").desc("赞").click();
}
function 显示更多(){
for(let i = 0; i < 2;i++){
click("显示更多");
}
}
toast("请打开点赞自己的人的界面");
while(notStopped()){
for(let i = 0; i < 10; i++){
();
}
显示更多();
下滑();
}

View File

@@ -0,0 +1,6 @@
while(true){
if(id("i4").untilFindOne().parent().parent().click()){
sleep(700);
id("gf").click();
}
}

View File

@@ -0,0 +1,3 @@
launchApp("网易云音乐");
id("kp").click();
text("签到").className("TextView").click();