0

I have some serious updates that I need to do in my application and I want to make sure that all of the users in my application will download it.

In order to do so, I use an in-app update where I took the answer from here

Basically what I did is as follows:

Added the following to the build.gradle:

implementation 'com.google.android.play:core:1.10.0'

Inside my Class I added:

private AppUpdateManager mAppUpdateManager;
private static final int RC_APP_UPDATE = 11;

@Override
protected void onStart() {
    super.onStart();
    mAppUpdateManager = AppUpdateManagerFactory.create( this );
    Task<AppUpdateInfo> appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
    appUpdateInfoTask.addOnSuccessListener( appUpdateInfo -> {
        if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
                && appUpdateInfo.isUpdateTypeAllowed( AppUpdateType.IMMEDIATE )) {
            try {
                mAppUpdateManager.startUpdateFlowForResult( appUpdateInfo, AppUpdateType.IMMEDIATE, this, RC_APP_UPDATE );
                Log.d( "TEST", "HERE1" );
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
                Log.d( "TEST", "HERE2" );
            }
        } else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
            Log.d( "TEST", "HERE3" );
        }
    } );
}


InstallStateUpdatedListener installStateUpdatedListener = new
        InstallStateUpdatedListener() {
            @Override
            public void onStateUpdate(InstallState state) {
                if (state.installStatus() == InstallStatus.INSTALLED) {
                    if (mAppUpdateManager != null) {
                        mAppUpdateManager.unregisterListener( installStateUpdatedListener );
                        Log.d( "TEST", "HERE4" );
                    }
                }
            }
        };

@Override
protected void onResume() {
    super.onResume();
    mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener( appUpdateInfo -> {
        if (appUpdateInfo.updateAvailability()
                == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
            try {
                mAppUpdateManager.startUpdateFlowForResult(
                        appUpdateInfo, AppUpdateType.IMMEDIATE, DiscoverActivity.this, RC_APP_UPDATE );
                Log.d( "TEST", "HERE5" );
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
                Log.d( "TEST", "HERE6" );
            }

        }
    } );
}

@Override
protected void onStop() {
    if (mAppUpdateManager != null) {
        mAppUpdateManager.unregisterListener(installStateUpdatedListener);
        Log.d( "TEST", "HERE7" );
    }
    super.onStop();
}

Now, I have used internal testing to make sure it works, and indeed when I opened the app it displayed the screen that I need to update the application. Once updated, the app re-opens but then it asks me to update again and so on in a loop.

Why is this happening? From my understanding, the unregisterListener should have solved it.

From debugging the code I see that it keeps entering "HERE1" and "HERE7" and it doesn't enter any listener or something like this. From another testing it never changes the state.installStatus() into INSTALLED and in the logs it says:

InstallState{installStatus=5, bytesDownloaded=0, totalBytesToDownload=0, installErrorCode=-100, packageName=com.xx.yy}

How can I solve it?

Thank you

Ben
  • 1,737
  • 2
  • 30
  • 61

1 Answers1

0

Stop to register the listener, while there is nothing to update; this goes into branch appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE:

mAppUpdateManager.registerListener(installStateUpdatedListener);

Registers a listener for this app that receives state changes for self-update operations.

And the moment when to unregister the listener usually is InstallStatus.INSTALLED:

appUpdateInfo.installStatus() == InstallStatus.INSTALLED

See https://developer.android.com/guide/playcore/in-app-updates/kotlin-java
Or https://gist.github.com/saikiran91/6788ad4d00edca30dad3f51aa47a4c5c

Also super.onStop() should always be called last.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • What you mean is that I should insert the registerListener into the if condition of if (AppUpdateIndo.updateAvailability...? – Ben May 09 '21 at 21:14
  • `appUpdateInfo` should know if an update is required; I'm not particularly certain into which branch, but moving it into there appears to make sense. Because else the app restarts and instantly registers the listener again, which may not be the expected behavior. – Martin Zeitler May 09 '21 at 21:18
  • Yes I understand. I tried to move it there but it still enters appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE, seems like it doesn't understand that update not available already. – Ben May 09 '21 at 21:21
  • None of it works =/ It just never gets into state.installStatus() == InstallStatus.INSTALLED – Ben May 09 '21 at 22:17