0

I have been trying to work on an application to help me upload a bunch of APKs through a CLI. I am using the Android Publisher API and I decided to write the cli in scala and make the API calls using apache httpclient. The code I have for uploads is:

 
    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
      }

The edit id and access token should be correct as it works in the rest of the application.

My code for the upload came from here

I have also tried using curl in case it was a problem with http client using a MultiPart entity. The curl I was using is:


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/[edit id]/apks?uploadType=media"

However, through all this the only think I can ever get back is a json error



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

Community
  • 1
  • 1
micoris
  • 3
  • 3

1 Answers1

0

As far as the curl goes - It was legitimately an invalid APK. This threw me off because it would upload fine on the web interface. I got a newer version of my apk out and it worked.

As for the scala, it was the fact that it was sending as a Multipart content-type with the required content-type in it. This would cause google to refuse it. The updated version of my function is:



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
  }

using a FileEntity instead of a MultipartEntityBuilder

micoris
  • 3
  • 3