2

TLDR - 当 minifyEnabled 为 true 时,Android 应用程序与 Google API 存在问题。

有一个 Android 应用程序使用 Google API 来创建活动和 Google 会议。我使用非常标准的工具来处理这些 API - GoogleAuthorizationCodeFlow, com.google.api.services.calendar.Calendar, com.google.api.services.calendar.model.Event. 我无缘无故地使用“Web 服务器应用程序”身份验证方式而不是“已安装的应用程序” ,但事实上我已经完成了第一个工作。在我的调试模式下一切正常,但是当我进入发布模式时,就会出现问题。

  • GoogleClientSecrets变得无法处理console.developers.google.com给我的secrets.json。相同的文件在调试模式下工作正常,但现在GoogleClientSecrets.getDetails返回 null。有趣的事实 -GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyString显示文件中的数据,但似乎缺少配置文件的所有引号。它最终修复了(现在我直接使用 clientId/clientSecret 创建秘密,没有 json 文件),但为什么问题首先出现?
  • 修复后,flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()给我https://accounts.google.com/o/oauth2/auth而不是https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=<myClientId>&redirect_uri=<myRedirect>&response_type=code&scope=https://www.googleapis.com/auth/calendar. 大多数“相对”部分都被跳过,尽管 redirectUrl 和 clientId 被正确读取和保存 - 但在 Url 中没有它们的踪迹。通过添加-keep class com.google.api.client.googleapis.auth.oauth2.*到我的proguard-rules.pro. 这看起来更像是一种解决方法,而不是真正的解决方案,但后来情况变得更糟。
  • 修复后,当我这样做时
    Credential credential = getCredential(context);
    Calendar service = new Calendar.Builder(HTTP_TRANSPORT,
                            JSON_FACTORY,
                            credential)
                            .setApplicationName(APPLICATION_NAME)
                            .build();
    service.events().insert(calendarId, event)
                            .setConferenceDataVersion(1)
                            .setSupportsAttachments(true)
                            .execute();

有了一个完美的事件,无需缩小即可正常工作,然后我得到

c.f.b.a.b.c.b: 404 Not Found
{
   "errors" : [ {
     "domain" : "global",
     "reason" : "notFound",
     "message" : "Not Found"
   } ],
   "code" : 404,
   "message" : "Not Found"
}

这可以-keep class com.google.api.services.calendar.* { *; }在我的proguard-rules.pro

  • 修复后,插入事件的同样尝试给了我
    W/System.err: java.lang.IllegalArgumentException: key creator
            at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:382)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
            at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)

经过一些测试,我注意到以上所有内容仅在 minifyEnabled 为 true 时才会出现。使用 minifyEnabled false,一切都像魅力一样。到目前为止,我找到了 3 个解决方案

  • minifyEnabled false. 我有点喜欢我的文件在发布时缩小了
  • dontobfuscate并且dontshrinkproguard-rules.pro. 有帮助,但会降低缩小的效果。
  • keep class * { *; }proguard-rules.pro. 有帮助,但会降低缩小的效果。

我无法相信像 minifyEnabled 这样的标准选项会破坏如此大规模的GoogleAuthorization标准工具。com.google.api.client.*不过,我可以相信我会犯一些愚蠢而明显的错误。目前,我的最后一根稻草是从“Web 服务器应用程序”转向“已安装”方式,但我并没有把希望寄托在这里——如果它是问题的主要来源,为什么它会在没有缩小的情况下工作......

为什么会发生所描述的行为?我究竟做错了什么?

4

1 回答 1

0

proguard-rules.pro每当您在发布版本中发现混淆问题时,将规则例外添加到文件中并不是一种不常见的做法。

单独使用 ProGuard 是一个完整的主题,但不要认为向应用程序的混淆工具添加例外会破坏应用程序的安全性或诸如此类。一些 API 和编码模式只需要一些例外即可正常工作;例如数据类/模型,以及来自 JNI 层的所有内容总是需要去混淆。

如果您仍然不相信,这里有一篇关于该主题的快速文章。

于 2020-12-15T17:22:15.957 回答