10

我已经将谷歌的 APK 扩展文件下载库集成到我的项目中,它或多或少都可以正常工作(除了一些小问题,其他人已经在 SO 上报告了这些问题)。

但是,我很难测试它。当我第一次测试它时,我将我签名的 APK + 主扩展文件版本 1 上传到了 Google Play,它运行良好。

但是,当我升级我的应用程序以及主扩展文件版本 2 时,应用程序无法再下载文件 - 库立即返回 NO_DOWNLOAD_REQUIRED,但文件不存在!我开始调试 LVL 检查通过,但可下载文件表为空!当我试图调试细节时......它突然又开始工作了!

我认为这是一种临时故障并继续我的工作,只是在再次更新我的 APK 和扩展文件后再次遇到相同的问题。应用程序通过了 LVL 检查,但库再次假定没有要下载的文件。

这是谷歌图书馆的一个已知问题吗?或者我可能需要等待一段时间,直到文件在 Google 的云上可用?

编辑:它刚刚开始工作正常。文件似乎需要一些时间才能以某种方式在 Google 方面传播。该库的一件坏事是,一旦它验证了许可证,它就再也不会检查下载列表,所以我不得不重新安装该应用程序。奇怪......为什么它这么复杂?

4

4 回答 4

17

有点线程死灵,但由于我在下载 OBB 时遇到了很多麻烦,所以我想把所有问题都放在一个地方。谷歌如何——或者说为什么——设法使从 t'internet 下载文件变得如此复杂,这超出了我的理解。

将库添加到 Android Studio

