[英]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.