【问题标题】:How can I adb install an apk to multiple connected devices?如何 adb 将 apk 安装到多个连接的设备?
【发布时间】:2012-01-26 11:59:06
【问题描述】:

我的开发机器中插入了 7 台设备。

我通常使用adb install <path to apk>,并且只能安装到单个设备上。

现在我想在我所有的 7 个连接设备上安装我的 apk。如何在单个命令中执行此操作?也许我想运行一个脚本。

【问题讨论】:

标签: java android eclipse adb adt


【解决方案1】:

您可以使用adb devices 获取已连接设备的列表,然后为列出的每个设备运行adb -s DEVICE_SERIAL_NUM install...

类似(bash):

adb devices | tail -n +3 | cut -sf 1 -d " " | xargs -iX adb -s X install ...

评论表明这可能对新版本更有效:

adb devices | tail -n +2 | cut -sf 1 | xargs -iX adb -s X install ...

对于 Mac OSX(未在 Linux 上测试):

adb devices | tail -n +2 | cut -sf 1 | xargs -I {} adb -s {} install ...

【讨论】:

  • 谢谢!不幸的是,我无法让脚本运行。我不是 shell 脚本专家。我得到错误:xargs: illegal option -- i usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr] [-L number] [-n number [-x]] [-P maxprocs] [-s size] [utility [argument ...]]
  • 尝试用-I X替换-iX
  • 您是否将... 替换为您的APK 名称?尝试用echo X 替换整个最后的adb 调用,以确保它打印出您期望的值。
  • adb devices | tail -n +3 | cut -sf 1 -d " " | xargs -I X echo X -s X install SONR 不打印任何内容
  • adb devices 怎么样? adb 甚至会看到您的设备吗?
【解决方案2】:

其他答案非常有用,但并没有完全满足我的需求。我想我会发布我的解决方案(一个 shell 脚本),以防它为其他读者提供更清晰的信息。它安装多个 apk 和任何 mp4

echo "Installatron"

for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
do 
  for APKLIST in $(ls *.apk);
  do
  echo "Installatroning $APKLIST on $SERIAL"
  adb -s $SERIAL install $APKLIST
  done

  for MP4LIST in $(ls *.mp4);
  do
  echo "Installatroning $MP4LIST to $SERIAL"
  adb -s $SERIAL push $MP4LIST sdcard/
  done
done

echo "Installatron has left the building"

感谢所有其他让我走到这一步的答案。

