B4A Library In-App Update Library

flexible_flow.png


Keeping your app up-to-date on your users’ devices enables them to try new features, as well as benefit from performance improvements and bug fixes. Although some users enable background updates when their device is connected to an unmetered connection, other users may need to be reminded to update. In-app updates is a Play Core library feature that introduces a new request flow to prompt active users to update your app.

This is a B4A wrapper for Google In-App Update. https://developer.android.com/guide/playcore/in-app-updates
Before you begin, please read google documentation. You can also read from CapTech https://www.captechconsulting.com/blogs/upgrading-your-app-with-in-app-updates and Medium article.


Requirements:
  • In-app updates works only with devices running Android 5.0 (API level 21) or higher, and requires you to use Play Core library 1.5.0 or higher. To install Play Core library start SDK Manager and in search field type: com.google.android.play:core and install it.
  • In-app updates are available only to user accounts that own the app. So, make sure the account you’re using has downloaded your app from Google Play at least once before using the account to test in-app updates.
  • Make sure that the app that you are testing in-app updates with has the same application ID(Package Name) and is signed with the same signing key as the one available from Google Play.
  • Because Google Play can only update an app to a higher version code, make sure the app you are testing as a lower version code than the update version code.
  • When testing, make sure the Google Play cache is up to date by closing the Play Store App and then going back to the My Apps & Games tab before testing updates.

HowToUse:
Note: This is an example of ImmediateUpdate which handle all tasks by itself.

If you want to use this library with B4XPages then follow instructions here(https://www.b4x.com/android/forum/threads/in-app-update-library.126305/post-809707)

- Add this line to your manifest.
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)

- Add this line in Project Attributes of your Main activity.
B4X:
#AdditionalJar: com.google.android.gms:play-services-base

- Define a variable as InAppUpdate library.
B4X:
Private Sub Globals
  Private InAppUpdate As InAppUpdate
End Sub

- Copy this codes to your main activity without change.
B4X:
Private Sub CheckUpdate
    InAppUpdate.initialize(False)
    InAppUpdate.GetAppUpdateInfo

    #IF JAVA
      public void _onactivityresult(int requestCode,int resultCode){
        com.khaan.iau.InAppUpdate.onActivityResult(activityBA,requestCode,resultCode);
      }
    #END IF
End Sub