错误信息部(https://developer.android.com/google/play/expansion-files.html)自豪地带给您的官方说明是完全错误的。

在导入库之前,转到sdk \extras\google\market_apk_expansion\downloader_library 并编辑 project.properties 以完全删除“android.library.0”行。您可能还需要更新同一文件中的 android 目标版本行以匹配您现有项目的目标版本。

按照上面链接页面上的安装说明,“准备使用下载器库”第 2 步应该是“文件 > 新建 > 导入模块”,而不是“文件 > 新建 > 新模块”。

导入两个模块后,转到“文件>项目结构”并添加依赖项:

  • 您的应用应该在许可库和下载器库上都具有“模块依赖关系”
  • 下载器库应该在许可库上有一个“模块依赖”

“您必须将 BASE64_PUBLIC_KEY 值更新为属于您的发布者帐户的公钥”的步骤。也是错误的。您需要此特定应用程序的公钥,而不是您的帐户,它在您选择应用程序后的“服务和 API”下的在线开发者控制台中。

许可证验证库和下载器库都依赖于现已删除的包“org.apache.http”

将“decodeExtras”方法的两个实例(一个在 APKExpansionPolicy.java 中,一个在 ServerManagedPolicy.java 中)替换为:

private Map<String, String> decodeExtras(String extras) {
    Map<String, String> results = new HashMap<String, String>();

    UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
    sanitizer.setAllowUnregisteredParamaters(true);
    sanitizer.setUnregisteredParameterValueSanitizer(new UrlQuerySanitizer.IllegalCharacterValueSanitizer(
            UrlQuerySanitizer.IllegalCharacterValueSanitizer.URL_LEGAL));
    sanitizer.parseQuery(extras);

    for (UrlQuerySanitizer.ParameterValuePair item : sanitizer.getParameterList()) {
        String name = item.mParameter;
        int i = 0;
        while (results.containsKey(name)) {
            name = item.mParameter + ++i;
        }
        results.put(name, item.mValue);
    }

    return results;
}

运行时崩溃,说“服务意图必须是明确的”

请参阅https://stackoverflow.com/questions/24480069上的答案。

W/LicenseValidator:联系许可服务器时出错

许可证验证库在模拟器上不起作用,这是它抛出的错误。如果您使用的是真实设备,则可能只是真正的超时。

调试版本未通过签名检查(签名验证失败),因此被拒绝访问。

调用许可证验证服务的二进制文件必须是正确签名的发布版本。如果您运行的调试副本并非如此,那么许可证检查将失败。

  • 转到您的在线开发者控制台、设置、帐户详细信息
  • 将“许可测试响应”更改为“许可”(或您正在测试的任何内容)
  • 在“具有测试访问权限的 Gmail 帐户”下输入您的电子邮件地址。

下载器返回“STATE_COMPLETED”,但下载未完成。

这是先前更改的副作用。您已获得许可,但仍未提供 APK 扩展文件,因为您并未真正获得许可。此步骤允许您在分发后实际测试下载,而不是手动将文件放置到您的测试设备上。

  • 为应用程序创建促销代码。
  • 在您的设备上为全新的 GMail 帐户创建一个新用户。
  • 以新用户身份登录您的设备,兑换促销代码。您现在是真正的应用程序所有者。
  • 在“具有测试访问权限的 Gmail 帐户”下添加新的 gmail 帐户,如上一节所述。

您不能使用开发者的帐户执行此操作,因为购买或兑换将失败,这意味着您永远无法拥有自己产品的副本,这意味着 OBB 下载将永远无法正常工作。

现在您有了第二个帐户,该帐户具有应用程序的正版 Play 商店副本,并且已注册为具有“假”许可状态的测试帐户,您可以运行代码的调试副本,获取 LICENSED 状态,拥有下载工作如您所愿。

W / LVLDL:中止下载whavever .obb的请求:写入目标文件时:java.io.FileNotFoundException:

从 Android v23 开始,有必要明确请求写入“外部存储”的权限,无论它是否是 SD 卡,并且除了在清单中列出权限之外。请参阅https://developer.android.com/guide/topics/permissions/requesting.html

“找不到文件”是指下载器库要放入OBB文件的外部存储上的目录,它一直无法创建。如果无法创建文件,则会引发异常,但如果无法创建目录,则会静默失败。请参阅processResponseHeaders()DownloadThread.java 。

W/LVLDL:中止下载主请求。不管.obb:http 错误 410

您的应用的版本号必须与 Google 知道的当前 APK 中的版本号匹配,否则您的下载请求将被拒绝并出现错误 410。

如果发现许可证一次有效,库将不会重新检查许可证。

如果您正在测试,您可能需要重做几次。许可证验证库在发现它被许可后缓存它的状态。您可以在不完全卸载您的应用程序的情况下清除它:

DownloadsDB db = DownloadsDB.getDB(my_app_context);
db.updateMetadata(0, 0);

它还将下载的 OBB 保留在适当的位置,可以使用以下命令找到并清除它:

final String dlName = Helpers.getExpansionAPKFileName(my_app_context, true, expansionVersion);
final String dlFullPath = Helpers.generateSaveFileName(my_app_context, dlName);
File dlFile = new File(dlFullPath);
if (dlFile.exists())
{
    dlFile.delete();
}

现在,如果你不介意的话,我要去一次精神上的静修会一个月左右。

于 2016-12-30T17:06:32.783 回答
7

除了作者描述的传播时间之外,APK + 扩展工作流程还有其他不直观且未记录的问题:

  1. 增加 APK versionCode 但继续使用相同的(旧)扩展文件。似乎如果您不将新的 APK 上传到开发者控制台,则无法从更新的应用程序(直接使用 adb 安装)下载。错误消息也没有帮助:“下载失败,因为找不到资源”。在我看来,谷歌似乎在说“好的,我知道这个扩展文件版本,但我不知道这个应用程序版本”。我在当前文档中没有找到任何关于此要求的参考。

  2. 上传到开发者控制台的新 APK 似乎从旧 APK 中“捕获”了扩展文件关联。示例:如果您删除新的 APK(但保留旧的,与扩展文件具有相同的版本),扩展文件似乎也消失了。也许他们认为工作流程是“我们必须将扩展与新 APK 关联起来,这样开发者就可以毫无问题地随意擦除旧 APK”。这仍然是另一个似乎没有在任何地方描述的问题。

这些是初步说明。我提交了一份支持请求,可能会确认这些发现,所以当(如果?)他们回复时,我会在此处发布更新......

于 2013-03-10T17:56:19.153 回答
0

获取扩展文件有两种标准方法。(您可以将其视为假设)。

  1. 假设您的应用程序开始时没有扩展文件。
  2. 检查文件是否存在obvious location

这样,您的应用程序将像往常一样运行。这种方法最好的部分是您可以选择提出下载文件的请求。

这些是来自开发者网站的注释。

Note: The URL that Google Play provides for your expansion files is unique for every download and each one expires shortly after it is given to your application.

Note: Whether your application is free or not, Google Play returns the expansion file URLs only if the user acquired your application from Google Play.

这里是如何使用
这里是如何提出下载请求

希望这将帮助您获得结果。

于 2012-09-25T07:05:23.717 回答
0

如果您使用示例应用程序中的完整代码,您是否更改了以下代码中的版本代码:-

private static final XAPKFile[] xAPKS = {
        new XAPKFile(
                true, // true signifies a main file
                <Version code here>, // the version of the APK that the file was uploaded
                   // against
                49597391L // the length of the file in bytes
        ),

};
于 2013-11-15T14:58:46.007 回答