【讨论】:

    【解决方案3】:

    这是根据 kichik 的回复量身定制的功能性单行命令(谢谢!):

    adb 设备 |尾-n +2 |切-sf 1 | xargs -iX adb -s X install -r *.apk

    但如果你碰巧使用的是 Maven,那就更简单了:

    mvn android:部署

    【讨论】:

    • 如何为 Android 设置这个?
    • 对我不起作用。输出:xargs: adb: 由信号 13 终止
    【解决方案4】:

    另一个简短的选择...我偶然发现了这个页面,得知-s $SERIAL 必须位于实际的 adb 命令之前!感谢stackoverflow!

    for SERIAL in $(adb devices | grep -v List | cut -f 1);
    do `adb -s $SERIAL install -r /path/to/product.apk`;
    done
    

    【讨论】:

      【解决方案5】:

      来自 Dave Owens 的通用解决方案,可在所有设备上运行任何命令:

      for SERIAL in $(adb devices | grep -v List | cut -f 1);
      do echo adb -s $SERIAL $@;
      done
      

      将其放入“adb_all”之类的脚本中,并在单个设备上使用与 adb 相同的方式。

      我发现的另一件好事是为每个命令分叉后台进程,并等待它们完成:

      for SERIAL in $(adb devices | grep -v List | cut -f 1);
      do adb -s $SERIAL $@ &
      done
      
      for job in `jobs -p`
      do wait $job
      done
      

      然后您可以轻松创建脚本来安装应用并启动活动

      ./adb_all_fork install myApp.apk
      ./adb_all_fork shell am start -a android.intent.action.MAIN -n my.package.app/.MainActivity
      

      【讨论】:

      • 我非常喜欢这个想法。在我的 ~/bin 文件夹中效果很好。
      【解决方案6】:

      我喜欢workingMatt's script,但认为它可以改进一点,这是我的修改版本:

      #!/bin/bash
      
      install_to_device(){
      local prettyName=$(adb -s $1 shell getprop ro.product.model)
      echo "Starting Installatroning on $prettyName"
      for APKLIST in $(find . -name "*.apk" -not -name "*unaligned*");
        do
        echo "Installatroning $APKLIST on $prettyName"
        adb -s $1 install -r $APKLIST
        adb -s $1 shell am start -n com.foo.barr/.FirstActivity;
        adb -s $1 shell input keyevent KEYCODE_WAKEUP
        done
        echo "Finished Installatroning on $prettyName"
      }
      
      echo "Installatron"
      gradlew assembleProdDebug
      
      for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
      do 
        install_to_device $SERIAL&
      done
      

      我的版本做同样的事情,除了:

      • 它从项目的根目录中查找 apk
      • 它同时安装到每台设备上
      • 它不包括“未对齐”的 apk 版本(这些只是被对齐的版本安装了
      • 它显示手机的可读名称,而不是它们的设备 ID

      还有一些方法可以改进,但我很满意。

      【讨论】:

      【解决方案7】:

      以下命令应该可以工作:

      $ adb devices | tail -n +2 | head -n -1 | cut -f 1 | xargs -I X adb -s X install -r path/to/your/package.apk
      

      adb devices 返回设备列表。使用 tail -n +2 从第 2 行开始,使用 head -n -1 删除末尾的最后一个空白行。使用默认的制表符分隔符通过管道让我们获得第一列,即连续剧。

      xargs 用于为每个序列运行 adb 命令。如果您不重新安装,请删除 -r 选项。

      【讨论】:

      • 这仅在我从 head 命令中删除 -1 并替换为 1 后才有效。而且这仅安装在第一台设备上,而不是全部。如果我不在 head 命令上用 1 替换 -1,我会得到一个 ./adb devices |尾-n +2 | head -n -1 head: 非法行数 -- -1
      • head: 非法行数 -- -1
      【解决方案8】:

      使用this script,您可以这样做:

      adb+ install <path to apk>
      

      干净,简单。

      【讨论】:

      • 完美,如果我们可以将它与通过 tcpip 连接的 Genymotion 设备一起使用...无法使用 -s 引用它们
      • @Jose_GD 为什么不呢?看我的回答,我成功使用了
      • @Drew 对不起,你是对的。后来才知道 -s ip_address 是可以的。
      • 有什么方法可以并行吗?现在,此脚本一次按顺序安装到一台设备上。
      【解决方案9】:

      如果您不想使用未启用 adb 的设备;用这个

      Mac/Linux

      adb devices | grep device | grep -v devices | awk '{print$1}' | xargs -I {} adb -s {} install path/to/yourApp.apk 
      
      adb devices | grep device | grep -v devices | cut -sf 1 | xargs -I {} adb -s {} install path/to/yourApp.apk
      

      【讨论】:

        【解决方案10】:

        使用此命令行实用程序:adb-foreach

        【讨论】:

          【解决方案11】:

          PowerShell 解决方案

          function global:adba() {
              $deviceIds = iex "adb devices" | select -skip 1 |  %{$_.Split([char]0x9)[0].Trim() } | where {$_ -ne "" }
              foreach ($deviceId in $deviceIds) {
                  Echo ("--Executing on device " + $deviceId + ":---")
                  iex ("adb -s $deviceId " + $args)
              }
          }
          

          将其放入您的配置文件 (notepad $PROFILE),重新启动您的 shell,您可以调用安装:

          adba install yourApp.apk
          

          【讨论】:

            【解决方案12】:

            此命令完美运行 adb devices | awk 'NR&gt;1{print $1}' | xargs -n1 -I% adb -s % install foo.apk

            【讨论】:

              【解决方案13】:

              很简单,您可以创建一个 installapk.bat 文件,该文件可以为多个连接的设备执行多个 apk 的工作,使用 notepad++ 打开 installapk.bat 并复制粘贴此代码

              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r Facebook.apk
              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r Instagram.apk
              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r Messenger.apk
              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r Outlook.apk
              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r Viber.apk
              FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r WhatsApp.apk
              

              【讨论】:

                【解决方案14】:

                这是用于在所有连接的设备上安装和运行 apk 的 bash

                使用

                nick@nickolay:/home/workspace/MyProject$ &gt; bash path/to/installAndRunApk.sh

                installAndRunApk.sh

                #!/usr/bin/env bash
                #--------find apk---------
                apkFile=$(find -name '*.apk' -print | grep -oP '(?<=.).*(.apk)')
                
                #--------find apkFilePath---------
                if test -z "apkFile"
                then
                echo "apkFile: is NULL"
                exit 0;
                fi
                
                echo "apkFile: ${apkFile}"
                apkFilePath=$(pwd)${apkFile}
                echo "apk file path: ${apkFilePath}"
                
                #--------install---------
                if test -z "$apkFilePath"
                then
                echo "apkFilePath: is NULL"
                exit 0;
                fi
                
                echo "adb install -t -r ${apkFilePath}"
                for SERIAL in $(adb devices | grep -v List | cut -f 1);
                do `adb -s ${SERIAL} install -t -r ${apkFilePath}`;
                done
                
                #--------get applicationId---------
                echo "aapt dump badging ${apkFilePath} | grep -oP '(?<=package: name=).*(?=versionCode)'"
                applicationId=$(aapt dump badging ${apkFilePath} | grep -oP '(?<=package: name=).*(?=versionCode)')
                echo "applicationId: is ${applicationId}"
                
                #--------launch---------
                if test -z "$applicationId"
                then
                echo "applicationId: is NULL"
                exit 0;
                fi
                
                echo "____________________START_APPLICATION_ID________________________"
                echo "applicationId: ${applicationId}"
                echo "____________________END_APPLICATION_ID__________________________"
                echo "____________________START_LAUNCHER______________________________"
                for SERIAL in $(adb devices | grep -v List | cut -f 1);
                do `adb -s ${SERIAL} shell monkey -p ${applicationId} -c android.intent.category.LAUNCHER 1`;
                done
                echo "____________________END_LAUNCHER________________________________"
                

                【讨论】:

                  【解决方案15】:

                  我从@WorkingMatt 添加到the answer

                  我更新了他的答案以另外做以下事情

                  1. 尝试使用开放端口 5555 连接到本地网络上的所有设备。警告:这可能存在安全风险。请注意连接到任意端口,除非您知道它是安全的。我没有接受过网络安全方面的培训,因此请谨慎采纳我的建议。
                  2. 如果安装了以前版本的软件包,请卸载(在我的情况下,我正在卸载以删除以前的应用程序数据)
                  #!/bin/bash
                  echo "Installatron2"
                  
                  # Connect to all devices on the local network (in our case 192.168.0.0)
                  # This section requires nmap (You may need sudo apt install nmap)
                  echo "Scanning the network for connected debuggable devices"
                  ADDRESSES=$(nmap --open -p 5555 192.168.0/24 -oG - | grep "/open" | awk '{ print $2 }')
                  for ADDRESS in $ADDRESSES;
                  do
                    adb connect $ADDRESS
                  done
                  
                  # Print devices connected to
                  echo "Connected to the following devices"
                  echo "$(adb devices)"
                  
                  # Iterate through all apks in current directory
                  for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
                  do
                    for APKLIST in $(ls *.apk);
                    do
                    #Get the package name from the apk file (Needs sudo apt install aapt)
                    package=$(aapt dump badging "$APKLIST" | awk '/package/{gsub("name=|'"'"'","");  print $2}')
                  
                    # Optionally uninstalls the pre-existing version of this package (In case you do not want to retain data)
                    echo "Uninstalling $package on $SERIAL"
                    adb uninstall $package
                  
                    # Now install with replacement to the same device
                    echo "Installatroning $APKLIST on $SERIAL"
                    adb -s $SERIAL install -r $APKLIST
                    done
                  done
                  
                  echo "Installatron2 has left the building"
                  

                  【讨论】:

                    【解决方案16】:

                    使用 Android Debug Bridge 1.0.29 版,试试这个bash script

                    APK=$1
                    
                    if [ ! -f `which adb` ]; then
                        echo 'You need to install the Android SDK before running this script.';
                        exit;
                    fi
                    
                    if [ ! $APK ]; then
                        echo 'Please provide an .apk file to install.'
                    else
                        for d in `adb devices | ack -o '^\S+\t'`; do
                            adb -s $d install $APK;
                        done
                    fi
                    

                    不确定它是否适用于早期版本。

                    【讨论】:

                      【解决方案17】:

                      关键是在单独的进程 (&) 中启动 adb

                      我想出了以下脚本来同时在我所有连接的设备上启动安装,最后在每个设备上启动已安装的应用程序:

                      #!/bin/sh
                      
                      function install_job { 
                      
                          adb -s ${x[0]} install -r PATH_TO_YOUR_APK
                          adb -s ${x[0]} shell am start -n "com.example.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
                      
                      }
                      
                      
                      #iterate over devices IP-addresses or serial numbers and start a job 
                      
                      while read LINE
                      do
                          eval x=($LINE)
                          install_job ${x[0]} > /dev/null 2>&1 &
                      done <<< "`adb devices |  cut -sf 1`"
                      
                      echo "WATING FOR INSTALLATION PROCESSES TO COMPLETE"
                      wait
                      
                      echo "DONE INSTALLING"
                      

                      注意 1: STDOUT 和 STDERR 被抑制。您不会看到任何“adb install”操作结果。如果你真的需要的话,我想这可能会得到改善

                      注意 2:您还可以通过提供 args 而不是硬编码的路径和活动名称来改进脚本。

                      这样你:

                      1. 不必在每台设备上手动执行安装
                      2. 不必等待一次安装完成即可执行另一次安装(并行启动 adb 任务)

                      【讨论】:

                        【解决方案18】:

                        源自这里:Make The Previous Post A Mass APK Installer That Does Not Uses ADB Install-Multi Syntax


                        @echo 关闭 :环形 ::---------------------------- 有论据? 如果 ["%~1"]==[""] ( 回声完成。 转到结束 ) ::---------------------------- 参数存在吗? 如果不存在 %~s1 ( 文件系统中不存在回显错误“%~1”。 ) 别的 ( echo "%~1" 存在 如果存在 %~s1\NUL ( echo "%~1" 是一个目录 ) 别的 ( echo "%~1" 是一个文件! - 安装时间: 调用 adb install %~s1 ) ) ::---------------------------- 转移 转到循环 :结尾 暂停 ::: ############################################## ########################### ::: ## ## ::: ## 0. 运行:adb devices - 启动守护进程并列出您的设备 ## ::: ## ## ::: ## 1. 将任意数量的文件 (APK) 拖放到此批处理文件上,## ::: ## ## ::: ## - 它将一一安装。 ## ::: ## - 它只是检查文件是否存在。 ## ::: ## - 它不检查它是否是一个有效的 APK 包 ## ::: ## - 它不检查包是否已安装 ## ::: ## - 如果出现错误,您可以随时按 [CTRL]+[C] ## ::: ## 停止脚本,并从下一个继续,## ::: ## 其他时间。 ## ::: ## - 文件被复制为 DOS 的 8.3 命名给你 ## ::: ## 无需担心包装文件名或重命名 ## ::: ## 它们,只需将它们拖放到这批上即可。 ## ::: ## ## ::: ## 埃拉德卡拉科 2016 年 1 月 1 日 ## ::: ## http://icompile.eladkarako.com ## ::: ############################################## ###########################

                        【讨论】:

                          【解决方案19】:

                          由于我无法评论 @Tom 的答案,因此这在 OSX 10.13 上对我有用

                          adb devices | tail -n +2 | cut -sf 1 | xargs -IX adb -s X install -r path/to/apk.apk
                          

                          (把小我换成大我)

                          【讨论】:

                            【解决方案20】:

                            我想记录安装过程中发生的事情,还需要稍微易于理解。结束了:

                            echo "Installing app on all connected devices."
                            
                            adb devices | tail -n +2 | cut -sf 1 | xargs -I % sh -c '{ \
                                echo "Installing on %"; \
                                adb -s % \
                                    install myApp.apk; \    
                            ; }'
                            

                            在 Linux 和 Mac 上测试

                            【讨论】:

                              【解决方案21】:

                              -获取存储在.apk文件夹中的所有apk

                              -在设备上安装和替换应用

                              getBuild() {
                                  for entry in .apk/*
                                  do
                                      echo "$entry"
                                  done
                                  return "$entry"
                              }
                              
                              newBuild="$(getBuild)"
                              
                              adb devices | while read line
                              do
                                if [! "$line" = ""] && ['echo $line | awk "{print $2}"' = "device"]
                                then
                                    device='echo $line | awk "{print $1}"'
                                    echo "adb -s $device install -r $newbuild"
                                    adb -s $device install -r $newbuild
                                fi
                              done
                              

                              【讨论】:

                                猜你喜欢
                                • 2016-02-29
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2017-10-13
                                相关资源
                                最近更新 更多