前言

起初这还只是一个想法,直到主题群有小伙伴问到daodao(叨叨点啥)的搭建,讨论到了如何快捷发送daodao,
原教程里只有ios版的,小伙伴就想着自己做一个,然后就有了daodao-bash。这版本是在pc端上用的,我就想着好像还差个安卓版,于是就有了daodao-Android……

其实对比daodao-bash也有很多相似的地方,可以说我是参考了daodao-bash的思路,由于我不是ios系统所以我也不知道ios版是怎么样的……



效果展示


核心代码

  • 常用指令 c

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    //c
    if (ui.r1.isChecked()) {
    dialogs.confirm("c 增加一条叨叨", "", function (b) {
    if (b) {
    dialogs.rawInput("请输入即将 发布的内容:", "", function (str) {
    http.get("www.baidu.com", {}, function (res, err) {
    if (err) {
    toast("网络异常!");
    return;
    }
    sleep(200);
    var url = ui.i1.text() + "/api?c=" + str + "&k=" + ui.i2.text();
    sleep(200);
    toast("发送中,请稍等~");
    sleep(200);
    if (str == null) {
    toast("没有内容!");
    return;
    } else {
    if (res.statusCode == 200) {
    var r = http.get(url);
    var txt = r.body.string();
    toast("发送成功");
    }
    }
    });
    });
    }
    });
    }

    参照小冰 大佬的发送格式

    1
    2
    3
    4
    5
    6
    c 增加一条叨叨(需输入密码)
    请求连接: {vercle项目链接}/api?c={content}&k={key}

    示例: https://daodao-three.vercel.app/api?c=这是一条测试&k=******

    content: 可以是文字或者html代码
  • 密码检测

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // 密码-pc
    var key2 = files.read("./2.txt");
    var key3 = files.read("./3.txt");
    var url = "https://" + key2 + "/api?c=Daodao for Android&k=" + key3;

    key();

    //判断key
    function key() {
    http.get("www.baidu.com", {}, function (res, err) {
    if (err) {
    toast("网络异常!");
    return;
    }
    sleep(200);
    toast("检测中...");
    sleep(1500);
    var r = http.get(url);
    var txt = r.body.string();
    if (txt == "Please enter the correct password") {
    toast("密码错误!");
    sleep(200);
    }
    else {
    toast("密码正确");
    sleep(200);
    }
    sleep(300);
    var dn = require("./dn.js");

    sleep(300);
    toast("已执行,请重启软件");
    });
    }
    1
    2
    3
    4
    5
    6
    //dn
    var key2 = files.read("./2.txt");
    var key3 = files.read("./3.txt");

    var url = "https://" + key2 + "/api?dn=1&k=" + key3
    http.get(url);

    密码检测思路来自daodao-bash思路:发送一条叨叨,检测发送后的提示语,从而判断密码真假,后删除测试发送的叨叨

    1
    2
    3
    4
    5
    6
    7
    8
    if magicFirst == True:
    return
    try:
    r1 = requests.get(url+'c=DaoDaoBash_LoginCheck'+'&k='+password)
    if r1.status_code == 200 and r1.text == 'Execution: you did not send a message today, create an issue and add a comment!':
    requests.get(url+'dn=1'+'&k='+password)
    except:
    return 2
  • 查询(旧)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //查询
    ui.b8.on("click", function () {
    threads.start(function () {
    toast("执行中,请稍等...");
    sleep(300);
    console.clear();
    sleep(200);
    console.hide();
    sleep(200);

    var url = "https://" + ui.i1.text() + "/api?q=" + ui.t3.text()
    var r = http.get(url);
    var t = r.body.string();
    sleep(200);
    toast("已获取");
    sleep(200);
    var txt = /("content":[\s\S]*?,|"from":[\s\S]*?,)/g;
    var a = t.match(txt);
    var res;
    a.forEach((child, index) => {
    if (index % 2 == 0) {
    res = "";
    var one = child.match(/"[\s\S]*?"/g)[1];
    var u8 = unescape(one.replace(/\\u/g, '%u'));
    res = u8 + "\n";
    } else {
    var two = child.match(/"[\s\S]*?"/g)[1];
    res += two + "\n";
    console.show();
    console.setTitle("摸鱼", "#ff11ee00", 30);
    console.setSize(1000, 1000);
    console.setCanInput(false);
    log(res);

    }
    })
    });
    })

    获取api,用正则表达式筛选输出到悬浮窗

  • 查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //q-pc
    function pc2() {
    let webview = ui.webview;
    var client = android.webkit.WebViewClient;

    var settings = webview.getSettings();
    settings.setUserAgentString(
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
    );
    function 网页中获取网页源代码() {
    r = document.getElementsByTagName("html")[0].innerText;
    return r;
    }
    var t = new JavaAdapter(client, {
    onPageFinished: function (view) {
    webview.evaluateJavascript(";" + 网页中获取网页源代码.toString() + ";网页中获取网页源代码();", function (s) {
    toast("已获取");
    });
    },
    });

    webview.setWebViewClient(t);
    webview.loadUrl("https://" + ui.i1.text());
    }

    用了牙叔的js爬虫,由于很久之前看的,忘了在哪看,有看到过小伙伴希望可以告知下我

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //类似原版js爬虫
    "ui";
    ui.layout(
    <vertical>
    <webview id="webview"></webview>
    </vertical>
    );

    pc();

    function pc() {
    let webview = ui.webview;
    var client = android.webkit.WebViewClient;

    var url = "";

    var settings = webview.getSettings();
    settings.setUserAgentString(
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
    );
    function 网页中获取网页源代码() {
    r = document.getElementsByTagName("html")[0].innerText;
    return r;
    }
    var t = new JavaAdapter(client, {
    onPageFinished: function (view) {
    webview.evaluateJavascript(";" + 网页中获取网页源代码.toString() + ";网页中获取网页源代码();", function (s) {
    let 网页源代码filePath = "./4.html";
    files.write(网页源代码filePath, s);
    });
    },
    });

    webview.setWebViewClient(t);
    webview.loadUrl(url);

    back();
    }

