[英]Is it possible to detect that an android app is either a beta version or production version?
我们在 Google Play 商店中使用测试版。 对于应用侧强制更新功能,我们希望检测我们的应用是来自 Google Play 商店的 Beta 阶段还是生产阶段。 这在android应用程序中可能吗?
目前无法检测应用程序是从 Play 商店的 Beta 版还是 Production Track 安装的。
假设您的应用程序将连接到您拥有的 API - 您可以做的是让 API 确定该应用程序是 Beta 应用程序还是 Prod 应用程序。 例如,在 API 上存储被视为 Prod 应用程序的应用程序版本号,当应用程序连接到 API 时,它会将它的版本号传递给 API,并且 API 返回一个响应,说明它是否是 Prod(版本匹配它存储的一个)或 Beta 版应用程序(它与它存储的一个不匹配)。
但这有 2 个限制:
如果您对这 2 个限制感到满意,那么您将只有 1 个 APK 和一种确定您的应用是 Prod 还是 Beta 的方法。
您可以使用 Google Play Developer API 做到这一点,但它看起来很痛苦。
https://developers.google.com/android-publisher/edits/overview
就像@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));
}
}
如果您的应用程序的版本名称 ( android:versionName
) 始终包含用于测试版本的字符串“beta”,您可以在运行时检索包名称,并进行检查。
使用getPackageInfo()
方法检索具有 versionName String 字段的PackageInfo
对象。
另一种方法是使用android:versionCode
。 例如,您可以决定您的 Beta 版本始终具有奇数版本代码,而生产版本始终具有偶数版本代码。 您可以使用getPackageInfo()
来检索版本代码并基于此做出决定。
在您的应用程序版本名称中使用“beta”或“staging”,您可以使用getPackageInfo()
获取它并使用 Regex 或indexOf
检查
context.packageManager.getPackageInfo(context.packageName, 0).versionName.indexOf("beta") >= 0
假设相同的 apk 通常从 Beta 升级到生产,Dizzy 的答案表明需要调用某些外部 API 是要走的路。
但是,您无需设置并访问您自己的后端 API,您只需使用 android HttpURLConnnection来检查 Google Play 商店详细信息页面以获取您自己的应用程序 ID。
如果当前用户已注册 Beta,则应用名称将显示为“ App Name (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();
}
我们在Google Play商店中使用Beta登台。 对于应用程序方面的强制更新功能,我们要检测我们的应用程序是否来自Google Play商店的Beta阶段或生产阶段。 这在Android应用程序中可能吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.