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
并且dontshrink
在proguard-rules.pro
. 有帮助,但会降低缩小的效果。keep class * { *; }
在proguard-rules.pro
. 有帮助,但会降低缩小的效果。
我无法相信像 minifyEnabled 这样的标准选项会破坏如此大规模的GoogleAuthorization
标准工具。com.google.api.client.*
不过,我可以相信我会犯一些愚蠢而明显的错误。目前,我的最后一根稻草是从“Web 服务器应用程序”转向“已安装”方式,但我并没有把希望寄托在这里——如果它是问题的主要来源,为什么它会在没有缩小的情况下工作......
为什么会发生所描述的行为?我究竟做错了什么?