以编程方式在Android设备上注册Google账号

5

我已经寻找了一段时间(几天而不是几分钟)来解决这个问题,但它非常有效地避开了我。

请注意,这不是关于启动注册过程的问题。这必须自动发生,没有任何用户交互。

我想将Google账户添加到我的定制设备上(有数千个)。该账户主要用于在设备上激活Google Play商店,以便当新版本可用时应用程序可以更新。

我的现有代码(我尝试的最短片段):

AccountManager mgr = AccountManager.get(this);
Account acc = new Account("email@gmail.com", "com.google");
mgr.addAccountExplicitly(acc, "password", new Bundle()));

自然产生

java.lang.SecurityException: caller uid 10047 is different than the authenticator's uid

那么我该如何实现这个目标呢?我的设备已经获取了root权限,如果这是唯一的方法,那么这不是障碍。


据我所知,您无法为另一个应用程序生成一个帐户验证器。如果您拥有固件和签名密钥,则可以将您的用户ID与系统用户ID共享。在这种情况下,您可能能够规避它。(作为非正式答案,因为我对此信息并不100%确定) - Knossos
好的,钛备份可以做到,所以肯定有办法实现。 - velis
2
由于这是您的自定义设备,并且您声称在其上拥有“Google Play商店”,因此您必须从Google获得了许可。您应该向Google询问他们在这些情况下预先建立Google帐户的政策,不仅要确定最佳方法,还要确定是否首先获得授权。 - CommonsWare
设备制造商拒绝了我们的请求,我没有关于拒绝的实际原因的信息。我的猜测是政治原因,但我不能确定。 - velis
我是否遇到了违反Google服务条款的事情?我也应该拒绝我的雇主吗? - velis
2个回答

0

警告:此解决方案效果不佳。请查看评论以获取说明。

事实证明,这并不是一件容易解决的事情。我最终注册了一个设备,然后从中提取了用户文件。用户文件的位置为:/data/system/users/0/accounts.db(如果设备上有多个用户配置文件,则最后一个目录可能根据所涉及的配置文件而异)。

我将此文件存储到我的应用程序资产中(经过gzip压缩,确保扩展名不是something.gz,因为在打包过程中会丢失-没有研究为什么)。

首先,我检查我的用户是否已存在:

AccountManager mgr = AccountManager.get(this);
for (Account acc: mgr.getAccountsByType("com.google")) {
  if (acc.name.equalsIgnoreCase("email@gmail.com"))
    return;
}

如果它是这样的话,我就跳过这一步。否则,我会解压缩用户文件并覆盖现有文件(使用su)。然后我还会重新启动以确保更改被注册。

你有没有找到更好的方法来做这件事?这里假设你已经手动注册了该用户帐户一次,以便accounts.db填充了电子邮件和密码哈希值。是否有一种方法可以跳过第一步,仅知道原始密码而不知道其哈希形式的情况下进行操作?此外,我不确定即使是完全相同型号的设备,密码的哈希形式是否会在不同设备之间相同。 - Thanasis Petsas
@ThanasisPetsas: 实际上并不是这样。事实证明,谷歌已经采取了某些策略进行检测。一旦使用同一帐户的50台设备处于联网状态,Play商店就会停止运作。因此,我们被迫实现自己的包更新机制。 - velis
好的,知道了!那么,49个设备使用一个账户没有问题吗?密码的哈希形式对于所有设备都是相同的吗? - Thanasis Petsas
从技术上讲,它们都使用了相同的帐户数据库。我不知道Play Store在哪个设备上停止工作,但我猜测它在50个设备之前就已经停止了。我们有成千上万的设备,所以我们甚至没有尝试找到解决这个问题的方法。设置文件本身只是一个SQLite数据库,因此从技术上讲,您可以随意使用它,只是很难猜出所有算法。 - velis

0

使用addAccountExplicitly()无法添加/创建Google帐户。您只能为自己的服务添加帐户,即使您的设备已经root,也会被Google Web服务器拒绝。有关更多详细信息,请查看link


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