部分代码

  1. ui(改的自带ui)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    "ui";

    ui.layout(
    <drawer id="draw" > //抽屉布局
    <vertical> //垂直布局
    <appbar> //顶端栏
    <toolbar id="tool" title="Daodao" />
    <tabs id="tab" />
    </appbar>

    <card w="*" h="45" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical"> //卡片布局(固定顶端)
    <vertical padding="18 8" h="auto">
    <text text="当前版本Beta 1.4.3 by:Reverse" textSize="16sp" padding="3" textColor="#FFCD7F32" />
    </vertical>
    <View bg="#f44336" h="*" w="10" />
    </card>

    <viewpager id="slide" > //滑动布局
    <vertical> //主页
    <card w="*" h="180" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
    <vertical padding="18 8" h="auto">
    <text text="域名" textColor="black" textSize="16sp" marginTop="16" />
    <input hint="不带http(s)的域名" id="i1" />

    <text text="密码" textColor="black" textSize="16sp" marginTop="16" />
    <input password="true" hint="显示已加密" id="i2" />
    </vertical>
    <View bg="#2196f3" h="*" w="10" />
    </card>

    <card w="*" h="80" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical"> //选择类型
    <horizontal padding="18 8" h="auto">
    <text text="选择类型 " textSize="16sp" textColor="black" />
    <radiogroup>
    <checkbox id="r1" text="c 发布 " textColor="blue" />
    <checkbox id="r2" text="dn 删除 " textColor="blue" />
    </radiogroup>
    <radiogroup>
    <checkbox id="r3" text="e 编辑 " textColor="blue" />
    <checkbox id="r4" text="a 补充 " textColor="blue" />
    </radiogroup>
    </horizontal>
    <View bg="#ff5722" h="*" w="10" />
    </card>

    <horizontal gravity="left">
    <button id="b2" text="清除数据" w="100" h="50" margin="5 5" />
    <button id="b3" text="网络测试" w="100" h="50" margin="5 5" />
    <button id="b5" text="域名检测" w="100" h="50" margin="5 5" />
    <button id="b6" text="" style="Widget.AppCompat.Button.Borderless" w="50" h="50" margin="5 5" />
    </horizontal>

    <horizontal gravity="left">
    <button id="b7" text="密码检测(单次)" w="120" h="50" margin="5 5" />
    <button id="b9" text="强制停止脚本" style="Widget.AppCompat.Button.Borderless.Colored" w="120" h="50" margin="5 5" />
    </horizontal>

    <button id="b1" text="确定" style="Widget.AppCompat.Button.Colored" w="*" h="50" margin="5 5" />
    </vertical>

    <vertical> //预览
    <card w="*" h="70" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical"> //类型
    <horizontal padding="18 8" h="auto">
    <text text="q= " textSize="16sp" textColor="black" />
    <input inputType="number" hint="默认10" id="t3" text="10" />
    <button id="b8" text="查询(旧)" w="100" h="40" margin="5 5" />
    <button id="b4" text="查询" style="Widget.AppCompat.Button.Colored" w="100" h="40" margin="5 5" />
    </horizontal>
    <View bg="#4caf50" h="*" w="10" />
    </card>
    <webview id="webview"></webview>
    </vertical>

    <vertical bg="?attr/selectableItemBackground" clickable="true" > //关于
    <text text="使用教程:" textSize="16sp" textColor="red" gravity="center" />
    <text id="t1" textSize="16sp" autoLink="all" textColor="#800080" gravity="left" />
    <text text=" 项目开源地址:" textSize="16sp" textColor="black" gravity="left" />
    <text id="t6" textSize="16sp" autoLink="all" textColor="black" gravity="left" />
    <text text="——————————分割线——————————" textSize="16sp" textColor="black" gravity="center" />
    <text text=" 其他版本:" textSize="16sp" textColor="black" gravity="left" />
    <text id="t5" textSize="16sp" autoLink="all" textColor="black" textStyle="bold" gravity="left" />
    <text text="——————————广告区——————————" textSize="16sp" textColor="black" gravity="center" />
    <text text=" 打个小广告 ~ " textSize="16sp" textColor="black" gravity="left" />
    <text id="t2" textSize="16sp" autoLink="all" textColor="black" textStyle="italic" gravity="left" />
    <text id="t4" textSize="16sp" autoLink="all" textColor="black" textStyle="italic" gravity="center_horizontal" />
    </vertical>

    </viewpager>
    </vertical>
    </drawer>
    );

    //关于
    ui.t6.setText(" Github: github.com/12thstan/daodao-android\n Gitee: gitee.com/c12th/daodao-android\n");
    ui.t1.setText(" 1. 请确保在网络正常下使用。\n 2. 填入域名和密码点击确定即可。\n 3. 第一次使用和修改密码都需要点击密码检测。\n 4. 只查询(需要悬浮窗权限)和域名检测可以只填域名。\n 5. 每次修改域名和密码都需要点击确定。\n");
    ui.t5.setText(" Daodao for Ios icloud.com/shortcuts/06fc462d4b4b4f668b16cb11e2e9d010\n 作者:冰糖红茶 https://github.com/Rock-Candy-Tea\n\n Daodao for Bash github.com/LittFlower/daodao-bash\n 作者:许江一墨 https://github.com/LittFlower\n")
    ui.t2.setText(" GitHub: github.com/12thstan\n Gitee: gitee.com/c12th\n CSDN: blog.csdn.net/qq_39788788\n Blog: blog.c12th.cn\n");
    ui.t4.setText("by:Reverse\n");

    //创建选项菜单(右上角)
    ui.emitter.on("create_options_menu", menu => {
    menu.add("日志");
    menu.add("退出");
    });

    //监听选项菜单点击
    ui.emitter.on("options_item_selected", (e, item) => {
    switch (item.getTitle()) {
    case "日志":
    alert("上个版本Beta 1.4.2(D) \n" +
    "\n 1.查询(旧)加上空位检测,并修正其他空位检测 \n" +
    "\n 2.完善了日志和关于页面的内容 \n" +
    "\n 3.新添加了启动画面 \n" +
    "\n 4.新添加强制停止脚本按钮 \n" +
    "\n 2023.08.29"
    );
    alert("当前版本Beta 1.4.3 \n" +
    "\n 1.修改部分空位检测 \n" +
    "\n 2.修复一个bug \n" +
    "\n 3.微调了下部分配置 \n" +
    "\n 2023.09.03"
    );
    break;

    case "退出":
    ui.finish();
    break;
    }
    e.consumed = true;
    });
    activity.setSupportActionBar(ui.tool);

    //滑动布局
    ui.slide.setTitles(["主页", "预览", "关于"])
    ui.tab.setupWithViewPager(ui.slide)
  2. 本地储存 + 读取数据 + 清除数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    //本地储存
    var save = storages.create("user")

    //读取数据
    var input = save.get("i1")
    if (input) {
    ui.i1.setText(input)
    };
    var input = save.get("i2")
    if (input) {
    ui.i2.setText(input)
    };

    ui.b1.click(function () {
    var input = ui.i1.text()
    save.put("i1", input)
    })

    ui.b1.click(function () {
    var input = ui.i2.text()
    save.put("i2", input)
    })

    //清除数据
    ui.b2.on("click", () => {
    threads.start(function () {
    save.clear()
    sleep(200);
    files.write("./2.txt", "");
    files.write("./3.txt", "");
    files.write("./4.txt", 2);
    sleep(200);
    toast("已清除,请重启软件");
    });
    })
  3. 复选判定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    //复选判定
    ui.r1.on("check", (checked) => {
    if (ui.r1.isChecked()) {
    ui.r2.setChecked(false)
    ui.r3.setChecked(false)
    ui.r4.setChecked(false)
    }
    });

    ui.r2.on("check", (checked) => {
    if (ui.r2.isChecked()) {
    ui.r1.setChecked(false)
    ui.r3.setChecked(false)
    ui.r4.setChecked(false)
    }
    });

    ui.r3.on("check", (checked) => {
    if (ui.r3.isChecked()) {
    ui.r1.setChecked(false)
    ui.r2.setChecked(false)
    ui.r4.setChecked(false)
    }
    });

    ui.r4.on("check", (checked) => {
    if (ui.r4.isChecked()) {
    ui.r1.setChecked(false)
    ui.r2.setChecked(false)
    ui.r3.setChecked(false)
    }
    });
  4. 网络检测

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //网络检测
    ui.b3.on("click", () => {
    threads.start(function () {
    http.get("www.baidu.com", {}, function (res, err) {
    if (err) {
    toast("网络异常!");
    return;
    }
    toast("网络正常");
    });
    });
    })
  5. 域名检测

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //域名检测
    ui.b5.on("click", function () {
    var text = ui.i1.text();
    if (text.length == 0) {
    ui.i1.setError("输入不能为空!");
    return;
    }
    threads.start(function () {
    http.get(ui.i1.text(), {}, function (res, err) {
    if (err) {
    toast("域名异常!");
    return;
    }
    toast("域名正常,可访问");
    });
    });
    })
  6. 悬浮窗权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //悬浮窗权限
    function 是否有悬浮窗权限() {
    return new android.provider.Settings().canDrawOverlays(context);
    }

    function 申请悬浮窗权限() {
    var intent = new Intent();
    intent.setAction("android.settings.action.MANAGE_OVERLAY_PERMISSION");
    activity.getEventEmitter().on("activity_result", function (requestCode, resultCode, intentData) { });
    activity.startActivityForResult(intent, 8000);
    }

使用教程

  1. 请确保在网络正常下使用。
  2. 填入域名和密码点击确定即可。
  3. 第一次使用和修改密码都需要点击密码检测。
  4. 只查询(需要悬浮窗权限)和域名检测可以只填域名。
  5. 每次修改域名和密码都需要点击确定。

其他版本:

最后

代码已在 githubgitee 上开源