I want Android apps to believe that Automatic Time Zone is set to ON even though it actually is not. I read that Automatic Time Zone is detected using Settings.Global.AUTO_TIME variable, which returns value 1 if Automatic Time Zone is ON and value 0 if Automatic Time Zone is OFF.
This variable is read using the below line
Settings.Global.getInt(getContentResolver(), Settings.Global.AUTO_TIME)
I read that this variable can only be set by a System App. Is there a way to change this variable somehow? Can I write an application that allows me to change this variable? Can this be done by rooting the android device.
The most commonly suggested solution is to use Settings.Global.putInt(getContentResolver(), Settings.Global.AUTO_TIME, 1). You will end up seeing this message in logcat, though:
Setting auto_time has moved from android.provider.Settings.System to android.provider.Settings.Global, value is unchanged.
According to the Android documentation, apps cannot modify these settings.
https://developer.android.com/reference/android/provider/Settings.Global
Global system settings, containing preferences that always apply identically to all defined users. Applications can read these but are not allowed to write; like the "Secure" settings, these are for preferences that the user must explicitly modify through the system UI or specialized APIs for those values.
These settings are read-only unless your app is installed as a system app or is signed by the manufacturer of the device that it is running on.
Most people end up rooting their device but there is an alternative. Device Owner apps can modify global system settings through a different API.
https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setGlobalSetting(android.content.ComponentName,%20java.lang.String,%20java.lang.String)
You would do it like so:
DevicePolicyManager dpm = (DevicePolicyManager) getApplicationContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName component = new ComponentName(getApplicationContext(), DeviceAdminReceiver.class);
dpm.setGlobalSetting(component, Settings.Global.AUTO_TIME, enable ? "1" : "0");
This alternative is mostly suitable for homebrew apps and proprietary Android-based products because the device cannot have user accounts. Play Store will not install apps as Device Owner, it must be done manually.
Here is how to do it with ADB:
https://developer.android.com/work/dpc/dedicated-devices/cookbook#dev-setup
You can use Settings.Global.putInt(getContentResolver(), Settings.Global.AUTO_TIME, 1) to set the value from your app.
You need to have the WRITE_SETTINGS permission though.
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 thought there would be some straight forward solution to this.
Requirements:
Uniquely identify device across app install/uninstall sessions.
Options:
Use some kind of Android's device-identifier-API each time when needed (read it every time from Android's API). According to Identififying-app-installations blog post this is not recommended and not reliable solution.
Generate UUID once (on first app start) and persist it somewhere somehow that it would be preserved across multiple app installs/uninstalls. This "somewhere somehow" part is the mystery. Solutions like storing onto the SD card or Cloud are not an option. iOS has keychain that can be used for this kind of stuff but I didn't find Android's equivalent of it.
What are my other options here? I prefer going the (2) route because of my server implementation (server is generating UUID for the first time if not present). But if it is not an option, I can fallback to (1) and modify the server.
Thanks.
To uniquely identify an application between application installs/reinstalls, you need to get it's hardware ID and use that as your credentials/key.
To fetch the hardwareID, you can use the following method:
public static String getHardwareId(Context context) {
return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
it's partially equivallent to a UUID with the following exception: The value may change if a factory reset is performed on the device.
The reason why i call it "partially equivallent" is this:
The HardwareID is a 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. The value may change if a factory reset is performed on the device.
Note: When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.
But this hits the #2 problem: where and how to store it; storing it in SharedPreferences is useless as that is wiped if the app is uninstalled. Same for /data/data/your.package.name/my_stored_keys folder as that one gets deleted from the phone during uninstallation as well.
You will need to save it server-side if you wish to persist between uninstalling and reinstalling the app.
Does anyone know what is the behavior in production of a device-owner App, distributed thru Google Play, when updates occur?
As we know, installing a device-owner App involves some motivation and is not easy: reset to factory default then NFC-provision the device with a second device etc… So even if we consider this step done, would any further update involve so much pain, each time?
This question occurs because on my development device, I cannot re-launch the device-owner App with changes if it was previously installed… unless I reset the device to factory settings!
Thanks for reading…
Once your Device Owner app is set, a new file is created under /data/system/device_owner.xml that references the Device/Profile owner apps.
The Android system is then reading this file to check which application is considered as Device Owner or Profile Owner App.
This file contains refers to the applications by using their package name. Updating these apps won't infer on this file since the package name stays the same.
When you're updating your app, just make sure you're always using the same certificate as the one you previously used when first setting you device owner for the first time (which is a standard rule of security for every application update in Android anyway).
Permissions can also be updated the same way, without the need to reprovision it through NFC, nor dpm tool.
I trying some stuffs with android as i am learning android development, now i have a scenario here.
I want to change the android phone's system date through my application( first i would like to know is this doable? )
Layout is as below
Now what i want is when the user clicks the button the date should increase by say 20 days
how can i do this.
i am unable to start...please help
As I already said that's impossible. You need the SET_TIME permission and that permission is granted by system only to applications that are in the Android system image. If You are able to gain that privilege you can easily change with the AlarmManager. SystemClock.setCurrentTimeMillis write the /dev/allarm file
adb shell ls -l /dev/alarm
crw-rw-r-- system radio 10, 46 2013-06-12 10:46 alarm
c stays for Character special file (stored in /dev).
system is the owner of the file
radio is the group
system and radio have read and write permissions (rw-, tree bits, int value 6), the others have only the read permission (r, int value 4). So the file permission is 664. If you can get root user (running su), you can change the permission of this file and wrote in it a new value. A bug report has been filled in order to ask google to allow apps to modify programmatically the mobile date but it has been declied. Here the reference
On Android, the only way for an application do have write access to the time&date is to get the SET_TIME permission, which is only possible for "applications that are in the Android system image or that are signed with the same certificate as the application that declared the permission." (see signatureOrSystem protection level).
The only way for your application to reach this protection level is to run on a rooted device, or build and sign your own android rom.
If this is your case, you can easily use the AlarmManager or simply the Calendar instance.
Good luck!
Normal user applications does not have permission to change the device time. Read the answer by cashbash in the following post for the alternate option.
Unfortunately, blackbelt is right; android lets us do a lot of cool things, but changing system time programmatically is not one of them.
Since I see that you are looking for more credible/official sources, I suggest you check out this open ticket with Google, which suggests this is an open problem--it ought to work, but doesn't, and it doesn't seem Google is going to fix it anytime soon. The gist of it is that the SET_TIME protection level is set higher than it ought to be. (for more information on permissions, see here)
Although this is not quite the same as changing the time programmatically, you can still make the user change the system time for you if for some reason you do need system time to be changed. This thread will explain how to go about implementing that if you want to go that route.
Hope this was helpful information!
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.