How to implement In-App Update Method in Android Studio | Implement In-App Update[Immediate & Flexible] | 2025

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) {
}
});
}
Scroll to Top