This blog will create an In-App Update method for Android apps. When users open your app, they can get an update popup system on their app home screen. So, we can follow below step-wise method.
Step:01
We implement In-App Update Dependency in the build.gradle(Module :app) file.
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
// In App Update Method Dependency
implementation 'com.google.android.play:app-update:2.1.0'
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
}
Step:02
Go to activity.home.xml layout and create layout ID which will help to show a popup in your home HomeActivity.java file.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
Step:03
We have to add INTERNET permission in the AndroidManifest.xml file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.InAppUpdateMethod"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Step:04
we have to create four variables in HomeActivity.java which uses the below code.
public class MainActivity extends AppCompatActivity {
private ActivityResultLauncher activityResultLauncher;
private AppUpdateManager appUpdateManager;
private static final int DAYS_FOR_FLEXIBLE_UPDATE = 10;
private static final int DAYS_FOR_IMMEDIATE_UPDATE = 20;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkForInAppUpdate();
}
Step:05
We are creating a method named checkForInAppUpdate for the Immediate and Flexible App Update Method.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkForInAppUpdate();
}
private void checkForInAppUpdate() {
appUpdateManager = AppUpdateManagerFactory.create(getApplicationContext());
// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_IMMEDIATE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.IMMEDIATE);
} else if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_FLEXIBLE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.FLEXIBLE);
}
}
});
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
// handle callback
if (result.getResultCode() != RESULT_OK) {
}
});
}
Step:06
We create a Update Lisitener method which means when app is install in your mobile device then users get popup to “Restart App” notification in the Home Screen.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkForInAppUpdate();
}
private void checkForInAppUpdate() {
appUpdateManager = AppUpdateManagerFactory.create(getApplicationContext());
// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_IMMEDIATE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.IMMEDIATE);
} else if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_FLEXIBLE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.FLEXIBLE);
}
}
});
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
// handle callback
if (result.getResultCode() != RESULT_OK) {
}
});
}
InstallStateUpdatedListener listener = state -> {
if (state.installStatus() == InstallStatus.DOWNLOADED) {
// After the update is downloaded, show a notification
// and request user confirmation to restart the app.
popupSnackbarForCompleteUpdate();
}
};
Step:07
We create a Display of the SnackBar notification and call to action to the “RESTART APP” Notification.
InstallStateUpdatedListener listener = state -> {
if (state.installStatus() == InstallStatus.DOWNLOADED) {
// After the update is downloaded, show a notification
// and request user confirmation to restart the app.
popupSnackbarForCompleteUpdate();
}
};
// Displays the snackbar notification and call to action.
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar = Snackbar.make(findViewById(R.id.main), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
snackbar.setActionTextColor(getResources().getColor(android.R.color.holo_blue_dark));
snackbar.show();
}
@Override
protected void onStop() {
super.onStop();
// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);
}
Step:08
We create on Resume method that can show users will download the latest version or not.
// Displays the snackbar notification and call to action.
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar = Snackbar.make(findViewById(R.id.main), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
snackbar.setActionTextColor(getResources().getColor(android.R.color.holo_blue_dark));
snackbar.show();
}
@Override
protected void onResume() {
super.onResume();
appUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
// If the update is downloaded but not installed,
// notify the user to complete the update.
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
}
@Override
protected void onStop() {
super.onStop();
// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);
}
Step:09
In this method, we can check app updated or not if app are update then Snakbar popup are stop showing in the Home Screen.
@Override
protected void onResume() {
super.onResume();
appUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
// If the update is downloaded but not installed,
// notify the user to complete the update.
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
}
@Override
protected void onStop() {
super.onStop();
// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);
}
private void startInAppUpdate(AppUpdateInfo appUpdateInfo, Integer updateType) {
appUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(updateType).build());
}
Step:10
In this method, we have to check If the Update is no longer than then Dismiss All Update System.
@Override
protected void onResume() {
super.onResume();
appUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
// If the update is downloaded but not installed,
// notify the user to complete the update.
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
}
@Override
protected void onStop() {
super.onStop();
// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);
}
private void startInAppUpdate(AppUpdateInfo appUpdateInfo, Integer updateType) {
appUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(updateType).build());
}
Final Step:
Finally, we pass the above method in the onCreate method.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkForInAppUpdate();
}
private void checkForInAppUpdate() {
appUpdateManager = AppUpdateManagerFactory.create(getApplicationContext());
// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_IMMEDIATE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.IMMEDIATE);
} else if (appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_FLEXIBLE_UPDATE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Request the update.
startInAppUpdate(appUpdateInfo, AppUpdateType.FLEXIBLE);
}
}
});
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
// handle callback
if (result.getResultCode() != RESULT_OK) {
}
});
}