首页 > 微信 > 详细

企业微信自动打卡的实现

时间:2019-01-12 17:44:07      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:tac   长按   cond   包安装   提示   选择   安全   randomize   ble   

本文旨在业余爱好,本人所在公司也没有微信打卡系统。建议小伙伴们还是要按时上班,好好工作,天道酬勤哦。

下面开始正题,企业微信打卡是基于定位的,所以如果要实现自动打卡,至少有如下两种方法:

  • 使用模拟定位,这种方式很简单,只要手机获取到root并安装模拟定位软件即可。不过,对于已经成熟的打卡平台,模拟定位数据应该是可以技术上做甄别的,有一定被发现的风险。而且,技术含量太低,所以本文没做尝试。
  • 通过类似按键精灵等工具模拟操作,完成打卡操作。该方式接近于物理外挂,安全性可以保证。缺点就是需要把手机一直放在有效定位范围内,可以找一个旧的不用的手机。

需要安装的工具

  • SuperSu:用来获取root权限。我用的是红米Note2,在调试过程中分别尝试了官方的ROOT(开发版)和Magisk,都不理想。对于官方root,操作比较简单,不过root不完全,还是有一些权限拿不到。Magisk很强大,不过可能是因为手机比较旧的原因,安装了好几个版本都存在兼容性问题,要么无法开机,要么开机后获取不到ROOT权限。最后换了SuperSu zip包安装后完美解决。
  • RE文件管理器:需要root权限,用来操作系统目录。
  • Tasker:定时运行工具。
  • Secure Settings:用于配合Tasker完成手机唤醒等操作。
  • 终端模拟器:可以直接在手机上完成adb的相关操作,配合Tasker完成任务调度。
  • 按键精灵手机版:完成打卡主流程操作。

另外,建议安装按键精灵电脑版,在电脑上完成调试比较方便快捷。其实,不使用按键精灵,只通过终端模拟器也是可以实现的,不过按键精灵做的比较完善,用它来实现会更稳定,也更方便。

安装SuperSu,获取ROOT权限

首先,需要获取root权限,无论是按键精灵还是其他软件,如果要实现全自动化操作,一般都绕不过这一步。

SuperSu安装有两种方式,这里推荐直接通过第三方Recovery安装ZIP包。三方Recovery可以在网上搜一下对应手机型号的,按照提示刷入Recovery即可。然后,将SuperSu的zip包放到手机存储中,重启手机进入recovery模式,找到SuperSu的zip包,按照提示完成安装即可。

类似操作网上有很多教程,此处不做赘述。

安装完成后,在桌面上会有个超级授权的图标,即是SuperSu应用了。此时,再运行其他需要root权限的应用时,就会弹框提示获取root权限,选择允许即可。

定时唤醒手机,调用按键精灵应用

通过Tasker的定时任务,调用Secure Settings定时的唤醒手机,点亮屏幕,然后调用内置的shell脚本。Tasker的配置文件如下:

<TaskerData sr="" dvi="1" tv="5.2.bf1">
    <Task sr="task4">
        <cdate>1546242617374</cdate>
        <edate>1547276696051</edate>
        <id>4</id>
        <nme>start</nme>
        <pri>100</pri>
        <Action sr="act0" ve="7">
            <code>1563799945</code>
            <Bundle sr="arg0">
                <Vals sr="val">
                    <com.intangibleobject.securesettings.plugin.extra.BLURB>Screen Bright
1 Second</com.intangibleobject.securesettings.plugin.extra.BLURB>
                    <com.intangibleobject.securesettings.plugin.extra.BLURB-type>java.lang.String</com.intangibleobject.securesettings.plugin.extra.BLURB-type>
                    <com.intangibleobject.securesettings.plugin.extra.SETTING>wake_device</com.intangibleobject.securesettings.plugin.extra.SETTING>
                    <com.intangibleobject.securesettings.plugin.extra.SETTING-type>java.lang.String</com.intangibleobject.securesettings.plugin.extra.SETTING-type>
                    <com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_DURATION>1000</com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_DURATION>
                    <com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_DURATION-type>java.lang.Long</com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_DURATION-type>
                    <com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_TYPE>bright</com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_TYPE>
                    <com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_TYPE-type>java.lang.String</com.intangibleobject.securesettings.plugin.extra.WAKE_LOCK_TYPE-type>
                    <com.twofortyfouram.locale.intent.extra.BLURB>Screen Bright
1 Second</com.twofortyfouram.locale.intent.extra.BLURB>
                    <com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
                    <net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
                    <net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
                </Vals>
            </Bundle>
            <Str sr="arg1" ve="3">com.intangibleobject.securesettings.plugin</Str>
            <Str sr="arg2" ve="3">com.intangibleobject.securesettings.plugin.Activities.TabsActivity</Str>
            <Int sr="arg3" val="0"/>
        </Action>
        <Action sr="act1" ve="7">
            <code>30</code>
            <Int sr="arg0" val="0"/>
            <Int sr="arg1" val="5"/>
            <Int sr="arg2" val="0"/>
            <Int sr="arg3" val="0"/>
            <Int sr="arg4" val="0"/>
        </Action>
        <Action sr="act2" ve="7">
            <code>123</code>
            <Str sr="arg0" ve="3">./system/xbin/auto.sh</Str>
            <Int sr="arg1" val="0"/>
            <Int sr="arg2" val="1"/>
            <Str sr="arg3" ve="3"/>
            <Str sr="arg4" ve="3"/>
            <Str sr="arg5" ve="3"/>
        </Action>
        <Img sr="icn" ve="2">
            <nme>hl_aaa_nixx_button</nme>
        </Img>
    </Task>
