无人值守现场部署 android 手机的远程应用程序更新和重启?

Remote app update and restart for unattended field-deployed android phones?

我们将部署数百部现成的 android 手机到偏远的现场位置进行无人值守操作。它们将是 运行 我们开发的应用程序,作为科学研究项目的一部分,用于接收、处理来自附近蓝牙传感器的数据并将数据中继到中央服务器。这些设备将可以访问互联网;我们与 phones/app.

有双向通信

我们将需要随着时间的推移更新我们的应用程序,如果不是为了修复错误,那么就是为了新功能。如果能够在没有用户交互的情况下远程强制更新并重启(或重启),那将是非常有用的——实际上是必不可少的;访问每个站点并手动完成更新在时间、精力和金钱上将非常昂贵。

哪些编程方法或第 3 方应用程序或技术可以使这成为可能?理想情况下,我们希望避免对手机进行 root,但如果这是唯一的方法,那么我们肯定会这样做。

从多年来发给 SO 和其他地方(例如,)的许多帖子来看,开箱即用、无根的 [=21] 不可能(或不可能) =] -- 这(仍然)是真的吗?我们正在寻找指向代码、产品或操作方法的指针以实现这一目标——越简单越好,但欢迎所有建议!

据我所知,(仍然)不可能在现成的 android 设备上进行完全无人值守的应用程序更新,因此我研究了 root 设备的可能性。经过一天的搜索、阅读和试验,我们得出了一种可行的方法,它为我们提供了所需的所有远程控制功能,甚至更多。所涉及的步骤和设置的粗略概述可能会帮助有类似需求的其他人:

  • root 设备(细节因设备而异,因此您必须搜索如何为您的特定设备执行此操作)
  • 配置(或重新配置,取决于生根程序的效果)设备设置(例如 wifi)以使其发挥最低限度的功能
  • 进入 Google 设置 > 安全并取消选中 "Improve harmful app detection" 和 "Scan device for security threats" 选项(否则,phone 在远程安装应用)
  • 确保开发者选项已启用;我读到该位置可能因 android 版本或设备制造商而异,但一个常见位置是设置 > Phone >(滚动到底部)内部版本号——在内部版本号项目上点击 7 次以启用开发者选项
  • 在“设置”>“开发人员选项”中启用 USB 调试(即使我们永远不会与 phone 建立 USB 连接,并且会通过 TCP 进行所有调试;此选项的行为似乎更像 "enable adb debugging" 无论是通过 USB 还是 TCP)
  • 安装 ssh 服务器或 sshd 应用程序(有很多;我现在选择 SSH Server 并配置它(为该服务器添加了 1 个服务器和 1 个用户)
  • 从计算机或其他设备上的终端 window,使用您在 SSH 服务器中设置的用于服务器的任何端口,通过 ssh 连接到 phone:
   $ ssh 192.168.1.217 -p 34567     # e.g., a local network IP address
  • 通过发出以下命令为 adb over TCP 配置设备(这样做,无需先通过 USB 连接):
   $ su
   $ setprop service.adb.tcp.port 5555
   $ stop adbd
   $ start adbd
   $ exit

   Note that the first time you issue the su command, the device
   will prompt for an on-screen tap to permit the SSH Server 
   app to run with elevated privileges -- this is a one-time 
   configuration that you must perform before you deploy to the field! 
   Note also that you specify which port adb will use -- you could 
   use something other than the default 5555.
  • 可选地,将 adb 授权密钥的文本文件放置到设备上(/data/misc/adb/adb_keys -- 需要 su)以预授权一台或多台您希望能够连接和管理远程设备的计算机设备 -- 请参阅下面的进一步讨论
  • 从 Android Studio 的终端选项卡(或从任何安装了 adb 的终端),使用 adb 连接到设备,最好使用设备的 public IP 地址(更多信息见下文):
   $ adb connect 93.184.216.34     # a public IP address
   # or, if you aren't set up yet for public access, a local address
   $ adb connect 192.168.1.217     # a local network IP address

   Note that you will get another on-screen prompt, this time
   to permit this computer to connect unless one of the
   following is true:
   a) you have previously connected to this device at this IP
      address from this computer and you check the option to
      permanently allow this connection, or
   b) you created an adb_keys file containing the key for the
      computer you are currently connecting from
   If you get the prompt, you must confirm it on-screen with
   a finger tap; if you select the option to permanently allow
   this connection, the /data/misc/adb/adb_keys file will be
   created and/or updated with the key for this connection

由于目标是配置 phone 以使其永远不需要任何屏幕上的用户交互,因此您需要确保使用包含以下内容的 adb_keys 文件将其部署到现场当您远程连接到它时,它将看到的密钥。最简单的方法是手动连接一次来自您将用于远程管理的计算机上的设备,并使用 phone 在部署时将拥有的 IP 地址,因为通过时密钥不同一个本地网络而不是整个互联网(我希望有比我更有知识的人来澄清所有这些——我只是报告我今天 seen/learned 将所有这些放在一起)。

如果您预计从多台计算机管理 phone(s),您应该提前确定所有此类计算机的密钥,并将它们放在一个文件中,在安装过程中安装到 /data/misc/adb/adb_keys.这将 "pre-authorize" 来自所有其密钥与文件中的密钥匹配的计算机的 adb 连接。

设置就到此为止。要使用此设置来实际管理应用程序更新非常简单,只需要 adb。以下是可用于管理远程设备的 adb 命令的最小列表——键入 adb --help 或在网络上搜索更多有关 adb 可以执行的许多操作的信息(请注意,大多数但不是全部命令是 'adb shell' 命令,用于 activity 管理器('adb shell am')或包管理器('adb shell pm'):

 # terminate your currently-running app
 $ adb shell am force-stop com.example.appname

 # uninstall your app completely
 $ adb shell pm uninstall com.example.appname
 # or, to keep the app's data and cache use the -k option
 $ adb shell pm uninstall -k com.example.appname

 # install your app from your local computer to the remote device
 $ adb install /local/path/to/the/app.apk

 # start your app by invoking it's main/startup activity
 $ adb shell am start -n com.example.appname.Main

我只做过一个phone;我将在接下来的几天内重复更多 phones 并修改此答案 if/as 需要。虽然每个 phone 的设置都有些复杂并且需要几分钟,但一旦配置完成,我们数百个 phone 的更新看起来就可以作为一个简单的 adb 命令脚本完全自动化.