如何为Android shell构建可执行文件

13
有时我需要在设备上运行命令或脚本,但它们不可用或不存在。
我们是否可以向 Android 设备的 shell 添加一些附加命令,除了已经可用的命令?
例如,向我的设备添加 screenrecord 命令(我的设备的 Android API 低于19),这在我的设备上不可用。
我知道如何使用 adb shell 获取设备上可用命令的列表。
adb shell ls /system/bin 

但是我想添加更多的自定义命令和脚本,以完成一些特殊的工作。

有没有办法做到这一点?或者说这是不可能的?


请参阅官方指南,这里的答案已经过时或过于复杂。如果想要最简单的方法(一行编译,无需构建系统),请查看此链接 - user_
请参阅官方指南,这里的答案已经过时或者过于复杂。如果想要最简单的方法(一行编译,无需构建系统),请参阅此链接 - undefined
3个回答

50

本答案提供了通过 Eclipse(已过时)和 Android Studio(截至撰写时为4.1+版本)两种方式构建 Android shell 可执行文件的步骤序列。后者包括使用 ndk-buildCMake


I. 准备源代码

mycommand.c 为例:

#include <stdio.h>

int main()
{
    printf("My Command!\n");
    return 0;
}

II. 生成可执行文件

Eclipse(可能已过时)

假设在 Eclipse 中已经设置了 NDK 的路径,创建一个新的 Android 应用程序项目 并按照以下步骤进行操作。

  1. Add native support. Right click on the project in Project Explorer > Android Tools > Add Native Support > Finish

  2. Add source code, i.e. put mycommand.c under project_root/jni folder.

  3. Edit Android.mk under project_root/jni as follows:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE     := mycommand
    LOCAL_SRC_FILES  := mycommand.c
    
    include $(BUILD_EXECUTABLE)
    
  4. Create Application.mk * under the project_root/jni folder:

    APP_ABI := all
    
  5. Build executable and find it under project_root/libs/<abi>/mycommand.

*此处生成适用于所有支持CPU架构的二进制文件。使用adb shell cat /proc/cpuinfo命令查找CPU架构,并根据支持的 ABI设置APP_ABI


Android Studio和ndk-build

步骤如下:

  1. Add mycommand.c, Android.mk (same as in the Eclipse section above) to the /app/src/main/cpp folder.

  2. Edit build.gradle:

    android {
        ...
        defaultConfig {
            ...
            externalNativeBuild {
                ndkBuild {
                    targets "mycommand"
                    // use a specific ABI filter if needed
                    // abiFilters "armeabi-v7a"
                }
            }
        }
        externalNativeBuild {
            ndkBuild {
                path "src/main/cpp/Android.mk"
            }
        }
    }
    
  3. Build project and find the executable under /app/.externalNativeBuild/ndkBuild/debug/obj/local/<abi>/mycommand

Android Studio和CMake

  1. Create a project using the Native C++ template.

  2. Add mycommand.c to the /app/src/main/cpp folder and edit CMakeLists.txt:

    cmake_minimum_required(VERSION x.x.x)
    
    add_executable(mycommand
                   mycommand.c )
    
  3. Edit build.gradle:

    android {
        ...
        defaultConfig {
            ...
            externalNativeBuild {
                cmake {
                    targets "mycommand"
                    // use a specific ABI filter if needed
                    // abiFilters "armeabi-v7a"
                }
            }
        }
        ...
        externalNativeBuild {
            cmake {
                path "src/main/cpp/CMakeLists.txt"
            }
        }
    }
    
  4. Build project and find the executable under /app/build/intermediates/cmake/debug/obj/<abi>/mycommand


三. 将二进制文件推送到设备

从源地址将 mycommand 二进制文件推送到设备中。请注意,SD卡上的文件默认情况下不可执行,因此应将二进制文件推送到设备的内部存储器中。根据设备是否已经root,您有以下选项:

  • On non-rooted device you can push the binary to /data/local/tmp:

     adb push mycommand /data/local/tmp
    
  • On rooted device you can push the binary to SD card and then copy it to /system/bin (after remounting the partition in read-write mode) along with the other executable files:

     adb push mycommand /path/to/sdcard
     adb shell
     su
     mount -o rw,remount /system
     cp /path/to/sdcard/mycommand /system/bin
    

IV. 设置可执行权限(可选

设置二进制文件的权限为可执行(如果使用/data/local/tmp则可能不需要此步骤)。以下是使用chmod 555(r-xr-xr-x)命令:

adb shell chmod 555 /path/to/mycommand

V. 执行命令

现在,您可以通过运行 adb shell 命令,进入设备的 shell 并执行命令。

  • On non-rooted device use the absolute path to the command:

     $ /data/local/tmp/mycommand
     My Command!
    
  • On rooted device, in case the binary has been copied to /system/bin, you can call it by the file name:

     $ mycommand
     My Command!
    

好的。我创建了一个空项目,将 mycommand.cAndroid.mk 添加到 app/src/main/cpp 目录下,并编辑了 build.gradle 文件,仅仅添加了推荐的内容(针对 ndk 的情况),然后进行构建 APK。构建失败,出现以下错误: - Olorin
在类型为org.gradle.api.Project的根项目"MyConsoleApplication4"上,找不到参数[build_4wbyjnnxfo36n8uu8rkjatpia$_run_closure1@332ef9dd]的android()方法。 - Olorin
1
抱歉这么晚才回复。在Android Studio中,你应该选择位于“手机和平板电脑”选项卡上的“本机C++”模板(向下滚动到模板位置)。 - Onik
有没有不用Android Studio的示例?我需要构建标志,因为我遇到了“TLS段未对齐”的错误。 - Trương Quốc Khánh
是否可以自动将已构建的可执行二进制文件打包到应用程序模块中?比如放在资产文件夹里之类的地方? - 3c71
显示剩余2条评论

3

如果你在这个位置没有Android和ndk-build的二进制文件,它们位于

app\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a\objs-debug\test1

对于arm64-v8a和其他平台有相应的二进制文件。


2
如果你遇到了这个错误:error: only position independent executables (PIE) are supported,当你使用CMake创建可执行文件时,
请在app gradle中添加以下代码:
default config
{
..........
..........
externalNativeBuild
{
 cmake 
  { 
   targets "my_command"
   abiFilters "armeabi-v7a"
   arguments "-DANDROID_PIE=ON" //important
  }
 }
...........
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接