【问题标题】:How to install an app in system/app while developing from android studio从android studio开发时如何在系统/应用程序中安装应用程序
【发布时间】:2015-04-02 21:07:36
【问题描述】:

在Android Studio上开发时,有没有办法让应用直接安装在system/app文件夹中(设备已root)?

意思是,当我按下“运行应用程序”按钮时,我希望将 apk 放置在系统/应用程序中。

如果无法做到这一点,那么在构建和测试系统应用程序时,推荐的最方便的方法是什么?

【问题讨论】:

    标签: android android-studio


    【解决方案1】:

    从 AS 自动部署系统应用

    您可以创建一个脚本来完成这项工作,并在您每次在 AS 中运行时自动运行它。

    1。创建脚本

    您可以调整我根据需要创建的脚本。放在:project_directory/installSystem.sh

    #!/bin/bash
    
    # CHANGE THESE FOR YOUR APP
    app_package="com.example"
    dir_app_name="MySysApp"
    MAIN_ACTIVITY="SysAppMainActivity"
    
    ADB="adb" # how you execute adb
    ADB_SH="$ADB shell" # this script assumes using `adb root`. for `adb su` see `Caveats`
    
    path_sysapp="/system/priv-app" # assuming the app is priviledged
    apk_host="./app/build/outputs/apk/app-debug.apk"
    apk_name=$dir_app_name".apk"
    apk_target_dir="$path_sysapp/$dir_app_name"
    apk_target_sys="$apk_target_dir/$apk_name"
    
    # Delete previous APK
    rm -f $apk_host
    
    # Compile the APK: you can adapt this for production build, flavors, etc.
    ./gradlew assembleDebug || exit -1 # exit on failure
    
    # Install APK: using adb root
    $ADB root 2> /dev/null
    $ADB remount # mount system
    $ADB push $apk_host $apk_target_sys
    
    # Give permissions
    $ADB_SH "chmod 755 $apk_target_dir"
    $ADB_SH "chmod 644 $apk_target_sys"
    
    #Unmount system
    $ADB_SH "mount -o remount,ro /"
    
    # Stop the app
    $ADB shell "am force-stop $app_package"
    
    # Re execute the app
    $ADB shell "am start -n \"$app_package/$app_package.$MAIN_ACTIVITY\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER"
    

    2。用 AS Run 绑定它

    1. 转到运行 -> 编辑配置
    2. 在(您的模块的)常规标签上进行以下更改

      • 安装选项->延迟:没有
      • 启动选项->启动:没有
      • 发布前:+,然后按Run External Tool,选择您的脚本。
        • 在新对话框中:
          • 设置任何名称。
          • 在“工具设置”->程序中:导航到项目的目录,然后选择您的脚本

    注意事项:

    首次安装

    设备需要在第一次安装应用时重新启动 (adb reboot)一次。之后,您只需按Run,一切都会自动发生。

    这是因为主机编译器 (dex2oat) 不会自动调用。不知何故,操作系统还没有收到这个新系统应用程序的通知。手动调用 dex2oat 应该可以解决这个问题,但我没有运气。如果有人解决了,请分享。

    adb root 问题

    有时(通常是重新启动后的初始执行)对adb root 的调用找不到设备。您可以简单地从AStudiosleep 在成功adb root 后重新播放一秒钟。

    使用su 而不是adb root

    adb push 将无法工作,尽管已安装系统并授予权限。要使其正常工作,请使用以下内容替换 ADB_SH 变量和脚本的安装部分:

    ..
    ADB_SH="$ADB shell su -c"
    ..
    # Install APK: using adb su
    $ADB_SH "mount -o rw,remount /system"
    $ADB_SH "chmod 777 /system/lib/"
    $ADB_SH "mkdir -p /sdcard/tmp" 2> /dev/null
    $ADB_SH "mkdir -p $apk_target_dir" 2> /dev/null
    $ADB push $apk_host /sdcard/tmp/$apk_name 2> /dev/null
    $ADB_SH "mv /sdcard/tmp/$apk_name $apk_target_sys"
    $ADB_SH "rmdir /sdcard/tmp" 2> /dev/null
    

    【讨论】:

    • 这太棒了!不过我做了一个小改动,从 Android 4.3+ 开始,路径不是/system/app,应该是/system/priv-app,谢谢你,它帮助我自动化了构建过程。
    • 这个脚本真的很有用!在 Windows 上,我必须对其进行一些修改以使其工作:ADB_EXE=/c/ADB/adbADB_SH="$ADB_EXE shell" 并且在任何地方调用 adb,将其替换为 $ADB_SH。此外,在第 2 节中,在工具设置中,程序部分:例如,将 C:\Program Files\Git\usr\bin\bash.exe 放在 Params 部分,即脚本的路径。
    • @Paschalis 我试过这个,但它给出了错误 = 13(权限被拒绝)。你知道如何绕过它吗?谢谢
    • @JoãoCartucho 试试chmod +x installSystem.sh
    • 如果你想让它在虚拟设备上工作,你必须使用emulator -avd AVD_NAME -writable-system启动模拟器。
    【解决方案2】:

    有兴趣的人可以使用 Windows 脚本:

    以相同的方式存储此文件:在项目目录的根目录 (installSysPrivApp.bat)

    ::WIN BATCH SCRIPT
    
    :: CHANGE THESE
    set app_package=com.example.package
    set dir_app_name=app
    set MAIN_ACTIVITY=MainActivity
    
    set ADB="adb"
    ::ADB_SH="%ADB% shell" # this script assumes using `adb root`. for `adb su` 
    see `Caveats`
    
    set path_sysapp=/system/priv-app
    set apk_host=.\Application\build\outputs\apk\Application-debug.apk
    set apk_name=%dir_app_name%.apk
    set apk_target_dir=%path_sysapp%/%dir_app_name%
    set apk_target_sys=%apk_target_dir%/%apk_name%
    
    :: Delete previous APK
    del %apk_host%
    
    :: Compile the APK: you can adapt this for production build, flavors, etc.
    call gradlew assembleDebug
    
    set ADB_SH=%ADB% shell su -c
    
    :: Install APK: using adb su
    %ADB_SH% mount -o rw,remount /system
    %ADB_SH% chmod 777 /system/lib/
    %ADB_SH% mkdir -p /sdcard/tmp
    %ADB_SH% mkdir -p %apk_target_dir%
    %ADB% push %apk_host% /sdcard/tmp/%apk_name% 
    %ADB_SH% mv /sdcard/tmp/%apk_name% %apk_target_sys%
    %ADB_SH% rmdir /sdcard/tmp
    
    :: Give permissions
    %ADB_SH% chmod 755 %apk_target_dir%
    %ADB_SH% chmod 644 %apk_target_sys%
    
    ::Unmount system
    %ADB_SH% mount -o remount,ro /
    
    :: Stop the app
    %ADB% shell am force-stop %app_package%
    
    :: Re execute the app
    %ADB% shell am start -n \"%app_package%/%app_package%.%MAIN_ACTIVITY%\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
    

    【讨论】:

    • 我收到 CreateProcess 错误 = 193。您知道如何解决此错误吗?
    • 只是一个可能的改进:删除删除之前的APK并调用Gradle的行。让 Android Studio 自己来做。它给了我启用的错误。所以我评论了这两行,让 Android Studio 与 Gradle 混淆。然后该脚本仅安装 Android Studio 使用 Gradle 创建的 APK。也许这在 Linux 上也是一个好主意,不知道(我不将 Linux 与 Android Studio 一起使用)。我还将set apk_host 行设置为set apk_host=.\app\build\outputs\apk\debug\app-debug.apk,因为Android Studio 将APK 放在那里。
    【解决方案3】:

    在将系统重新安装为只读之前,在包管理器的帮助下绕过@paschalis 回答重新安装应用程序的重新启动问题:

    # Reinstall app
    $ADB_SH "pm install -r $apk_target_sys"
    
    # Unmount system
    $ADB_SH "mount -o remount,ro /"
    

    包管理器会自己调用 dex2oat。

    【讨论】:

      【解决方案4】:

      (Android Q >> Windows)

      ::WIN BATCH SCRIPT
      ::setup emulator https://stackoverflow.com/a/64397712/13361987
      
      :: CHANGE THESE 
      set app_package=com.project.package
      set dir_app_name=NewApkName
      set MAIN_ACTIVITY=Package.MainActivity
      
      set ADB="adb"
      
      set path_sysapp=/system/priv-app
      set apk_host=.\app\build\outputs\apk\debug\app-debug.apk
      set apk_name=%dir_app_name%.apk
      set apk_target_dir=%path_sysapp%/%dir_app_name%
      set apk_target_sys=%apk_target_dir%/%apk_name%
      
      :: Delete previous APK
      del %apk_host%
      
      ::  Compile the APK: you can adapt this for production build, flavors, etc.
      call gradlew assembleDebug
      
      set ADB_SH=%ADB% shell su 0
      
      :: Install APK: using adb su
      %ADB_SH% mount -o remount,rw /system
      %ADB_SH% chmod 777 /system/lib/
      %ADB_SH% mkdir -p /sdcard/tmp
      %ADB_SH% mkdir -p %apk_target_dir%
      %ADB% push %apk_host% /sdcard/tmp/%apk_name%
      %ADB_SH% mv /sdcard/tmp/%apk_name% %apk_target_sys%
      %ADB_SH% rm -r /sdcard/tmp
      
      :: Give permissions
      %ADB_SH% chmod 755 %apk_target_dir%
      %ADB_SH% chmod 644 %apk_target_sys%
      
      :: Unmount system
      %ADB_SH% mount -o remount,ro /
      
      :: Stop the app 
      %ADB% shell am force-stop %app_package%
      
      :: Re execute the app
      %ADB% shell am start -n \"%app_package%/%app_package%.%MAIN_ACTIVITY%\" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
      
      
      
      
      :: from >> https://stackoverflow.com/questions/28302833/how-to-install-an-app-in-system-app-while-developing-from-android-studio
      

      【讨论】:

        【解决方案5】:

        Mac 版

        通过使用@Paschalis 的脚本,我首先遇到了 3 个问题,我无法从 adb 安装系统,所以我只使用来自 jack palevich 的“用于 android 的终端模拟器”(需要一次)https://play.google.com/store/apps/details?id=jackpal.androidterm

        mount -o rw,remount /system
        

        第二个问题是JRE和Android studio不一样。

        所以我加了

         export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home/
        

        拥有与 android studio 使用的相同版本的 java(在 android studio 中使用“ctrl + ;”来获取此路径)

        最后一个问题是因为 adb root 无法在生产版本中运行,所以我用 magisk 刷新了这个 zip

        https://github.com/evdenis/adb_root

        Android: adbd cannot run as root in production builds

        但后来我的手机不再被检测到,所以我删除了 adb root,这一次一切正常。

        还可以尝试在终端中逐行手动运行脚本以调试此脚本 android studio 不会给出所有错误。

        【讨论】:

          【解决方案6】:

          我认为adb push *.apk /system/app/*.apk 应该没问题。

          我不了解 Android Studio,但如果您使用的是 Linux,您可以尝试为

          创建一个别名
          adb install
          

          指向那个命令,它应该可以工作!

          【讨论】:

          • 这不起作用。得到“无法将'[文件名]'复制到'/system/app/[文件名]':只读文件系统”。我已经看到了使您的建议发挥作用的流程,例如 stackoverflow.com/a/10362072/876603,但这是一个非常长的开发流程
          • 你说得对,我忘了你还必须重新挂载文件系统 rw 才能使这个技巧起作用......我不知道任何其他方法,抱歉
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多