草庐IT

C# adb封装类

将技术进行到底... 2023-03-28 原文

为了方便操作apk 实现app的自动化点击 封装了个adb操作类。基本上的操作都有了,

如果配合好C# 程序和模拟器 基本上什么样的操作都可以实现。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;

class Emulator {

    static readonly String ADBPATH = "D:/Microvirt/MEmu/"; //adb 所在目录
    static readonly String ROOTPATH = AppDomain.CurrentDomain.BaseDirectory;
    static readonly String SAVEPATH = AppDomain.CurrentDomain.BaseDirectory + "temp";
    static readonly String SNAPEPATH = SAVEPATH + @"\gsnap.png";
    static readonly String TEMPLATE = AppDomain.CurrentDomain.BaseDirectory + "template/";

    internal String devices { get; set; }

    internal Emulator() {
    }

    internal Emulator(String devices) {
        this.devices = devices;
    }
    //获取的所有能连接使用的设备
    internal List<String> GetDevices() {
        List<String> lst = new List<string>();
        String result = Common.Execute(ADBPATH + "adb devices");
        String[] lines = Regex.Split(result, "\r\n");// result.Split('\n');
        foreach (String line in lines) {
            if (line.Contains("\tdevice")) {
                lst.Add(line.Replace("\tdevice", ""));
            }
        }
        return lst;
    }
    //获取当前运行的APP 最顶层的Activity
    internal string GetTopActivity() {
        try {
            MatchCollection matchs;
            IEnumerator enumerator;
            String input = "";
            input = Common.Execute(ADBPATH + "adb -s " + devices + " shell dumpsys activity|findstr mFocusedActivity"); //获取最顶层的 activity
            if (input.IndexOf("HistoryRecord") > 0) {
                matchs = Regex.Matches(input, @"HistoryRecord.*?\}", RegexOptions.Singleline);
            }
            else {
                matchs = Regex.Matches(input, @"ActivityRecord.*?\}", RegexOptions.Singleline);
            }
            int num = 0;
            try {
                enumerator = matchs.GetEnumerator();
                while (enumerator.MoveNext()) {
                    Match current = (Match)enumerator.Current;
                    num++;
                    return current.Value;
                }
            }
            catch { }
            return "";
        }
        catch {
        }
        return "";
    }

    //截屏
    internal void snape() {
         Common.Execute(ADBPATH + "adb -s " + devices + " exec-out screencap -p > " + SNAPEPATH);
    }
    //载屏并保存为指定名称
    internal void snape(String name) {
        String path = SAVEPATH + "/" + name + ".bmp";
        Common.Execute(ADBPATH + "adb -s " + devices + " exec-out screencap -p > " + path);
    }

    //判断是否安装了某个包(APP)
    internal Boolean CheckApp(String package) {
        String Result = Common.Execute(ADBPATH + "adb -s " + devices + " shell pm list packages");
        return Result.IndexOf(package) > 0;
    }

    //安装APP
    internal Boolean install(String package) {
        String Result = Common.Execute(ADBPATH + "adb -s " + devices + " install " + package);
        return Result.IndexOf("Success", StringComparison.CurrentCultureIgnoreCase) > 0;
    }

    //卸载某个应用  //包名 可通过 adb shell pm list packages -s 来查看
    internal void uninstall(String package) {
         Common.Execute(ADBPATH + "adb -s " + devices + " uninstall " + package);
    }

    //启用APP  
    internal void start(String package) {
        Common.Execute(ADBPATH + "adb -s " + devices + " shell am start -n " + package);
    }
    //结束运行中的APP
    internal void stop(String package) {
        Common.Execute(ADBPATH + "adb -s " + devices + " shell am force-stop " + package);
    }

    //单击某区域
    internal void click(Point point) {
        String cmd = ADBPATH + "adb -s " + devices + " shell input tap " + (point.X) + " " + point.Y;
        Common.Execute(cmd);
    }
    //长按某个按
    internal void LongPress(String Key) {
        Common.Execute(ADBPATH + "adb - s " + devices + " input keyevent--longpress " + Key);
    }
    //按住某点滑动
    internal void swipe(Point first, Point second, int time) {
        Common.Execute(ADBPATH + "adb - s " + devices + " input swipe " + first.X + " " + first.Y + " " + second.X + " " + second.Y + " " + time);
    }

    //输入文本信息
    internal void text(String text) {
        Common.Execute(ADBPATH + "adb -s " + devices + " shell input text " + text);
    }
    //发送键值
    internal void key(String key) {
        Common.Execute(ADBPATH + "adb -s " + devices + " shell input keyevent " + key);
    }

    //检测某应用是否运行
    internal bool isrun(String packname) {
        String Result = Common.Execute(ADBPATH + "adb -s " + devices + " shell ps");
        return Result.IndexOf(packname, StringComparison.CurrentCultureIgnoreCase) > 0;
    }
    //滑动解锁
    internal void unlock() {
        StringBuilder cmd = new StringBuilder();
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 3 0 32");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 3 1 353");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 1 330 1");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 0 0 0");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 3 0 260");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 0 0 0");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 1 330 0");
        cmd.AppendLine(ADBPATH + "adb -s " + devices + " shell sendevent /dev/input/event0 0 0 0");
        Common.Execute(cmd.ToString());
    }
}

  

