We use beta staging in google play store. For app side force update functionality we want to detect if our app is either coming from the beta stage or the production stage of the google play store. Is this possible in android apps?
It's currently not possible to detect if the app was installed from either the Beta or Production Track on the Play Store.
Assuming your app will be connecting to an API that you own - What you can do is let the API determine if the App is a Beta or Prod App. For example store the app version number(s) that are considered a Prod app on the API, when the app connects to the API it passes it's version number to the API and the API returns a response with whether it is Prod (The version matches one it has stored) or Beta App (it's does not match one it has stored).
There are 2 Limitations to this though:
- You will need to update the mobile app version number(s) on your API when the app is ready to go to production.
- Mobile apps will be determined by their version number not what Track they are on in Play Store.
If you're happy with these 2 limitations then you will only have 1 APK and a means to determine if your app is Prod or Beta.
You can do this with the Google Play Developer API but it looks pretty painful.
https://developers.google.com/android-publisher/edits/overview
Like @Jayen said, it is possible using the Google AndroidPublisher Service API. See the following sample code (in 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));
}
}
If your application's version name (android:versionName
) always contains the string "beta" for beta releases, you can retrieve the package name at runtime, and check that.
Use the
getPackageInfo()
method to retrieve a PackageInfo
object which has a versionName String field.
Another approach would be to use the android:versionCode
. For example, you could decide that your beta releases always have an odd version code, and production releases always have an even one. You could use getPackageInfo()
to retrieve the version code and make your determination based on that.
With "beta" or "staging" in your app version name, you can get it with getPackageInfo()
and check with a Regex or indexOf
context.packageManager.getPackageInfo(context.packageName, 0).versionName.indexOf("beta") >= 0
Assuming the same apk is typically promoted from Beta to Production, the answer by Dizzy suggesting that a call out to some external API is required is the way to go.
However, rather than setting up and hitting your own back-end API, you can just use an android HttpURLConnnection to check the Google Play store details page for your own app id.
If the current user is enrolled in Beta, the app name is presented as "App Name (Beta)".
A little further down the page it will also say "You're a beta tester for this app. Awesome!"
The page contains a single button labelled either "Install", "Update" or "Installed", from which you can determine whether or not the user has the latest version
On the same page your app can also look up the last production Updated date, and latest production version name.
Sample Java code for how you might implement this below:
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();
}
© 2022 - 2024 — McMap. All rights reserved.