B4A Library AppUpdating 2.0 - update non-market apps

Time goes by, things change and old tools need to be updated.

AppUpdating 2.0 is a partial rewrite of AppUpdating, a lib written back in 2014 to allow the remote update of non-market applications hosted on a webserver.

Why AU 2.0? Main reason is Google's introduction of Android 8 and the profound changes on a few key points coming with it. But it was time to leverage B4x's new features too. And, finally, a bit of clean up is always due.. :)

On next two posts I'll describe the steps needed to make the lib work with your code.
Edit: see post#43 below for installing instructions related to version 2.05 and higher.

What the lib does is simply to check whether the version number reported by reading an info text file on your webserver is greater than the one showed in the running copy of your app. If it finds indication of a newer version, it downloads it, then it asks the user to install it.
Since we can't know if the user agrees to update the app, we simply go on with our app, knowing that a service burned in the lib will fire when the OS will signal that the user accepted to install the newly downloaded copy of the app. In this latter case, the same service will reload the app when ready.

Files attacched:
AppUpdating.b4xlib - version 2.05 packed following the new b4xlib standard
AU200_src - source code for the lib
AU200_demo - example program using the lib
AU200_lib - lib file compiled with B4A 8.30

Versions changelog
2.05 - made it compatible with simultaneous use of NB6
2.00 - initial release of AppUpdating 2.0
 

Attachments

  • AU200_demo.zip
    31.6 KB · Views: 789
  • AU200_src.zip
    14.9 KB · Views: 572
  • AU200_lib.zip
    25.3 KB · Views: 767
  • AppUpdating.b4xlib
    7.3 KB · Views: 275
Last edited:

udg

Expert
Licensed User
Hi all, sorry for the long delay.
In order to stop the ever growing confusion about versions of the lib, please find in post #1 the latest one.
It's labeled 2.05 altough its code base is identical to version 2.03. You find it published in the form of the newer b4xlib, so to access its code just rename it to a zip file and open it: you'll find the class c_appupdate and the service newinst2 as always.

For those who simply want to use the lib w/o concern on how is built or what's inside it, just copy the b4xlib file to your Additional Libraries folder (I put it in the sub-folder B4X) and check AppUdating in your IDE's Library Manager. Then prepare the Manifest of your app as follows (this means "forget instructions from post#2 above):
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.basic4ppc.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

AddReceiverText(newinst2,
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>)

' Starting from Android 7 (API 24) we pass a file uri using a FileProvider
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)

'new external-files-path ensures compatibility with NB6
CreateResource(xml, provider_paths,
<paths>
   <files-path name="name" path="shared" />
   <external-files-path name="name1" path="shared1" />
</paths>
)

AddManifestText(<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="19" />
)

AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)
AddPermission(android.permission.INTERNET)

Edit: section Main Activity from post #2 is still needed.

As soon as possible I will update the demo and hopefully add a B4xPages demo too.
 
Last edited:

DonManfred

Expert
Licensed User

udg

Expert
Licensed User
AppUpdating 2.05 - installation

Lib files installation

As usual with any contributed library published in the b4xlib format, download the lib file (AppUpdatingxxx.b4xlib, you need just this one), and place it in your Additional Libraries path (see menu option "Tools/Configure paths" in your B4A installation). Best if you place it in the B4X sub-folder.
To access its source code, just rename its extension to "zip" and open it as any zipped file; in it you'll find the class c_appupdate and the service newinst2 as in older versions.
The above point is also useful if you need to recompile the lib with a more recent version of B4A.

Manifest
For any app that you'd like to use this lib with, go to its Manifest editor ("Project/Manifest Editor") and add the following code:
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.basic4ppc.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

AddReceiverText(newinst2,
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>)

' Starting from Android 7 (API 24) we pass a file uri using a FileProvider
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)

'new external-files-path ensures compatibility with NB6
CreateResource(xml, provider_paths,
<paths>
   <files-path name="name" path="shared" />
   <external-files-path name="name1" path="shared1" />
</paths>
)

AddManifestText(<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="19" />
)

AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)
AddPermission(android.permission.INTERNET)

Main activity
Don't forget to check AppUdating in your IDE's Library Manager.
Add to your Main activity the following code and call it before issuing an "install" command to the lib.
B4X:
'Check whether we already have permission for install other apps.
'If not we open the relevant settings page
'then wait for Activity_Resume and check the value of CanRequestPackageInstalls again
Private Sub CheckInstallationRequirements As ResumableSub
    If File.ExternalWritable = False Then
        MsgboxAsync("Storage card not available. Make sure that your device is not connected in USB storage mode.", "")
        Return False
    Else If phone.SdkVersion >= 26 And apkupdt.CanRequestPackageInstalls = False Then
        MsgboxAsync("Please allow me to install applications.", "")
        Wait For Msgbox_Result(Result As Int)
        Dim in As Intent
        in.Initialize("android.settings.MANAGE_UNKNOWN_APP_SOURCES", "package:" & Application.PackageName)
        StartActivity(in)
        Wait For Activity_Resume '<-- wait for Activity_Resume
        Return apkupdt.CanRequestPackageInstalls
    Else If apkupdt.CheckNonMarketAppsEnabled = False Then
        MsgboxAsync("Please enable installation of non-market applications." & CRLF & "Under Settings - Security - Unknown sources" _
        & CRLF & "Or Settings - Applications - Unknown sources", "")
        Return False
    Else
        Return True
    End If
End Sub

Note: code above assumes you named the instance of the class cl_appupdate as apkupdt (Dim apkupdt As cl_appupdate). If you used a different name, change the above code accordingly.

That's it. You're now ready to use the lib.
You may want to refer to the demo soon to be attached to post#1 in order to see how the methods from the lib are used in a couple of scenarios.
 
Last edited:
Top