Private Sub InAppUpdate_onAppUpdateInfoReceived(success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
    Log($"InAppUpdate_onAppUpdateInfoReceived, Success: ${success}"$)

    If success Then
      If inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS Or inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE Then
        InAppUpdate.startImmediateUpdateFlow
      End If
    End If
End Sub

- And finaly call CheckUpdate everywhere you want. for example in Activity_Resume
B4X:
Private Sub Activity_Resume
    CheckUpdate
End Sub


If you want to use FlexibleUpdate then you should implement methods and handle events and states manually.
When you start a flexible update, a dialog first appears to the user to request consent. If the user consents, the download starts in the background and you can Show your custom progressbar to user when update is downloading, and the user may continue to interact with the app.
After the update is downloaded, show a notification and request user confirmation to install update and restart the app.

for more information please read documents.




InAppUpdate
Version:
1.1
  • InAppUpdate
    Events:
    • InAppUpdate_onAppUpdateInfoReceived (success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
    • InAppUpdate_onUserAcceptUpdate (accepted As Boolean)
    • InAppUpdate_onStateUpdate (installStatus As Int, arg1 As Long, arg2 As Long)
  • Fields:
    • INSTALL_STATUS_REQUIRES_UI_INTENT As int
    • INSTALL_STATUS_CANCELED As int
    • INSTALL_STATUS_PENDING As int
    • INSTALL_STATUS_DOWNLOADED As int
    • INSTALL_STATUS_INSTALLING As int
    • INSTALL_STATUS_DOWNLOADING As int
    • INSTALL_STATUS_FAILED As int
    • INSTALL_STATUS_INSTALLED As int
    • INSTALL_STATUS_UNKNOWN As int
  • Methods:
    • fake_UserRejectsUpdate As void
      Simulates that a user has declined an update from the update confirmation dialog.
      This method call works only if isConfirmationDialogVisible() or isImmediateFlowVisible() is true.
    • fake_UpdateDownloaded As void
      Simulates that update downloaded.
    • isTestMode As java.lang.Boolean
      Retuen whether test mode is enabled or not.
    • fake_UpdateDownloading As void
      Simulates that update downloading.
    • StartImmediateUpdateFlow As void
      Trigger the immediate update flow.
    • fake_UserCancelsDownload As void
      Simulates the user canceling the download via the Play UI.
      This method call works only if the download of an update is pending or downloading.
    • installFlexibleUpdate As void
      Once we detect that the InstallStatus represents the DOWNLOADED state,
      We are required to restart the app so that the update can be installed.
      Whilst the immediate update method handles this for you, in the case of the flexible update
      We need to manually trigger this. In order to manually trigger this update we need to make use of the installFlexibleUpdate method.
      When this is called, a full-screen UI will be displayed from the play core library and the app will be restarted in the background so that the update can be installed.
      The app will then be restarted with the update applied.
    • Initialize (ba As anywheresoftware.b4a.BA, testMode As boolean) As com.khaan.iau.InAppUpdate
      Initializes the In-App update.
    • fake_UserAcceptsUpdate As void
      Simulates that a user has accepted an flexible update from the update confirmation dialog.
      The download is enqueued in PENDING status.
    • StartFlexibleUpdateFlow As void
      Trigger the flexible update flow.
    • fake_CustomState (status As int) As void
      Simulates custom state.
    • fake_UpdateFailed As void
      Simulates that update is failed.
    • GetAppUpdateInfo As void
      Checking whether there is an update that is available from the play store.
  • InAppUpdateInfo
    Fields:
    • UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS As int
    • UPDATE_AVAILABILITY_AVAILABLE As int
    • UPDATE_AVAILABILITY_UNKNOWN As int
    • UPDATE_AVAILABILITY_NOT_AVAILABLE As int
  • Methods:
    • totalBytesToDownload As long
    • updateAvailability As int
    • isImmediateUpdateAllowed As boolean
    • bytesDownloaded As long
    • clientVersionStalenessDays As java.lang.Integer
    • installStatus As int
    • updatePriority As int
    • availableVersionCode As int
    • isFlexibleUpdateAllowed As boolean
 

Attachments

  • InAppUpdate.jar
    7 KB · Views: 565
  • InAppUpdate.xml
    7.9 KB · Views: 532
Last edited:

Roger Daley

Well-Known Member
Licensed User
Longtime User
flexible_flow.png


Keeping your app up-to-date on your users’ devices enables them to try new features, as well as benefit from performance improvements and bug fixes. Although some users enable background updates when their device is connected to an unmetered connection, other users may need to be reminded to update. In-app updates is a Play Core library feature that introduces a new request flow to prompt active users to update your app.

This is a B4A wrapper for Google In-App Update. https://developer.android.com/guide/playcore/in-app-updates
Before you begin, please read google documentation. You can also read Medium article (thanks to Joe Birch)

Requirements:
  • In-app updates works only with devices running Android 5.0 (API level 21) or higher, and requires you to use Play Core library 1.5.0 or higher. To install Play Core library start SDK Manager and in search field type: com.google.android.play:core and install it.
  • In-app updates are available only to user accounts that own the app. So, make sure the account you’re using has downloaded your app from Google Play at least once before using the account to test in-app updates.
  • Make sure that the app that you are testing in-app updates with has the same application ID(Package Name) and is signed with the same signing key as the one available from Google Play.
  • Because Google Play can only update an app to a higher version code, make sure the app you are testing as a lower version code than the update version code.

HowToUse:
Note: This is an example of ImmediateUpdate which handle all tasks by itself.

- Add this line to your manifest.
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)

- Add this line in Project Attributes of your Main activity.
B4X:
#AdditionalJar: com.google.android.gms:play-services-base

- Define a variable as InAppUpdate library.
B4X:
Private Sub Globals
  Private InAppUpdate As InAppUpdate
End Sub

- Copy this codes to your main activity without change.
B4X:
Private Sub CheckUpdate
    InAppUpdate.initialize(False)
    InAppUpdate.GetAppUpdateInfo

    #IF JAVA
      public void _onactivityresult(int requestCode,int resultCode){
        com.khaan.iau.InAppUpdate.onActivityResult(activityBA,requestCode,resultCode);
      }
    #END IF
End Sub

Private Sub InAppUpdate_onAppUpdateInfoReceived(success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
    Log($"InAppUpdate_onAppUpdateInfoReceived, Success: ${success}"$)

    If success Then
      If inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS Or inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE Then
        InAppUpdate.startImmediateUpdateFlow
      End If
    End If
End Sub

- And finaly call CheckUpdate everywhere you want. for example in Activity_Resume
B4X:
Private Sub Activity_Resume
    CheckUpdate
End Sub


If you want to use FlexibleUpdate then you should implement methods and handle events and states manually.
When you start a flexible update, a dialog first appears to the user to request consent. If the user consents, the download starts in the background and you can Show your custom progressbar to user when update is downloading, and the user may continue to interact with the app.
After the update is downloaded, show a notification and request user confirmation to install update and restart the app.

for more information please read documents.




InAppUpdate
Version:
1.1
  • InAppUpdate
    Events:
    • InAppUpdate_onAppUpdateInfoReceived (success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
    • InAppUpdate_onUserAcceptUpdate (accepted As Boolean)
    • InAppUpdate_onStateUpdate (installStatus As Int, arg1 As Long, arg2 As Long)
  • Fields:
    • INSTALL_STATUS_REQUIRES_UI_INTENT As int
    • INSTALL_STATUS_CANCELED As int
    • INSTALL_STATUS_PENDING As int
    • INSTALL_STATUS_DOWNLOADED As int
    • INSTALL_STATUS_INSTALLING As int
    • INSTALL_STATUS_DOWNLOADING As int
    • INSTALL_STATUS_FAILED As int
    • INSTALL_STATUS_INSTALLED As int
    • INSTALL_STATUS_UNKNOWN As int
  • Methods:
    • fake_UserRejectsUpdate As void
      Simulates that a user has declined an update from the update confirmation dialog.
      This method call works only if isConfirmationDialogVisible() or isImmediateFlowVisible() is true.
    • fake_UpdateDownloaded As void
      Simulates that update downloaded.
    • isTestMode As java.lang.Boolean
      Retuen whether test mode is enabled or not.
    • fake_UpdateDownloading As void
      Simulates that update downloading.
    • StartImmediateUpdateFlow As void
      Trigger the immediate update flow.
    • fake_UserCancelsDownload As void
      Simulates the user canceling the download via the Play UI.
      This method call works only if the download of an update is pending or downloading.
    • installFlexibleUpdate As void
      Once we detect that the InstallStatus represents the DOWNLOADED state,
      We are required to restart the app so that the update can be installed.
      Whilst the immediate update method handles this for you, in the case of the flexible update
      We need to manually trigger this. In order to manually trigger this update we need to make use of the installFlexibleUpdate method.
      When this is called, a full-screen UI will be displayed from the play core library and the app will be restarted in the background so that the update can be installed.
      The app will then be restarted with the update applied.
    • Initialize (ba As anywheresoftware.b4a.BA, testMode As boolean) As com.khaan.iau.InAppUpdate
      Initializes the In-App update.
    • fake_UserAcceptsUpdate As void
      Simulates that a user has accepted an flexible update from the update confirmation dialog.
      The download is enqueued in PENDING status.
    • StartFlexibleUpdateFlow As void
      Trigger the flexible update flow.
    • fake_CustomState (status As int) As void
      Simulates custom state.
    • fake_UpdateFailed As void
      Simulates that update is failed.
    • GetAppUpdateInfo As void
      Checking whether there is an update that is available from the play store.
  • InAppUpdateInfo
    Fields:
    • UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS As int
    • UPDATE_AVAILABILITY_AVAILABLE As int
    • UPDATE_AVAILABILITY_UNKNOWN As int
    • UPDATE_AVAILABILITY_NOT_AVAILABLE As int
  • Methods:
    • totalBytesToDownload As long
    • updateAvailability As int
    • isImmediateUpdateAllowed As boolean
    • bytesDownloaded As long
    • clientVersionStalenessDays As java.lang.Integer
    • installStatus As int
    • updatePriority As int
    • availableVersionCode As int
    • isFlexibleUpdateAllowed As boolean

This is really great, in the past I've tried to find a way to do what your library does. Just as important was the step by step instructions on how to implement it. I have inserted it in to every app I could, except one in B4XPages, I will hold off on that one for now.

Roger
 

ArminKh1993

Active Member
This is really great, in the past I've tried to find a way to do what your library does. Just as important was the step by step instructions on how to implement it. I have inserted it in to every app I could, except one in B4XPages, I will hold off on that one for now.

Roger
i will find a solution for it
but for now i dont know if "_onactivityresult" hook is changed in b4x pages or not? maybe @Erel can help us
 
Last edited:

ArminKh1993

Active Member

samikinikar

Member
Licensed User
Longtime User
Works perfectly on given test app, but not on my app, The app updates dialog repeats every time even though the update/install is complete. When I start the app, I still see the old app. Any idea what might be the issue.
 

ArminKh1993

Active Member
Works perfectly on given test app, but not on my app, The app updates dialog repeats every time even though the update/install is complete. When I start the app, I still see the old app. Any idea what might be the issue.
As i said at first post:
  • When testing, make sure the Google Play cache is up to date by closing the Play Store App and then going back to the My Apps & Games tab before testing updates.
 

samikinikar

Member
Licensed User
Longtime User
Thank you for the update, Its the same, I tried multiple devices too, then too same issue. The update dialog repeats again and again, even after completing.
 

epneeh

Member
Thank you for the update, Its the same, I tried multiple devices too, then too same issue. The update dialog repeats again and again, even after completing.
Hi there, i have similar issues, i also check inAppUpdateInfo.availableVersionCode for version code it says lower version (61) than my latest version (63)
 

ArminKh1993

Active Member
Hi there, i have similar issues, i also check inAppUpdateInfo.availableVersionCode for version code it says lower version (61) than my latest version (63)
Please read first post.
  • When testing, make sure the Google Play cache is up to date by closing the Play Store App and then going back to the My Apps & Games tab before testing updates.
 

ArminKh1993

Active Member
I recently tried to run a project on b4xpages and used this library as well.
If you want to use this library in b4xpages, you have to change a few pieces of code.

- Define a variable as InAppUpdate library in your page.
B4X:
Private Sub Class_Globals
     Private InAppUpdate As InAppUpdate   
End Sub

- Copy this codes to your page without change.
B4X:
Private Sub CheckUpdate
    InAppUpdate.initialize(False)
    InAppUpdate.GetAppUpdateInfo
End Sub

Private Sub InAppUpdate_onAppUpdateInfoReceived(success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
    Log($"InAppUpdate_onAppUpdateInfoReceived, Success: ${success}"$)

    If success Then
      If inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS Or inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE Then
        InAppUpdate.startImmediateUpdateFlow
      End If
    End If
End Sub

- Copy this codes to your main activity without change.
B4X:
Sub InAppUpdate_onUserAcceptUpdate(accepted As Boolean)
        #IF JAVA
            public void _onactivityresult(int requestCode,int resultCode){
                com.khaan.iau.InAppUpdate.onActivityResult(activityBA,requestCode,resultCode);
            }
        #END IF
        
        CallSub2(B4XPages.MainPage,"InAppUpdate_onUserAcceptUpdate",accepted)
End Sub

- Note: You must replace B4XPages.MainPage with your page

- And finaly call CheckUpdate everywhere you want. for example in B4XPage_Foreground
B4X:
Private Sub B4XPage_Foreground
        CheckUpdate
End Sub

Good Luck😉
 

samikinikar

Member
Licensed User
Longtime User
Now another issue .... I changed the local VersionCode to higher than the play store, then too "InAppUpdate_onAppUpdateInfoReceived" is returned Success=True.

Play App Store version : 2
Local VersionCode : 4

Any idea what might be the issue ? I cleared the play cache and followed as indicated above but same issue continues.


Its solved now.
 
Last edited:

ArminKh1993

Active Member
Now another issue .... I changed the local VersionCode to higher than the play store, then too "InAppUpdate_onAppUpdateInfoReceived" is returned Success=True.

Play App Store version : 2
Local VersionCode : 4

Any idea what might be the issue ? I cleared the play cache and followed as indicated above but same issue continues.


Its solved now.
Success=True means that the app information has been successfully received from the server.
 

tarique

Member
I have difficulty in this library, I have tested this library, it does not work on android 6, 9, and 11. only it is working on android 7, even on android 7 the update screen also repeats itself, it shows installation completed but the app is still old.

in android 6,9 and 11 I am getting this only "InAppUpdate_onAppUpdateInfoReceived, Success: true"
I have cleared the cache of the play store as well but the problem still exists.
 

Roger Daley

Well-Known Member
Licensed User
Longtime User
I have difficulty in this library, I have tested this library, it does not work on android 6, 9, and 11. only it is working on android 7, even on android 7 the update screen also repeats itself, it shows installation completed but the app is still old.

in android 6,9 and 11 I am getting this only "InAppUpdate_onAppUpdateInfoReceived, Success: true"
I have cleared the cache of the play store as well but the problem still exists.

Tarique,
I can't help you much except to confirm the library works well on Android 8 &11, LG V20 & Galaxy A70 respectively.

I hope you find your problem, the update feature is really great and looks very professional.

Regards Roger.
 

tarique

Member
Than
Tarique,
I can't help you much except to confirm the library works well on Android 8 &11, LG V20 & Galaxy A70 respectively.

I hope you find your problem, the update feature is really great and looks very professional.

Regards Roger.
Thanks, but I am getting this response when I use "Inappupdatetest" example for b4xpages available on "https://www.b4x.com/android/forum/t...brary-usable-with-b4xpages.126534/post-791573" I have changed pkg name and used signing Keystore file, the available version Code on playstore is 7, while I have tested from 1 to 6 and it shows me the following response with following code

Test code:
Private Sub InAppUpdate_onAppUpdateInfoReceived(success As Boolean, inAppUpdateInfo As InAppUpdateInfo)
        Log($"InAppUpdate_onAppUpdateInfoReceived, Success: ${success}"$)
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE)
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS)
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_NOT_AVAILABLE)
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_UNKNOWN)
Log(inAppUpdateInfo.updateAvailability)
        If success Then
          If inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS Or inAppUpdateInfo.updateAvailability = inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE Then
                InAppUpdate.startImmediateUpdateFlow
          End If
        End If
End Sub

the output response of thes logs are
InAppUpdate_onAppUpdateInfoReceived, Success: true
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_AVAILABLE) =2
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) =3
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_NOT_AVAILABLE)=1
Log(inAppUpdateInfo.UPDATE_AVAILABILITY_UNKNOWN)=0
Log(inAppUpdateInfo.updateAvailability)=1
the value of Log(inAppUpdateInfo.updateAvailability) should be 2

I don't know why it shows me that there is no new version. even playstore not showing update button, it only shows open and uninstall. by pressing open button this test example opens.
 

ArminKh1993

Active Member
Unfortunately, due to the revocation of my account license, I can no longer support my libraries. It is funny that I can not even edit my messages :)
You can ask for help from Erel or other members in the forum or you can use other libraries.
I'm sorry for what happened and I hope you understand what I mean. Thanks
 

Roger Daley

Well-Known Member
Licensed User
Longtime User
Unfortunately, due to the revocation of my account license, I can no longer support my libraries. It is funny that I can not even edit my messages :)
You can ask for help from Erel or other members in the forum or you can use other libraries.
I'm sorry for what happened and I hope you understand what I mean. Thanks

Not really sure what you mean. But sorry to lose your contributions if that is the case.
 
Top