51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2087|回复: 7
打印 上一主题 下一主题

[转贴] 把 Android 应用当成命令行工具来用

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-6-1 11:21:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
背景

这种方法的好处可以使用shell用户的权限调用Android系统中的一些特殊接口,比如模拟点击,屏幕截图。
命令行工具如何使用

比如一个Android的包名是 com.example.helloworld,首先拿到包在手机上的安装路径

$ adb shell pm path com.example.helloworld
# expect: package:/data/app/com.example.helloworld-1.apk

然后使用一个很长的命令调用启动helloworld中的Console.java中的代码

$ adb shell CLASSPATH=/data/app/com.example.helloworld-1.apk exec app_process /system/bin com.example.helloworld.Console --help
Usage of helloworld:
    -h, --help  print this message
    -v, --version show current version
    ... other ...

具体用法大概就是这样,接下来说下这个Console.java该怎么写
写一个支持命令行运行的helloworld.apk

使用AndroidStudio创建一个名叫HelloWorld的应用。然后在有MainActivity.java文件的目录下,创建一个Console.java的文件。把下面的代码直接粘贴过去

package com.example.helloworld;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* Created by hzsunshx on 2017/5/11.
*/

public class Console {
    private static final String PROCESS_NAME = "helloworld.cli";
    private static final String VERSION = "1.0";

    public static void main(String[] args) {
        setArgV0(PROCESS_NAME);

        for (String arg : args) {
            if (arg.equals("--help")) {
                System.out.println("TODO: Usage of " + PROCESS_NAME);
                return;
            } else if (arg.equals("--version")) {
                System.out.println(VERSION);
                return;
            } else {
                System.err.println("Error: unknown argument " + arg);
                System.exit(1);
            }
        }
    }

    private static void setArgV0(String text) {
        try {
            Method setter = android.os.Process.class.getMethod("setArgV0", String.class);
            setter.invoke(android.os.Process.class, text);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

这个代码比较简单,但是足够使用了。接下来用下外部的common-cli库,完善命令行的解析。

将compile group: 'commons-cli', name: 'commons-cli', version: '1.3.1'加入到build.gradle文件中
将main(String[] args)中的代码修改成

public static void main(String[] args) {
    setArgV0(PROCESS_NAME);

    Options options = new Options();
    options.addOption("v", "version", false, "show current version");
    options.addOption("h", "help", false, "show this message");

    CommandLineParser parser = new DefaultParser();
    HelpFormatter formatter = new HelpFormatter();
    CommandLine cmd;

    try {
        cmd = parser.parse(options, args);
    } catch (ParseException e) {
        System.err.println(e.getMessage());
        formatter.printHelp(PROCESS_NAME, options);
        System.exit(1);
        return;
    }

   if (cmd.hasOption("version")) {
        formatter.printHelp(PROCESS_NAME, options);
        return;
    }
    if (cmd.hasOption("version")) {
        System.out.println(VERSION);
        return;
    }
}

然后代码的上部加入import org.apache.commons.cli.*;

编译,然后安装到手机上,试试效果

$ adb shell CLASSPATH=/data/app/com.example.helloworld-2.apk exec app_process /system/bin com.example.helloworld.Console --help
usage: helloworld.cli
-h,--help      show this message
-v,--version   show current version

关于这个库的更详细的用法参考 https://commons.apache.org/proper/commons-cli/
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

3#
 楼主| 发表于 2017-6-1 11:31:48 | 只看该作者
回复 支持 反对

使用道具 举报

该用户从未签到

6#
发表于 2017-6-1 11:34:41 | 只看该作者
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-11 04:50 , Processed in 0.072027 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表