Our product is made up of several .apks. To make life easier for our clients we package them all into a single Setup.apk. Setup.apk in turn will install each .apk. (Note we don't distribute via the Play Store).
Our .apks, including Setup.apk, require special permissions. To get these permissions we need the platform certificate for each device we support, we get the platform certificate from the manufacturers. (They are media players, not phones).
By adding the required permission to the manifest, compiling to release mode, and signing the .apk with the platform certificate we acquire these permissions. Examples of these permissions are:
INSTALL_PACKAGES
ACCESS_SURFACE_FLINGER
READ_FRAME_BUFFER
etc.
Until now our target SDK in the manifest was 14 as we have many clients still running Android 4 devices.
Using INSTALL_PACKAGES Setup.apk can shell to the command line and use Package Manager to install each .apk in turn. This has been working perfectly for years and years. Until Android 7. Now it's not working. So I need help with this, more detailed info below:
The supplier of our latest device says it's not working because Android 7 requires Dynamic Permissions. So I have tried implementing runtime permissions, which I've done with other Play Store apps, as below:
Set the target SDK in the manifest to 26:
I have the following permissions requested in the manifest:
I select the RuntimePermissions library in Process_Globals:
In Activity_Create I request run time permissions:
I then compile all the .apks and sign each of them with the platform certificate I was supplied, autorun.apk for example:
We then copy the .apks we want installed via Setup.apk to it's Files folder for inclusion in Setup.apk, compile it and sign it.
We then copy the final Setup.apk to a flash drive and install it on the new device.
Setup.apk installs and runs. It copies the embedded .apks to a newly created /mnt/sdcard/Player/Setup directory. It then attempts to install each via a command line shell using Package Manager like autorun for example:
The shell return string is then logged to a log file.
With the above manifest permission requests and runtime permission requests and the target SDK set to 26, our .apks do not install. Package Manager returns the following error:
I then added android.permission.INTERACT_ACROSS_USERS_FULL to both the manifest and runtime permissions. Repeating the above process, our .apks still don't install but the Package Manager error changes to:
I note that I only got one runtime permission dialog when Setup.apk started and that was for WRITE_EXTERNAL_STORAGE.
At this stage I am stumped. This worked perfectly for years. Any ideas how to solve this?
Our .apks, including Setup.apk, require special permissions. To get these permissions we need the platform certificate for each device we support, we get the platform certificate from the manufacturers. (They are media players, not phones).
By adding the required permission to the manifest, compiling to release mode, and signing the .apk with the platform certificate we acquire these permissions. Examples of these permissions are:
INSTALL_PACKAGES
ACCESS_SURFACE_FLINGER
READ_FRAME_BUFFER
etc.
Until now our target SDK in the manifest was 14 as we have many clients still running Android 4 devices.
Using INSTALL_PACKAGES Setup.apk can shell to the command line and use Package Manager to install each .apk in turn. This has been working perfectly for years and years. Until Android 7. Now it's not working. So I need help with this, more detailed info below:
The supplier of our latest device says it's not working because Android 7 requires Dynamic Permissions. So I have tried implementing runtime permissions, which I've done with other Play Store apps, as below:
Set the target SDK in the manifest to 26:
B4X:
android:targetSdkVersion="26"
I have the following permissions requested in the manifest:
B4X:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I select the RuntimePermissions library in Process_Globals:
B4X:
Dim libRuntimePermissions As RuntimePermissions
In Activity_Create I request run time permissions:
B4X:
'Permissions
Dim iPermissionCounter As Int
'INSTALL_PACKAGES
iPermissionCounter = 0
Do While True
libRuntimePermissions.CheckAndRequest("android.permission.INSTALL_PACKAGES")
Wait For Activity_PermissionResult (Permission As String, bResult As Boolean)
If bResult Then
Exit
Else
If iPermissionCounter >= 2 Then
Msgbox("You have repeatedly denied permission for the app to install packages." & CRLF & CRLF & "The app will not work without this permission.", "Setup")
ExitApplication
End If
Msgbox("This app requires permission to install packages. Please allow the app to install packages.", "Setup")
iPermissionCounter = iPermissionCounter + 1
End If
Loop
'WRITE_EXTERNAL_STORAGE
iPermissionCounter = 0
Do While True
libRuntimePermissions.CheckAndRequest("android.permission.WRITE_EXTERNAL_STORAGE")
Wait For Activity_PermissionResult (Permission As String, bResult As Boolean)
If bResult Then
Exit
Else
If iPermissionCounter >= 2 Then
Msgbox("You have repeatedly denied permission for the app to install packages." & CRLF & CRLF & "The app will not work without this permission.", "Setup")
ExitApplication
End If
Msgbox("This app requires permission to install packages. Please allow the app to install packages.", "Setup")
iPermissionCounter = iPermissionCounter + 1
End If
Loop
I then compile all the .apks and sign each of them with the platform certificate I was supplied, autorun.apk for example:
B4X:
"C:\Program Files\Java\jdk1.8.0_211\bin\java" -jar "C:\Root\Player\Android\Signing\signapk.jar" "C:\Root\Player\Android\Signing\platform.x509.pem" "C:\Root\Player\Android\Signing\platform.pk8" Autorun.apk Autorun-signed.apk
We then copy the .apks we want installed via Setup.apk to it's Files folder for inclusion in Setup.apk, compile it and sign it.
We then copy the final Setup.apk to a flash drive and install it on the new device.
Setup.apk installs and runs. It copies the embedded .apks to a newly created /mnt/sdcard/Player/Setup directory. It then attempts to install each via a command line shell using Package Manager like autorun for example:
B4X:
pm install -r /mnt/sdcard/Player/Setup/autorun.apk
The shell return string is then logged to a log file.
With the above manifest permission requests and runtime permission requests and the target SDK set to 26, our .apks do not install. Package Manager returns the following error:
B4X:
Error: java.lang.SecurityException: Permission Denial: runInstallCreate from pm command asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
I then added android.permission.INTERACT_ACROSS_USERS_FULL to both the manifest and runtime permissions. Repeating the above process, our .apks still don't install but the Package Manager error changes to:
B4X:
Error: java.lang.NullPointerException
I note that I only got one runtime permission dialog when Setup.apk started and that was for WRITE_EXTERNAL_STORAGE.
At this stage I am stumped. This worked perfectly for years. Any ideas how to solve this?