Android Question APP Update marked as Owner (Kiosk)

Mike1970

Well-Known Member
Licensed User
Longtime User
Hi Guys, I've a watchdog app that is installed using the "ADB install -t "path-to-apk" and then set as kiosk app by using the adb command
B4X:
adb shell dpm set-device-owner myCompany.myProduct.watchdog/anywheresoftware.b4a.objects.AdminReceiver2
That watchdog app run the main app and also update the main-app and all works fine.
The problem now is that I need to update the watchdog app and the same method used to update the main app, simply does not works. The intent looks going fine but no install update is performed.
I've used the class RequestInstallApp
B4X:
Sub Class_Globals
    Private ion As Object
    Private phone As Phone
    Private apk_filename As String
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(apk_name As String)
    apk_filename = apk_name
End Sub

Public Sub Install As ResumableSub
    File.copy(File.DirInternalCache, apk_filename, Starter.Provider.SharedFolder, apk_filename)
    Dim i As Intent
    If phone.SdkVersion >= 24 Then
        i.Initialize("android.intent.action.INSTALL_PACKAGE", Starter.Provider.GetFileUri(apk_filename))
        i.Flags = Bit.Or(i.Flags, 1) 'FLAG_GRANT_READ_URI_PERMISSION
    Else
        i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(Starter.Provider.SharedFolder, apk_filename))
        i.SetType("application/vnd.android.package-archive")
    End If
    
    'TODO - C'è da vedere come e se funziona
    StartActivityForResult(i)
    Wait For ion_Event (MethodName As String, Args() As Object)
    Log(MethodName)
    For Each o In Args
        Log(o)
    Next
    
    Return True 'TODO
End Sub


Private Sub StartActivityForResult(i As Intent)
    Dim jo As JavaObject = GetBA
    ion = jo.CreateEvent("anywheresoftware.b4a.IOnActivityResult", "ion", Null)
    jo.RunMethod("startActivityForResult", Array As Object(ion, i))
End Sub

Private Sub GetBA As Object
    Dim jo As JavaObject = Me
    Return jo.RunMethod("getBA", Null)
End Sub

The manifest of the main-app that in this case is responsible to update the watchdog is set this way:
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: https://www.b4x.com/forum/showthread.php?p=78136

' Il targetSdkVersion era 33, messo a 28.
AddManifestText(
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33"/>   
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.

AddPermission(android.permission.SHUTDOWN)
AddPermission(android.permission.READ_EXTERNAL_STORAGE) ' Allows an application to read from external storage.
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE) ' Allows an application to write to external storage.
AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE) ' Allows an application to write to external storage.
AddPermission(android.permission.ACCESS_SUPERUSER)
AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)

AddPermission("android.permission.SET_TIME_ZONE")
AddPermission("android.permission.SET_TIME")

SetActivityAttribute(main, android:windowSoftInputMode, adjustResize|stateHidden)
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddApplicationText(<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />)

CreateResourceFromFile(Macro, Core.NetworkClearText)


AddManifestText(   
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>   
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.SET_TIME" />
    <uses-permission android:name="android.permission.SET_TIME_ZONE" />   
    <uses-permission android:name="android.permission.SET_TIME" android:protectionLevel="signature|system" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
)

'<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

'**** FILE PROVIDER: ****************************************************************
AddManifestText(
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"  android:maxSdkVersion="19" />
)
SetApplicationAttribute(android:requestLegacyExternalStorage, true)
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>
)
CreateResource(xml, provider_paths, <files-path name="name" path="shared" />)
'************************************************************************************

Any way to do it?
I'm using a customized Android device that do not show the request to the user to perform the update, but it is still without root permissions.

Thank you in advance.
 

OliverA

Expert
Licensed User
Longtime User
I'm using this:
B4X:
            ' // Hint: https://stackoverflow.com/a/66204377
            If phone.SdkVersion >= 24 Then
                Log(Provider.GetFileUri(fileName))
                'i.Initialize("android.intent.action.INSTALL_PACKAGE", Provider.GetFileUri(fileName))
                'i.Flags = Bit.Or(i.Flags, FLAG_GRANT_READ_URI_PERMISSION)
                i.Initialize("android.intent.action.INSTALL_PACKAGE", "")
                'According to the link above, you have to use setData when you give permissions via intent
                'SetFileUriAsIntentData does both the setData and the Read
                Provider.SetFileUriAsIntentData(i, fileName)
            Else
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
I'm using this:
B4X:
            ' // Hint: https://stackoverflow.com/a/66204377
            If phone.SdkVersion >= 24 Then
                Log(Provider.GetFileUri(fileName))
                'i.Initialize("android.intent.action.INSTALL_PACKAGE", Provider.GetFileUri(fileName))
                'i.Flags = Bit.Or(i.Flags, FLAG_GRANT_READ_URI_PERMISSION)
                i.Initialize("android.intent.action.INSTALL_PACKAGE", "")
                'According to the link above, you have to use setData when you give permissions via intent
                'SetFileUriAsIntentData does both the setData and the Read
                Provider.SetFileUriAsIntentData(i, fileName)
            Else
Hi, thank you for your reply. Your code behave exactly like mine. The intent is started, but the application is not installed/updated. If I try with another apk file that is not a "kiosk" app, then even my posted code perform as expected, installing the app.
If I try to install the watchdog app, that is a kiosk app, then nothing happens.
No errors, just nothing.

At the bottom of the function Install of the class "RequestInstallApp" there are these lines after the "StartActivityForResult":
B4X:
    Wait For ion_Event (MethodName As String, Args() As Object)
    Log(MethodName)
    For Each o In Args
        Log("Eventi ion " &  o)
    Next
MethodName return "ResultArrived" and then just one line from the loop: "Eventi ion null"
Everythings terminate without errors, but the installation is not performed.

Any clue?
Thank you for your help.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Hook up the phone via USB cable and look at the raw logs while the app is trying the install. One issue I encountered is that I had to randomize the filename of the APK I wanted to install, otherwise the play store gleefully ignored the install request and only by looking at the raw logs was I able to figure out what was going on.
 
Upvote 0
Top