技術部開発基盤グループの id:gfx と申します。
Google I/O 2014で発表されたGoogle Play Developer API (Android Publisher)を調べてみました。
Android PublisherはPlayのアプリケーション情報やAPKバイナリの操作を行うAPIで、これがあればリリースエンジニアリングの自動化(Release Engineering as Code)や、アプリの説明文や更新情報のgit管理などができるようになります。リリースエンジニアリングは属人化しがちなので、その作業をコードに落としこむという点で大きな意味を持つAPIだと言えるでしょう。AndroidアプリケーションにおけるRelease Engineering as Codeの実現に一歩近づくことができます。
本エントリでは、Android Publisher API(以下、単に「API」といいます)について簡単に紹介します。
APIでできること
- APKのアップロードやアプリの説明文、更新情報などを取得・更新ができる
- IABの設定を行える(このエントリでは未検証)
- APIリクエストの限界は 200,000 queries per day
サンプルコードについて
詳細はこのエントリでは省きますが、このエントリのコードはGradle+Groovyプロジェクトで試しました。依存ライブラリは以下のとおりです。
dependencies {
compile 'com.google.apis:google-api-services-androidpublisher:v2-rev2-1.19.0'
compile 'com.google.api-client:google-api-client:1.19.0'
compile 'com.google.api-client:google-api-client-gson:1.19.0'
}
APIを使う準備
AndroidPublisher service clientの生成
認証方法は「OAuth2」と「service account」の二種類あります。今回はservice accountで認証しましょう。以下の「Getting Started」に従って、Developer Consoleでservice accountを作ってAPIの設定をしてください。
認証の流れとしては、認証情報を設定したGoogleCredentialを生成し、それをもとにAndroidPublisherを生成します。
認証情報としては、Google API Developer Consoleで生成した Google Play Android Developer-xxxx.json
のなかの client_email と、 Google Play Android Developer-xxxx.p12
ファイルが必要です。
public static class Account {
public String private_key_id
public String private_key
public String client_email
public String client_id
public String type
}
def account = new Gson().fromJson(credentialFile(jsonName).text, Account);
assert account.client_id;
def httpTransport = GoogleNetHttpTransport.newTrustedTransport()
def jsonFactory = JacksonFactory.getDefaultInstance()
def credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(account.client_email)
.setServiceAccountScopes(AndroidPublisherScopes.all())
.setServiceAccountPrivateKeyFromP12File(credentialFile(p12Name))
.build()
def publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory,
credential)
.build()
このpublisherオブジェクトに対してリクエストを生成することで、Playのアプリケーション情報を操作します。この部分はメソッドにして分離しておくといいですね。
なお、認証情報などのクライアント生成のための情報が足りないとIllegalArgumentExceptionをただ投げるだけなので、これに悩まされたら思い切ってソースを読みましょう。
編集の準備を行う
AndroidPublisherを生成したら、APIを呼ぶために、リクエストのための準備をします。これはどのリクエストでも共通です。
def packageName = "com.example.android.app"
def edits = publisher.edits()
def editRequest = edits.insert(packageName, null)
def appEdit = editRequest.execute()
これでようやくAPIを呼ぶ準備が整いました。次に、実際にAPIを見てみましょう。
Android Publisher API
Edits.apks
APKを操作します。list()とupload()メソッドを持っています。
まずlist()で情報を取得してみます。取得できるのはversionCodeとapk binaryのSHA1値です:
Apk apk = edits.apks()
.list(packageName, appEdit.getId())
.execute()
.getApks()
.first()
println("versionCode: ${apk.getVersionCode()}, SHA1: ${apk.getBinary().getSha1()}")
次にupload()ですが、これはpackage名とapkファイルがあればできます。最後にcommitするまで実際の更新は適用されません。なお、不正なファイルをアップロードするとエラーになります:
def mimeType = "application/vnd.android.package-archive"
def apkFile = new FileContent(mimeType,
new File('./app/build/outputs/apk/app-release.apk'))
Apk apk = edits.apks(
.upload(packageName, appEdit.getId(), apkFile)
.execute()
println("uploaded: versionCode: ${apk.getVersionCode()}, sha1: ${apk.getBinary().getSha1()}")
edits.commit(packageName, appEdit.getId())
.execute()
Edits.apklistings
その他のAPIについても同様に操作できます。たとえば、Edits.apklistings
は言語(ロケール)ごとの更新情報を取得・更新できます。操作にはバージョンコードが必要なので、必要に応じて Edits.apks
から入手するとよいでしょう。
edits.apklistings()
.list(packageName, appEdit.getId(), apk.getVersionCode())
.execute()
.getListings()
.each { ApkListing listing ->
println("recent changes: ${listing.getRecentChanges()} (${listing.getLanguage()})")
}
同様に、 管理者の連絡先用の Edits.details
、公開状態を操作する Edits.tracks
、タイトルや説明文を操作する Edits.listings
などがあります。
さてここまでの前提知識があればオフィシャルのREST APIリファレンスとAndroidPublisherのjavadocを元にAPIを使えるようになると思います。
おまけ:API使用の注意点
API Usage Instructions に書いてあることのまとめです。
- productionはもちろんのこと、alpha/betaリリースであっても、必要のない限り1日1度以上リリースすべきではない。頻繁なリリースはユーザーに負担をかける。
- 外注先などの協力会社にアプリの作成や公開・配付を行わせてはいけない。それはGoogle Play Developer API Terms of Serviceに違反している
- 協力会社にアプリの開発を任せる場合は、開発用アカウントを共有してはいけない。パーミッションを制限したアカウントを作ってそれを使わせること
- 協力会社には作成したサービスアカウントを与えないことを奨励する