上传到 Google 发布者 API

Uploading to the Google Publisher API

我一直在尝试开发一个应用程序来帮助我通过 CLI 上传一堆 APK。我正在使用 Android Publisher API,我决定在 scala 中编写 cli,并使用 apache httpclient 进行 API 调用。我的上传代码是:

 
    def uploadApk(packageName: String, editId: String, accessToken: String, fileName: String) = {
        val packageApklListUrl = "https://www.googleapis.com/upload/androidpublisher/v2/applications/" + 
          packageName + "/edits/" + editId + "/apks?uploadType=media&access_token=" + accessToken
        val httpclient = HttpClientBuilder.create.build

        val httppost = new HttpPost(packageApklListUrl)
        val file = new File(fileName)
        val contentType = ContentType.create("application/octet-stream")

        val mpEntity = MultipartEntityBuilder.create
        mpEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
        mpEntity.addBinaryBody("apk", file, contentType, fileName)
        val builtEntity = mpEntity.build
        httppost.addHeader("Content-Type", "application/octet-stream")
        httppost.setEntity(builtEntity)

        val response = httpclient.execute(httppost)
        val resEntity = response.getEntity.getContent
        Source.fromInputStream(resEntity).getLines.mkString
      }

编辑 ID 和访问令牌应该是正确的,因为它适用于应用程序的其余部分。

我的上传代码来自here

我也尝试过使用 curl,以防使用 MultiPart 实体的 http 客户端出现问题。我使用的卷曲是:


curl --data-binary @"[apk name]" -v --header "Content-Type: application/octet-stream" --header "Authorization: Bearer [access token]" -X POST "https://www.googleapis.com/upload/androidpublisher/v2/applications/[package name]/edits/[编辑 id]/apks?uploadType=media"

然而,经过这一切,我唯一能找回的是一个 json 错误



    {
     "error": {
      "errors": [
       {
        "domain": "androidpublisher",
        "reason": "apkInvalidFile",
        "message": "Invalid APK file."
       }
      ],
      "code": 403,
      "message": "Invalid APK file."
     }
    }

就 curl 而言 - 它是一个合法的无效 APK。这让我很失望,因为它可以在网络界面上正常上传。我得到了我的 apk 的更新版本并且它有效。

至于 Scala,事实上它是作为一个包含所需内容类型的多部分内容类型发送的。这将导致 google 拒绝它。我的函数的更新版本是:

</p>

<pre><code>def uploadApk(packageName: String, editId: String, accessToken: String, fileName: String) = {
    val packageApklListUrl = "https://www.googleapis.com/upload/androidpublisher/v2/applications/" + 
      packageName + "/edits/" + editId + "/apks?uploadType=media"
    val httpclient = HttpClientBuilder.create.build

    val httppost = new HttpPost(packageApklListUrl)
    val file = new File(fileName)
    val contentType = ContentType.create("application/octet-stream")
    val fileEntity = new FileEntity(file,contentType)

    httppost.addHeader("Content-Type", "application/octet-stream")
    val authHeader = new BasicHeader("Authorization","Bearer " + accessToken)
    httppost.addHeader(authHeader)
    httppost.setEntity(fileEntity)

    val response = httpclient.execute(httppost)
    val resEntity = response.getEntity.getContent
    Source.fromInputStream(resEntity).getLines.mkString
  }

使用 FileEntity 而不是 MultipartEntityBuilder