</TaskerData>

 

在定时任务中,调用了一个内置的shell脚本./system/xbin/auto.sh,在该脚本中完成了几个简单的模拟点击操作,最终调起了按键精灵应用中的打卡脚本。脚本内如如下:

#!/system/bin/sh
#每次运行时,创建一个ClockInScreencap的文件夹,用于存放运行过程中的截图等信息,方便调试。
rm -rf /storage/sdcard0/ClockInScreencap
date>/storage/sdcard0/ClockInScreencap/time.txt
#模拟滑动解锁
input swipe
200 1500 800 500 200 sleep 3
screencap -p /storage/sdcard0/ClockInScreencap/01.png #启动按键精灵
am force
-stop com.cyjh.mobileanjian sleep 5 am start -n com.cyjh.mobileanjian/com.cyjh.mobileanjian.activity.GuiActivity sleep 15 screencap -p /storage/sdcard0/ClockInScreencap/02.png #启动按键精灵后,通过几步点击,启动预先写好的打卡脚本,剩下的就是按键精灵的事情了
input tap
973 1838 sleep 2 screencap -p /storage/sdcard0/ClockInScreencap/03.png input tap 145 1300 sleep 2 screencap -p /storage/sdcard0/ClockInScreencap/04.png input tap 100 444 sleep 2 screencap -p /storage/sdcard0/ClockInScreencap/05.png input tap 534 1450 screencap -p /storage/sdcard0/ClockInScreencap/06.png

 

可以直接通过RE文件管理器,在system/xbin目录下完成上述脚本的编辑,或者在电脑端完成编辑后,再通过RE文件管理器放到system/xbin目录下。

然后通过RE文件器修改文件执行权限为777,修改方式:长按文件-->右上角菜单->权限设定->将所有权限都勾选即可。

该脚本的坐标都是写死的,所以需要根据手机的实际情况自行调试,目的就是最终调起按键精灵的脚本开始执行。

Taps:如果采用电脑端编辑后拖入的方式,会因为文件格式的问题导致每行最后多了个空格,执行时报错。解决办法,在电脑端编辑完成后,将文件转换为UNIX格式(即清除每行的\r换行符),或者在拖入后,通过RE文件管理器编辑删除每一行最后的空格。

按键精灵的打卡脚本

手动操作几遍打卡步骤,然后提取所有的操作点,通过脚本模拟完成。

为了是整个过程更健壮,要适当的加入时延和状态判断,重试机制等。这也是使用按键精灵,而不是直接使用shell脚本完成所有打卡步骤的原因,按键精灵很多功能可以帮助我们将脚本写的更完善,更健壮。

所以此处建议手动写脚本,而非通过录制功能完成,录制的脚本兼容性差,很容易出错。

Taps:由于是定时运行,为了避免每天的打卡时间相同或相近,可以在打卡开始时随机等待一段时间。

Function find_pic_with_retry(start_x, start_y, end_x, end_y, pic1, pic2)
    Dim find_x = -1, find_y = -1
    Rem rem_retry_find
    Device.UnLock()
    Delay 1000
    Dim pic = "Attachment:"&pic1
    If pic2 <> Null Then
        pic = "Attachment:"&pic1&"|"&"Attachment:"&pic2
    End If
    FindPic start_x, start_y, end_x, end_y, pic, "000000", 0, 0.8, find_x, find_y
    If find_x > -1 And find_y > -1 Then
        TracePrint "找到"&pic
    Else
        TracePrint "未找到"&pic
        If retry_times > 0 Then 
            retry_times = retry_times - 1
            Delay 10000
            Goto rem_retry_find
        End If
    End If
    find_pic_with_retry = Array(find_x, find_y)
End Function

Function find_workbench
    Device.UnLock()
    Delay 1000
    KillApp "com.tencent.wework"
    KeyPress "Home"
    Delay 1000
    RunApp "com.tencent.wework"
    Delay 10000
    FindPic 627,1870,723,1904, "Attachment:工作台.png|Attachment:工作台_选中.png", "000000", 0, 0.9, workbench_X, workbench_Y
    If workbench_X > -1 And workbench_Y > -1 Then
        TracePrint "找到工作台"
    Else
        TracePrint "未找到工作台"
        If retry_times > 0 Then 
            KillApp "com.tencent.wework"
            retry_times = retry_times - 1
            Call find_workbench()
        End If
    End If
End Function

Function echo_message(msg_str)
    TracePrint msg_str
    ShowMessage msg_str
End Function

Function end_script
    Delay 5000
    KeyPress "Power"
    EndScript
