A few questions :
What implications does upgrading an app have on stored data i.e. Preferences and database? Does the system perform a clean install of the new version(i.e. remove the older version and then install the new) or something else?
What if the user wants to retain the stored data- say values in the shared preference or a sqlite database?
How can I emulate this app-update-install scenario? If I have a version 'x' installed on my emualator and I do a adb install of version 'x+1' I am getting INSTALL_FAILED_ALREADY_EXIST error. Should I try hosting the new apk on a Web server, will the Package Manager take this as an update?
All data persists (files, preferences, databases). Databases are special as you can specify a database version and if it detects the version changed it will call your onUpgrade(). For all others you're responsible of updating them to the new version, if needed.
As I said in 1, Android persists everything. It's up to you to handle any changes in the way you store your data.
Use adb install -r /path/to/newApk.apk (notice the -r flag, which tells adb to reinstall). Basically, the workflow should be the following:
.
adb uninstall my.package
adb install /path/to/old.apk
# play with app, set preferences, databases, etc.
adb install -r /path/to/new.apk
# watch your app crash in an impressive ball of fire
# fix stuff
# goto 0
Other notes: Yes, the app performs a clean removal of your app before installing the new version. As I said, however, your app's data is not removed. Still, you have to be careful, because this removal causes a few things:
Any processes related to your app are killed (so if your app is running -- any activities, services, anything, all components will be killed).
Anything related to your app is removed from the system, like notifications pushed via the NotificationManager, alarms set via the AlarmManager, etc. I'm not sure what happens to any widgets you might have (never worked with widgets).
You have to take care about that for yourself. Look for onUpgrade() method i.e.
As you have to take care for yourself, you can give the user the possibility to do everything.
You should ensure you have the reinstall option set. Adb should update your application correctly than.
Related
I've been doing some experimentation with Android in order to lock down a kid's phone. Ideally, I'd like him only to be able to use apps that have been pre-installed on the phone; he spends and inordinate amount of time playing games on the phone. I found out that I can disable the Google Play Store on the phone (once rooted) by issuing the command pm disable com.android.vending.
However, I suspect that this setting will not persist of the kid factory resets the phone (he knows how to as he's done it before when I locked down his phone with a 3rd party app).
I've managed to get AOSP built and running on the phone and installed the necessary Gapps for Google Fi (our carrier) and other bare essentials, but I want my final Android image to default to com.android.vending being disabled by default unless explicitly re-enabled after, say, a factory reset.
Now, my knowledge of Android is somewhat limited, but from what I have found via some of the pm source is that the default enabled/disabled status is specified in the AndroidManifest.xml within the APK package. Since I'm trying to disable a Google app, I likely won't be able to modify this.
So, instead I was attempting to figure out via the pm source how exactly pm goes about marking an app as disabled. Unfortunately, my Java comprehensions is terrible so I wasn't able to ascertain anything about the internal workings of how pm does this.
Is there any way that I can cause com.vending.android to be disabled in my system root by default when building AOSP?
Update 1: It seems that the app disabled status is user-dependent. So, disabling the app for one user does not disable for any others. But, surely, there is a global settings file somewhere that the user configuration inherits from...?
Update 2: So, looks like pm works with an in-memory state that is not saved (at least for system apps) even upon a reboot.
You should just buy an old phone for your kid. Factory reset will erase everything you have install, including security programs.
I need to update multiple applications installed on many Android devices.
Is there anyway to put theirs updated apks on USB flash drive, write some script that updates them and run this script manually after I plug it to the device?
I guess the most basic question would be why? Is this something you are purposely keeping off the app store? If it is not TOS breaking just pay the 25$ for a dev account and you can even just keep it in a beta/alpha status so only people you allow to can download it.
Beyond that Android phones can install APK's from third party sources, host the APK somewhere or get it to the user in some fashion and they can download from the phone and install.
Really the app store is your best bet.
It really depends on your use case and control of the devices that you are updating. Using an OTA update tool is always the fastest option for getting upgrades out. You can use BETA distribution, or TestFairy, or even hockey app, however, if you are not choosing to use these items then you will need to do a little extra leg work. Don't worry I won't patronize you with "why are you doing this", you asked a question so I'll do my best to answer it.
1) Register a service or app who's whole goal is to update others. Maybe you call it updateService.
2) Register a Broadcast Receiver for the updateService that listens for USB connected
3) Read the contents of the USB stick to know what needs to be updated. Possibly a folder system where you check "if folder exists, then update" or you can keep a local sql db of update service ownership that keeps track of last updates or current versions.
4) Once you see what needs installed have your service run ADB Install commands. However, if you have new permissions added then user interaction would be required unless you have root access or system level privelages on your update service.
Here is a package installer thread that will give you some ideas of how to silently update. Install apps silently, with granted INSTALL_PACKAGES permission
So the short answer is, yes you can do it, but the longer answer is revolving around the type of control you have, and if you have root or system level access and how much leg work is it worth to you. If you are ok with User Interactions on install then you won't have to worry as much, but I'm guessing you want silent installations.
Hope that helps.
First of all, please note that this question is not same as all the "android foreground app" questions I found on SO, please read on :-)
I'm trying to write an android app for my own use, using golang, without using android-sdk or ndk (this is the KEY point). It is pretty simple, just use golang to write a http service, compile it for arm CPU and voila my app is running and can be access by simply visit http://localhost.
For the purpose of my app, I need to know the currently running foreground application, to define it precisely:
Foreground application is the application that occupies the screen, or has an "activity" what-so-ever (forgive me I'm not an android developer).
Anything that that is depended by the foreground application (e.g. services) is NOT what I am interested in.
If the phone is LOCKED/screen turned off, I want the solution to tell me there is NO foreground app.
And since I do not use anything android, just treat the phone as a LINUX machine, I want the solution to use native LINUX ways, e.g. by inspect /proc, or by calling any installed android command line tool (including sending messages via these command line tools), but NOT using any SDK/NDK way so that I have to use java or incorporate these thing into my app.
Starting from Android SDK 26 (if I remember well) Apps are executed on -one-User-per-App, so (i.e.) WhatsApp is running on UID=30 and Telegram on UID=76, so executing a ROOT command of "ps -A -o PID,USER,NAME" you can parse output and then Kill all Processes that you don't want to be executed.
36119 u30_a149 <WhatsApp_packagename>
36203 u76_a211 <Telegram_packagename>
37399 root [kworker/1:2H]
37423 u0_a329 su
38069 root sh
Without Root Permissions nothing of what you're trying to achieve is possible simply because is not possibile to denied an application to be executed or to kill it without Superuser privilege.
we have build Android from sources and it looks good on our device. Currently we need to make own OTA process, but we dont know how.
We try to implement FSLOTa (https://github.com/embest-tech/android_packages_apps_fsl_imx_demo/tree/master/FSLOta) against our http server, but documentation is very poor - so we simply add source to our source and compile it.
Problem is, that we see app in our box, but it doesnt nothing.
Or there is way to modify built in OTA app, when we change server to our server, we get http request at least. But we dont know, how tells http server to box about new version - any manifest file? XML, JSON or? Is there any example?
Or is there another simple way for implements OTA update to AOSP?
Thank you very much
D
I dont know about FSLOTa nor do I know about the device you are working on. But If you want to implement your own OTA process you could try the following (Just a short draft since your question is very broad):
Create a system app that checks from time to time your server for new packages.
if it detects a new package it downloads it to your device.
it copies the downloaded update.zip to /cache/
Then the app creates the following file /cache/recovery/command and writes --update_package=path_to_your_file in it. (For more commands see /bootable/recovery.cpp)
Then it forces a reboot into recovery
recovery installs your ota package.
Update:
I quickly checked the app you linked. I would check these things:
Do you get till the point where RecoverySystem.installPackage() is called ? (https://github.com/embest-tech/android_packages_apps_fsl_imx_demo/blob/master/FSLOta/src/com/fsl/android/ota/OTAServerManager.java#L282)
Do you see a message in logcat from the RecoverySystem that it is going to reboot? (maybe you have a permission problem and your app is not allowed to force "reboot recovery")
Is the path to your update.zip correct? (it should be in /cache/)
i have been developing an OTA updater android application, you should know application send request to backend server and receive a JSON file about the available update. everything iiiiiiiiiiiiiiiiiiiiii anwserd was ok on non/AB devices, but for A/B devices, the android application downloads the OTA package under /data
and installation will not happen in recovery or anything, the changes will apply to the unused slot before REBOOT.
I always wonder how Android's BackupManager will act when the same BackupManager enabled App is installed on multiple devices (e.g. Smartphone and Tablet) linked to the same Google Account. It seems that I am not the only one, but I couldn't find any specification about this.
What's your experience with this scenario? Are there any official resources that describe that case?
This mechanism doesn't have any user-facing documentation, nor a lot of documentation for app developers, since it's supposed to automatically do the right thing, but the code is available. All the information below comes from inspecting the source code and from the documented options of the bmgr tool. This answer is adapted to be more developer-oriented, from a user-friendly answer I originally wrote on the Android Stack Exchange.
Let's talk about sets, baby
Android's backup service has a concept called a set: the set of all data backed-up from one device on one transport. Each set is identified by a unique string, such as the IMEI on the device. When an app (or the list of installed apps) is backed up, its backup data go into the set associated with the device it's being backed up from. All the sets are still specific to the user's Google account. If you wipe your device and sell it to someone else, he won't be able to access that device's set unless he can log into your Google account.
Default behaviour
When an app is installed, or a device has its list of apps restored, the backup system first looks in that device's set for backup data for that package. If it doesn't find any (either because it's a completely new device with no backed-up data, or because that package has never been installed on that device), it'll expand the search to other sets. (If there's a choice, it'll use the last set that was used for a full-device restore.)
Thus, when you set up a new device, it'll restore the list of apps from an old device's backup, and restore each app from the old device's backup. If you had an app installed on one device and you install it on another device, the app will be restored with its data from the old device. In either case, the data are now backed up into the new device's set, which means that the backup data from the two devices are separate from now on.
After you factory-reset a device, it'll restore from that device's last backup if there is one, and failing that, from some other device's backup if there is one, but it will start to create its own set from then on.
bmgr: basic use
The bmgr tool is intended for debug and test, and gives you a little control over the backup/restore process. You can use this tool in an adb shell to trigger backups and restores of chosen packages, wipe packages' backed-up data, and even a whole-device restore.
Don't try to use it in an on-device shell except as root: you need the system-level android.permission.BACKUP to do anything interesting with it.
For testing, you can make a package update its backed-up data immediately:
bmgr backup com.shadowburst.showr
bmgr run
(or whatever the package name is). To restore one package from the backed-up data it would choose by default:
bmgr restore com.shadowburst.showr
This only works on already-installed packages: it won't install a package in order to restore the data. Both these commands are just for testing, since normally the device backs-up and restores data whenever it needs to.
More control
Now for the stuff that the backup system won't do on its on. To see what sets of backed-up data are available:
bmgr list sets
and you'll get some output like this:
3ff7800e963f25c5 : manta
3f0e5c90a412cca7 : manta
3dd65924a70e14c8 : TF101
3baa67e9ce029355 : m0
The 64-bit hex number on the left is called a token, and uniquely identifies the set. The thing on the right is a (relatively) friendly name for the device that owns the set. For example, manta is the code name for the Nexus 10; TF101 refers to the original Asus Transformer. You can restore a package's data from a set of your choice, by specifying its token:
bmgr restore 3ff7800e963f25c5 com.shadowburst.showr
You can add more package names to the end of the command to restore several packages at once, or you can specify no package name (just the token) to restore every package with data in that set (that is, it does a full-system restore).
Finally, you can wipe an package's data from the current set:
bmgr wipe com.shadowburst.showr
This will make its next backup operation start from scratch. This might be useful while debugging your backup code.
You can't make a device start writing into a different set, nor can you wipe a whole set in one go.