以编程方式将“测试版”apk 升级为“生产”
Posted
技术标签:
【中文标题】以编程方式将“测试版”apk 升级为“生产”【英文标题】:Promoting 'beta' apk to 'production' programmatically 【发布时间】:2018-09-10 07:40:12 【问题描述】:我正在使用 Google Play Developer API v2以编程方式将我的测试版 apks 上传到 Playstore,它运行良好 :-)
现在,我想以编程方式将 beta apk 从“beta”轨道“提升”到“production”轨道(因此我不再需要在 Google Dev Console 上手动执行此操作. 我的应用套件由 10 个应用组成.. 这需要时间)
我正在尝试,但我不清楚如果不重新上传 apk,我应该怎么做。 我想要实现的是修改之前上传的 apk,只需将 Track 从“beta”更改为“production”。
下面是我写的代码:
查找所有曲目 找到“测试版”轨道 找到对应的apk 将 apk 轨道从“beta”更改(但不是正确的方法)到“production” 提交更改 -> 以下异常:SEVERE: Exception was thrown while updating listing com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden "code" : 403, "errors" : [ "domain" : "androidpublisher", "message" : "Testing-track (alpha/beta) APK with version code 1522428584 appears in another track", "reason" : "testingTrackApkInMultipleTracks" ], "message" : "Testing-track (alpha/beta) APK with version code 1522428584 appears in another track" at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) at com.elementique.tools.publish.elementique.ElementiquePromoteBetaApkToProduction.main(ElementiquePromoteBetaApkToProduction.java:74)
根据例外情况,我编写的代码不会修改现有的 apk,而是尝试创建一个与现有 beta 轨道具有相同 id 的新 apk。 我明白这是错误的,但不知道如何正确地做到这一点..
这是代码:有人可以解释我如何正确地做吗?
谢谢。
package com.elementique.tools.publish.elementique;
import com.elementique.tools.publish.AndroidPublisherHelper;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisher.Edits;
import com.google.api.services.androidpublisher.model.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
public class ElementiquePromoteBetaApkToProduction
private static final Log log = LogFactory.getLog(ElementiquePromoteBetaApkToProduction.class);
private static final String PACKAGE_NAME = "com.elementique.home";
public static final String TRACK_BETA = "beta";
public static final String TRACK_PRODUCTION = "production";
public static void main(String[] args)
try
// Create the API androidPublisher service.
final AndroidPublisher androidPublisher = AndroidPublisherHelper.init("Elementique", null);
final Edits edits = androidPublisher.edits();
// Create a new edit to make changes.
Edits.Insert insertEdit = edits.insert(PACKAGE_NAME, null);
AppEdit insertAppEdit = insertEdit.execute();
// search for 'beta' apk(s) in the 'beta' track..
// first list all tracks..
TracksListResponse trackListResponse = edits.tracks().list(PACKAGE_NAME, insertAppEdit.getId()).execute();
for (Track track : trackListResponse.getTracks())
// filter for beta track..
if (TRACK_BETA.equals(track.getTrack()))
// beta track found...
System.out.println("Beta Track found!\n" + track.toPrettyString());
// in my case, I am supposed to have exactly one 'beta' apk
List<Integer> betaApkVersionCodes = track.getVersionCodes();
if (betaApkVersionCodes.size() == 1)
// one apk: OK, that's the 'beta' apk I want to promote to 'production'
Integer betaApkVersionCode = betaApkVersionCodes.get(0);
// now search for the given apk among all existing apks (is it the good way to proceed..??)
ApksListResponse apksListResponse = edits.apks().list(PACKAGE_NAME, insertAppEdit.getId()).execute();
for (Apk apk : apksListResponse.getApks())
// is it our 'beta' apk?
if (betaApkVersionCode.equals(apk.getVersionCode()))
System.out.println("Beta apk found!\n" + apk.toPrettyString());
// OK, we got it.
// now trying to change the 'track' of this apk from 'beta' to 'production'
// and this is not the way to proceed...
List<Integer> apkVersionCodes = new ArrayList<>();
apkVersionCodes.add(apk.getVersionCode());
Edits.Tracks.Update updateTrackRequest =
edits.tracks().update(
PACKAGE_NAME,
insertAppEdit.getId(),
TRACK_PRODUCTION,
new Track().setVersionCodes(apkVersionCodes));
Track updatedTrack = updateTrackRequest.execute();
log.info(String.format("Track %s has been updated.", updatedTrack.getTrack()));
// Commit changes for edit.
Edits.Commit commitRequest = edits.commit(PACKAGE_NAME, insertAppEdit.getId());
AppEdit commitAppEdit = commitRequest.execute();
log.info(PACKAGE_NAME + " beta apk moved to production (" + commitAppEdit.getId());
System.exit(0);
catch (IOException | GeneralSecurityException ex)
log.error("Exception was thrown while updating listing", ex);
(不要告诉我括号地狱的事情,我只是为了做一个简单的测试而写了这样的代码;-)
注意事项:
原始 Google Smaple 项目是 here 和 'Google Play Developer API V2' maven artifact here 一些附加信息:javadoc here 和一些附加(非 java)信息 here【问题讨论】:
我想我找到了right documentation page,它通过调用Edits.tracks: update 两次来解释如何做到这一点。我将尝试根据此实验的结果更新我的问题/发布答案。 【参考方案1】:搞定了:-) 可以在这里找到解释:https://developers.google.com/android-publisher/tracks
以编程方式将“测试版”轨道提升为“生产”轨道的示例代码:
package com.elementique.tools.publish.elementique;
import com.elementique.tools.publish.AndroidPublisherHelper;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisher.Edits;
import com.google.api.services.androidpublisher.model.AppEdit;
import com.google.api.services.androidpublisher.model.Track;
import com.google.api.services.androidpublisher.model.TracksListResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
// Google Play Developer API v2 javadoc:
// https://developers.google.com/resources/api-libraries/documentation/androidpublisher/v2/java/latest/index.html?com/google/api/services/androidpublisher/AndroidPublisher.html
// + this: https://developers.google.com/android-publisher/api-ref/
public class ElementiquePromoteBetaApkToProduction
private static final Log log = LogFactory.getLog(ElementiquePromoteBetaApkToProduction.class);
private static final String PACKAGE_NAME = "com.elementique.home";
public static final String TRACK_BETA = "beta";
public static final String TRACK_PRODUCTION = "production";
public static void main(String[] args)
try
final AndroidPublisher androidPublisher = AndroidPublisherHelper.init("Elementique", null);
final Edits edits = androidPublisher.edits();
// Create a new edit to make changes.
Edits.Insert insertEdit = edits.insert(PACKAGE_NAME, null);
AppEdit insertAppEdit = insertEdit.execute();
// Promote beta to production: doc here:
// https://developers.google.com/android-publisher/tracks
TracksListResponse trackListResponse = edits.tracks().list(PACKAGE_NAME, insertAppEdit.getId()).execute();
Track betaTrack = null;
Track productionTrack = null;
// list current tracks.
// searching for exactly one beta and one production...
for (Track track : trackListResponse.getTracks())
if (TRACK_BETA.equals(track.getTrack()))
if (track.getVersionCodes().size() == 1)
// one version: OK, that's the 'beta' apk I want to promote to 'production'
betaTrack = track;
log.info(PACKAGE_NAME + ": found 'beta' apk " + betaTrack.getVersionCodes().get(0));
else if (TRACK_PRODUCTION.equals(track.getTrack()))
if (track.getVersionCodes().size() == 1)
// one version: OK, that's the 'production' apk I want to replace with the former 'beta' apk
productionTrack = track;
log.info(PACKAGE_NAME + ": found 'production' apk" + productionTrack.getVersionCodes().get(0));
if (betaTrack != null && productionTrack != null)
// first set production track to version of current beta
Edits.Tracks.Update updateProductionTrackRequest =
edits.tracks().update(
PACKAGE_NAME,
insertAppEdit.getId(),
TRACK_PRODUCTION,
new Track().setVersionCodes(betaTrack.getVersionCodes()));
updateProductionTrackRequest.execute();
// .. then clear beta version(no more beta apk)
Edits.Tracks.Update updateBetaTrackRequest =
edits.tracks().update(
PACKAGE_NAME,
insertAppEdit.getId(),
TRACK_BETA,
new Track().setVersionCodes(new ArrayList<>()));
updateBetaTrackRequest.execute();
// Commit changes for edit
Edits.Commit commitRequest = edits.commit(PACKAGE_NAME, insertAppEdit.getId());
AppEdit commitAppEdit = commitRequest.execute();
log.info(PACKAGE_NAME + ":" +
" 'production' apk " + productionTrack.getVersionCodes().get(0) + "" +
" replaced by 'beta' apk " + betaTrack.getVersionCodes().get(0));
catch (IOException | GeneralSecurityException ex)
log.error(PACKAGE_NAME + " : Error while trying to promote 'beta' apk to 'production'", ex);
【讨论】:
以上是关于以编程方式将“测试版”apk 升级为“生产”的主要内容,如果未能解决你的问题,请参考以下文章
如果 beta apk 比官方 apk 旧,beta 用户将获得哪个 apk?
如何以编程方式检查应用程序是不是在 TestFlight beta 模式下运行? [复制]