End Function

Dim all_retry_times = 5
echo_message "一切从这里开始..."
Dim wait_time
Randomize  
wait_time = Int(((15-2+1) * Rnd()) + 1)   
echo_message "等待:"&wait_time&"分钟"
wait_time = wait_time * 60 * 1000
//Traceprint wait_time
Delay wait_time
Rem Start
Rem 查找工作台按钮
Dim workbench_X = -1, workbench_Y = -1
Dim retry_times=3
Call find_workbench()
If workbench_X = -1 Or workbench_Y = -1 Then 
    echo_message "未找到“工作台”"
    end_script
End If
echo_message "工作台按钮: "&workbench_X&", "&workbench_Y
workbench_X = workbench_X + 40
Tap workbench_X, workbench_Y

Rem 查找打卡菜单
Dim x_y = find_pic_with_retry(165,474,265,526, "打卡.png", Null)
Dim clock_x = x_y(0)
Dim clock_y = x_y(1)
If clock_x = -1 Or clock_y = -1 Then 
    echo_message "未找到“打卡”菜单"
    end_script
End If
echo_message "打卡菜单:"&clock_X&", "&clock_Y
Tap clock_X, clock_Y

Rem 查找上下班Table页
Delay 1000
x_y = find_pic_with_retry(207, 247, 337, 292, "上下班_选中.png", "上下班.png")
Dim on_off_duty_x = x_y(0)
Dim on_off_duty_y = x_y(1)
If on_off_duty_x = -1 Or on_off_duty_y = -1 Then
    echo_message "未找到上下班Tabel页"
    end_script
Else 
    echo_message "上下班Table页:"&on_off_duty_x&", "&on_off_duty_y
    Tap on_off_duty_x, on_off_duty_y
End If

Rem 是否还在定位中
Dim time_out = 6
x_y = find_pic_with_retry(461,698,624,757, "定位中.png", Null)
Dim location_x = x_y(0)
Dim location_y = x_y(1)
If location_x > -1 Or location_y > -1 Then 
    echo_message "还在定位中,等待定位完成"
    If time_out > 0 Then 
        time_out = time_out - 1
        Delay 10000
        Goto 是否还在定位中
    End If
End If
If location_x > -1 Or location_y > -1 Then 
    echo_message "定位失败!"
End If

Rem 查找是否存在我要加班按钮
Delay 1000
x_y = find_pic_with_retry(371, 1790, 544, 1838, "我要加班.png", Null)
Dim overtime_work_x = x_y(0)
Dim overtime_work_y = x_y(1)
overtime_work_x = overtime_work_x + 100
overtime_work_y = overtime_work_y + 20
If overtime_work_x = -1 Or overtime_work_y = -1 Then 
    echo_message "没有找到我要加班的信息"
Else 
    //Tap overtime_work_x, overtime_work_y
    //Delay 1000
    echo_message "非工作日,不需要打卡"
    end_script
End If

Rem 查找是否存在不在打卡范围内的信息
x_y = find_pic_with_retry(173,696,912,760, "不在打卡范围内.png", Null)
Dim not_in_x = x_y(0)
Dim not_in_y = x_y(1)
If not_in_x > -1 or not_in_y > -1 Then 
    echo_message "不在打卡范围内,不做打卡操作"
    end_script
End If

Rem 查找上班打卡按钮
Delay 10000
x_y = find_pic_with_retry(173, 696, 912, 760, "已在打卡范围.png", Null)
Dim in_x = x_y(0)
Dim in_y = x_y(1)
If in_x = -1 or in_y = -1 Then 
    echo_message "没有找到已在打卡范围内的信息"
End If

Rem 查找上班打卡或下班打卡按钮
x_y = find_pic_with_retry(462, 1292, 620, 1337, "上班_下班打卡.png", Null)
Dim clock_in_out_x = x_y(0)
Dim clock_in_out_y = x_y(1)
If clock_in_out_x = -1 Or clock_in_out_y = -1 Then 
    echo_message "没有找到上班打卡或下班打卡的选项"
    If all_retry_times > 0 Then 
        all_retry_times = all_retry_times - 1
        echo_message "打卡失败,再来一次......"
        KillApp "com.tencent.wework"
        Delay 1000
        Goto Start
    End If
Else 
    echo_message "滴滴..."
    Tap clock_in_out_x, clock_in_out_y
    end_script
End If

 

小结

在整个调试过程中,按键精灵完成打卡步骤其实是很简单的,稍微有点编程基础的都可以很轻松的完成。

比较困难的是如何完成定时运行,由于之前没有这方便经验,包括Tasker、Magisk、Secure Settings等都折腾了很久,其实上述几个工具,真的很强大,可以完成很多的自动化事务,有兴趣的可以自行研究。

再次声明,此文仅是出于爱好,尝试自动化技术用于日常事务的可行性。强烈建议大家按时上下班,好好工作,不要将上班流于形式,害人害己。

企业微信自动打卡的实现

标签:tac   长按   cond   包安装   提示   选择   安全   randomize   ble   

原文:https://www.cnblogs.com/l200702031000/p/10260125.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号