Appium从夜神模拟器获取钉钉通讯录

钉钉中有公司所有人的联系信息,可以查看。但是钉钉为了保护个人隐私,钉钉支持持个人把手机通讯录同步到钉钉,但是不允许普通用户把钉钉通讯录同步到手。只有部分管理员有权限从后台导入或导出所有人的联系方式和邮箱。
根据可见及可得的基本思想写下了下面主要代码。
遍历钉钉中组织架构下所有人的联系方式并组合成一个字符串。
主要使用appium自动化测试。夜神模拟器做测试机。
本来使用python编码,但是发现没有java严谨。java编码更加方便,都拼写要求比较低。

  1. 为了能正常运行可能要安装adb

  2. 启动夜神模拟器 使用命令 adb devices 查找模拟器调试接口 程序中会用到

  3. 启动appium 配置一个调试(可以直接写代码)能够正常连接 模拟器

     {
       "platformName": "Android",
       "platformVersion": "4.4.4",
       "deviceName": "emulator-5554",
       "appPackage": "com.alibaba.android.rimet",
       "appActivity": "com.alibaba.android.rimet.biz.SplashActivity",
       "remoteAdbHost": "localhost"
     }
    
  4. 连接成功后,使用java程序连接并开始写代码。

     public class Main {
    
         private AndroidDriver driver;
    
         @Before
         public void setUp() throws MalformedURLException {
             DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
             desiredCapabilities.setCapability("platformName", "Android");
             desiredCapabilities.setCapability("platformVersion", "4.4.4");
             desiredCapabilities.setCapability("deviceName", "emulator-5554");
             desiredCapabilities.setCapability("appPackage", "com.alibaba.android.rimet");
             desiredCapabilities.setCapability("appActivity", "com.alibaba.android.rimet.biz.SplashActivity");
             desiredCapabilities.setCapability("remoteAdbHost", "localhost");
    
             URL remoteUrl = new URL("http://localhost:4723/wd/hub");
    
             driver = new AndroidDriver(remoteUrl, desiredCapabilities);
         }
    
         @Test
         public void sampleTest() {
             try {
                 java.lang.Thread.sleep(3000);
                 MobileElement el1 = (MobileElement) Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/login_slide_btn",0);
                 el1.click();
                 MobileElement el2 = (MobileElement) Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/et_phone_input",0);
                 el2.sendKeys("<账号>");
                 MobileElement el3 = (MobileElement) Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/et_pwd_login",0);
                 el3.sendKeys("<密码>");
                 MobileElement el4 = (MobileElement) Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/btn_next",0);
                 el4.click();
                 MobileElement el5 = (MobileElement) Utils.waitForElementById(driver,"android:id/button1",0);
                 el5.click();
                 MobileElement el6 = (MobileElement) Utils.waitForElementByAccessibilityId(driver,"同意",0);
                 el6.click();
    
                 MobileElement el7 = (MobileElement) Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/home_bottom_tab_button_contact",0);
                 el7.click();
    
                 List<MobileElement> el8s = driver.findElementsById("com.alibaba.android.rimet:id/cell_title");
                 for(MobileElement element : el8s){
                     if ("组织架构".equals(element.getText())){
                         element.click();
                         AllPages.start(driver);
                         break;
                     }
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
    
         @After
         public void tearDown() {
             driver.quit();
         }
     }
    

setUp() 连接模拟器指定应用,并启动。
sampTest() 登录并找到组织架构
tearDown() 停止

  1. 遍历组织架构

     public class AllPages {
    
         static String AllUser = "";
    
         static public void start(AndroidDriver driver){
             String source = driver.getPageSource();
             System.out.println(source);
             MobileElement list_view = Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/list_view",0);
             List<MobileElement> contents = list_view.findElementsById("com.alibaba.android.rimet:id/rl_content");
             for(MobileElement element : contents){
                 MobileElement titleEle = element.findElementById("com.alibaba.android.rimet:id/tv_dept_name");
                 System.out.println(titleEle.getText());
                 scanFromElement(driver,titleEle);
             }
         }
    
         static public void scanFromElement(AndroidDriver driver,MobileElement rootElement){
             try {
                 rootElement.click();
                 java.lang.Thread.sleep(3000);//等待页面加载
                 String source = driver.getPageSource();
                 System.out.println(source);
    
                 MobileElement list_view = Utils.waitForElementById(driver,"com.alibaba.android.rimet:id/list_view",0);
    
                 List<MobileElement> items = list_view.findElementsById("com.alibaba.android.rimet:id/tv_contact_name");
                 for (MobileElement item : items) {
                     System.out.println(item.getText());
                     getPersenalInfoWithElement(driver,item);
                 }
    
                 List<MobileElement> contents = list_view.findElementsById("com.alibaba.android.rimet:id/rl_content");
                 for(MobileElement element : contents){
                     try {
                         MobileElement titleEle = element.findElementById("com.alibaba.android.rimet:id/tv_dept_name");
                         System.out.println(titleEle.getText());
                         scanFromElement(driver,titleEle);
                     }catch (Exception e){
                         e.printStackTrace();
                     }
                 }
                 MobileElement up = (MobileElement) driver.findElementByXPath("//android.widget.HorizontalScrollView/android.widget.LinearLayout/android.widget.LinearLayout[last()-1]");
                 up.click();
                 java.lang.Thread.sleep(3000);//等待页面加载
             }catch (Exception e) {
                 e.printStackTrace();
             }
         }
    
         static public void getPersenalInfoWithElement(AndroidDriver driver,MobileElement element){
             try {
                 String fileName = element.getText();
                 element.click();
                 java.lang.Thread.sleep(3000);//等待页面加载
                 String source = driver.getPageSource();
                 writeFile(fileName,source);
                 System.out.println(source);
    
                 getUserInfo(driver);
    
                 MobileElement back =(MobileElement) driver.findElementByXPath("//android.widget.ImageButton[@content-desc=\"返回\"]");
                 back.click();
             }catch (Exception e){
                 e.printStackTrace();
             }
         }
    
         static public void writeFile(String fileName,String content){
             try{
                 FileWriter writer = new FileWriter("/Users/cai/Desktop/appium/_333/files/"+fileName+".xml");
                 writer.write(content);
                 writer.flush();
                 writer.close();
             }catch (IOException e){
                 e.printStackTrace();
             }
         }
    
         static public void getUserInfo(AndroidDriver driver){
    
             try{
    
                 String userInfo = "";
    
                 List<MobileElement> keys1 = driver.findElementsById("com.alibaba.android.rimet:id/cell_title");
                 List<MobileElement> values1 = driver.findElementsById("com.alibaba.android.rimet:id/cell_subTitle");
    
                 for (int i=0;i<keys1.size() && i<values1.size();i++){
                     try {
                         MobileElement keyEle = keys1.get(i);
                         MobileElement valueEle = values1.get(i);
                         String key = keyEle.getText();
                         String value = valueEle.getText();
                         userInfo = userInfo+key+":"+value+",";
                     }catch (Exception e){
                         e.printStackTrace();
                     }
                 }
    
                 try{
                     MobileElement mobileValueEle =(MobileElement) driver.findElementById("com.alibaba.android.rimet:id/user_mobile_info_content_tv");
                     String mobile = mobileValueEle.getText();
                     userInfo = userInfo+"mobile:"+mobile+",";
                 }catch (Exception e){
                     e.printStackTrace();
                 }
    
                 try{
                     MobileElement mailValueEle =(MobileElement) driver.findElementById("com.alibaba.android.rimet:id/user_mail_info_content_tv");
                     String email = mailValueEle.getText();
                     userInfo = userInfo+"email:"+email+",";
                 }catch (Exception e){
                     e.printStackTrace();
                 }
    
                 AllUser = AllUser + userInfo + "\n";
                 System.out.println(AllUser);
             }catch (Exception e){
                 e.printStackTrace();
             }
         }
     }
    

start()开始遍历每个item
scanFromElement()点击进入每个item,这里分成两类,一类是人的信息,一类是组织信息。如果是组织信息继续进入深度优先遍历。
getPersenalInfoWithElement()获取个人信息
writeFile()所有个人信息页面信息保存
getUserInfo()提取关键信息

  1. 代码中使用到的工具类

     public class Utils {
         static public MobileElement waitForElementById(AndroidDriver driver, String elementId, int timeout){
             int cout = 0;
             while (timeout == 0 || timeout>0 && cout<timeout) {
                 try {
                     return (MobileElement) driver.findElementById(elementId);
                 } catch (Exception e) {
                     cout = cout + 1;
                     System.out.println(elementId+":"+cout);
                 }
             }
             return null;
         }
    
         static public MobileElement waitForElementByAccessibilityId(AndroidDriver driver, String AccessibilityId, int timeout){
             int cout = 0;
             while (timeout == 0 || timeout>0 && cout<timeout) {
                 try {
                     return (MobileElement) driver.findElementById(AccessibilityId);
                 } catch (Exception e) {
                     cout = cout + 1;
                     System.out.print(AccessibilityId+":"+cout);
                 }
             }
             return null;
         }
     }
    

因为有这个程序中有很多延时,完整运行完程序可能会有很长时间。复制最后日志中打印的结果就可以保存成文件了。这里没有写保存文件的代码。

源码:https://github.com/caicai0/getDingDingAddressBook
iOS利用Contacts.framework导入表格通讯录: https://www.jianshu.com/p/279da431ce0d
ios 导入通讯录demo:https://github.com/caicai0/ios_demo/tree/master/contacts_demo

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,417评论 2 45
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    wgl0419阅读 6,270评论 1 9
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,383评论 0 17
  • 卡牌测试得分 红色17分 绿色 12分 黄色 8分 蓝色 0分 性格描述:你是一个红色性格显著兼有绿色性格特点的人...
    未央行者阅读 148评论 0 0
  • 林黛玉 绝世聪明绝代愁, 惜花人不为花留。 于今香冢埋芳草, 当日春风绕画楼。 满地落红飞灿烂, 一林娇鸟叫勾輈。...
    六个太阳金阅读 4,109评论 1 7