有关C# adb封装类的更多相关文章

  1. ruby-on-rails - 如何在 Ruby 中封装包含的模块方法? - 2

    我希望能够在包含该模块的类无法访问的模块中拥有方法。给定以下示例:classFooincludeBardefdo_stuffcommon_method_nameendendmoduleBardefdo_stuffcommon_method_nameendprivatedefcommon_method_name#blahblahendend我希望Foo.new.do_stuff爆炸,因为它试图访问模块试图对其隐藏的方法。不过,在上面的代码中,Foo.new.do_stuff可以正常工作:(有没有办法在Ruby中实现我想做的事情?更新-真正的代码classPlace"Place"}has_

  2. ruby - 如何在 Ruby Gem 中封装 Ruby C 扩展? - 2

    我找不到很多这方面的文档。如何打包gem,以便在安装gem时编译C扩展?特别是我想这样做:在Linux和MacOSX上,我想在安装gem时编译C扩展在Windows上,我想简单地安装一个预编译的.so对此的任何帮助,特别是示例源代码,都将非常有用:) 最佳答案 LuisLavena创造了rake-compiler只是为了这个目的。Homepage/GitHubGitHubWiki但是,您确定需要C扩展吗?关于C扩展的事情是,每个Ruby实现都有自己的C扩展API(而非基于C的API,如XRuby、JRuby、Ruby.NET、Iro

  3. ruby - Ruby 的 "Open Classes"会破坏封装吗? - 2

    在Ruby中,程序员可以更改预定义的类。所以一个非常糟糕的程序员可能会做这样的事情:classStringdef==(other)returntrueendend显然,几乎没有人会这么蠢,但是对预定义类进行更细微的更改可能会导致已经运行的代码出现问题的想法在我看来违反了封装原则。四个问题:首先,这是否实际上违反了面向对象的封装原则?其次,作为一名程序员,有没有一种方法可以保证我正在使用类的未修改版本的代码?第三,我应该在我的代码中“打开”类吗?原因?最后,在大规模生产编码环境中如何处理这类事情?换句话说,编程行业的人真的用其他人的代码来做这件事吗?将使用?或者即使他们不这样做,你如何确

  4. javascript - 如何封装mocha `expect()`代码? - 2

    我正在尝试测试是否存在一些我希望在所有测试中都需要的api响应属性(status和data属性)。这是一个通用测试,它断言supertest中的所需属性expect()方法:it('shouldcreateawidget',done=>{letstatus=200;request(test_url).post('/api/widgets').set('Authorization',`Bearer${token}`).send({sku:my_widget_data.sku,name:my_widget_data.name,description:''}).expect(res=>{as

  5. javascript - Angular Component 的 CSS 封装是如何工作的? - 2

    我想明白如果我创建两个样式表样式1.heading{color:green;}样式2.heading{color:blue;}现在如果这两个样式分别写在两个不同的View中,渲染的时候在布局上作为PartialView,那么在这种情况下可能会发生冲突一个可以覆盖另一个的样式。但是使用angular(见第16页),这两种不同组件的样式怎么封装在同一个页面上渲染呢?为什么CSS没有被覆盖?例如import{Component}from'@angular/core';@Component({selector:'app-user-item',template:'abc',styleUrls:[

  6. Go 封装http请求包Get、Post - 2

    之前已经封装过leveldb包.今天再把项目中经常会用到的一个技术封装成包,记录下来,仅供需要的小伙伴学习参考go如何封装包给别人和自己使用。有需要的小伙伴也可以在自己的项目中直接使用此包。这里小编以github为例(go的很多第三方包都在github上),其他平台大同小异。1.创建仓库去github上创建仓库,仓库命名为gorequest2.本地创建项目命名为gorequest。注意:因为go从1.11版本之后开始使用gomod管理包的版本。所以这里要想用gomod下载你封装的包,要生成go.mod文件gomodinit路径(路径要和你第一步创建的仓库路径保持一致)mkdirgoreques

  7. javascript - 封装在 Javascript 中 - 2

    我是Javascript的新手,我的SO个人资料可以证明这一点。我刚刚阅读了一些教程,遇到了一些我在应用Javascript时对面向对象和封装不完全理解的东西。教程指出Javascript对象可以这样声明:varmyCustomObject=newObject();你可以像这样给它实例变量:myCustomObject.myVariable="somevalue";myCustomObject.myOtherVariable="deadbeef";最后,它指出您可以创建一个模板函数来创建新对象,如下所示:functionCustomObject(myVariable,myOtherVa

  8. AD新建工程&快速绘制PCB封装 - 2

    目录一、准备工作一、新建项目 二、PCB建库一、准备工作一、新建项目1、“文件” ->“新的”->项目:默认设置即可,选择工程存放的路径2、新建原理图、PCB、原理图库、PCB库 二、PCB建库画封装主要有四个步骤:1.元件起名、2.放置引脚、3.放置丝印、4.放置3D外框    顶层TopLayer:画元器件的引脚(PAD)    丝印层TopOverlay:画外框    机械层Mechanical:画上一个3D外形在PCBLibrary👇         在顶层👇 只选四个引脚                 这样只会批量修改四个引脚CTRL+M可测量间距          在丝印层👇  

  9. javascript - 在 Getters 后面封装方法 - 2

    我正在使用node.js/express堆栈开发一个网站,我正在尝试以对我来说很新的函数式风格进行开发。express方式res.send要求将函数作为方法调用,因为它在函数体中引用this,但调用方法在函数式风格中并不自然。你可以把这个方法放在一个getter函数后面,把它变成一个函数,但我不知道除了代码复杂之外还有什么缺点吗?例子:(function(){"usestrict";functionFoo(){functionbar(){console.log(this.x);}return{bar,getbaz(){vars=this;return()=>s.bar();}}}var

  10. javascript - react - 在不破坏封装的情况下访问 DOM - 2

    是否有一种规范的方法可以在不破坏封装的情况下执行类似以下的操作?importReact,{Component,PropTypes}from'react';classDashboardextendsComponent{constructor(props,context){super(props,context);this.setRef=::this.setRef;}componentDidMount(){constnode=ReactDOM.findDOMNode(this.someRef);constnewHeight=window.innerHeight-node.offsetTop

随机推荐