我们在 Google Play 商店中使用测试版。对于应用程序侧强制更新功能,我们希望检测我们的应用程序是来自 Google Play 商店的测试阶段还是生产阶段。这在 Android 应用程序中可能吗?
目前无法检测该应用程序是从 Play 商店的 Beta 版还是 Production Track 安装的。
假设您的应用程序将连接到您拥有的 API - 您可以做的是让 API 确定该应用程序是 Beta 应用程序还是 Prod 应用程序。例如,在 API 上存储被视为 Prod 应用程序的应用程序版本号,当应用程序连接到 API 时,它将其版本号传递给 API,并且 API 返回一个响应,说明它是否是 Prod(版本匹配)已存储的应用程序)或 Beta 应用程序(与已存储的应用程序不匹配)。
但这有两个限制:
如果您对这 2 个限制感到满意,那么您将只有 1 个 APK 和一种确定您的应用是 Prod 还是 Beta 的方法。
就像 @Jayen 所说,可以使用 Google AndroidPublisher Service API。请参阅以下示例代码(Java 语言):
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.SecurityUtils;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import com.google.api.services.androidpublisher.model.AppEdit;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Objects;
import java.util.Set;
public class AndroidPublisherService {
private final AndroidPublisher service;
/**
* Constructs a GooglePlayService instance with the specified credentials.
*
* @param accountId
* @param keyStoreInputStream
* @param keyStorePassword
* @param keyAlias
* @param keyPassword
* @throws GeneralSecurityException
* @throws IOException
*/
public AndroidPublisherService(
String accountId,
InputStream keyStoreInputStream,
String keyStorePassword,
String keyAlias,
String keyPassword
) throws GeneralSecurityException, IOException {
// Specify info for your application 'CompanyName-ApplicationName/ApplicationVersion'
// This is not part of the authentication, but sample code from Google specifies this.
final String applicationName = "SomeCompany-SomeApplication/1.0";
final JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
final HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
final var keyInputStream = Objects.requireNonNull(keyStoreInputStream);
final var key = Objects.requireNonNull(SecurityUtils.loadPrivateKeyFromKeyStore(
SecurityUtils.getPkcs12KeyStore(),
keyInputStream,
keyStorePassword,
keyAlias,
keyPassword
));
var credentials = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(accountId)
.setServiceAccountScopes(Set.of(AndroidPublisherScopes.ANDROIDPUBLISHER))
.setServiceAccountPrivateKey(key)
.build();
this.service = new AndroidPublisher.Builder(
httpTransport, jsonFactory, credentials
).setApplicationName(applicationName).build();
}
/**
* Checks whether the application with the specified packageName/versionCode is in the production lane or not.
*
* @param packageName The package name of the application
* @param versionCode The version code of the application
* @return true if the application is a test version (not in production lane), false otherwise.
* @throws IOException
*/
public boolean isTestVersion(String packageName, long versionCode) throws IOException {
// Create the API service.
final AndroidPublisher.Edits edits = service.edits();
// Create a new edit to make changes.
AndroidPublisher.Edits.Insert editRequest = edits
.insert(packageName, null);
AppEdit appEdit = editRequest.execute();
// Get a list of apks.
var tracksListResponse = edits
.tracks()
.list(packageName, appEdit.getId()).execute();
return tracksListResponse.getTracks().stream()
.filter(it -> !it.getTrack().equalsIgnoreCase("production"))
.flatMap(it -> it.getReleases().stream())
.anyMatch(it -> it.getVersionCodes().contains(versionCode));
}
}
您可以使用 Google Play Developer API 来完成此操作,但看起来非常痛苦。
https://developers.google.com/android-publisher/edits/overview
android:versionName
) 始终包含 beta 版本的字符串“beta”,您可以在运行时检索包名称并进行检查。
getPackageInfo()
方法检索具有 versionName String 字段的 PackageInfo
对象。
另一种方法是使用
android:versionCode
。例如,您可以决定测试版本始终具有奇数版本代码,而生产版本始终具有偶数版本代码。您可以使用 getPackageInfo()
检索版本代码并据此做出决定。
应用程序版本名称中包含“beta”或“staging”,您可以使用
getPackageInfo()
获取它并使用正则表达式或 indexOf
进行检查
context.packageManager.getPackageInfo(context.packageName, 0).versionName.indexOf("beta") >= 0
假设相同的 apk 通常从 Beta 升级到 Production,Dizzy 的回答建议需要调用某些外部 API。
但是,您可以使用 android HttpURLConnnection 来检查 Google Play 商店详细信息页面以获取您自己的应用程序 ID,而不是设置并点击您自己的后端 API。
如果当前用户注册了 Beta,应用程序名称将显示为“应用程序名称(Beta)”。
页面再往下一点,它还会显示“您是此应用程序的 Beta 测试人员。太棒了!”
该页面包含一个标有“安装”、“更新”或“已安装”的按钮,您可以从中确定用户是否拥有最新版本
在同一页面上,您的应用程序还可以查找上次生产更新日期和最新生产版本名称。
下面是有关如何实现此功能的示例 Java 代码:
boolean isBeta = false;
URL url = new URL("https://play.google.com/sore/apps/details?id=com.example.app");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
Scanner scanner = new Scanner(in);
isBeta = (scanner.findWithinHorizon("\\s\\(Beta\\)", 650000) != null);
} finally {
urlConnection.disconnect();
}