Prelude:
The client wants to install EMM for his owner devices. Sometimes the user wants to use the device as work device (only taxi and couriers apps) and sometimes the user wants to use the device as his own (install games, social apps, and his own Google accounts).
Situation:
The client wants to store his gsuite accounts in FRP storage (to have the ability to unlock a phone in case employee leave organization) but doesn't want an employee to unlock the phone after FR entering his personal account credentials.
Example:
I added two work account programmatically (like described here). But after the user gets the phone he entered his personal Gmail account to use Gmail, other apps. How can I programmatically or maybe from DPC app prevents user recover access to the phone using his personal account after Factory Reset?
I found the answer, finally. The link to the documentation.
I need just to create a bundle with google plus ids of accounts that will have the opportunity to recover device after factory reset.
And after that need to send a broadcast to notify the system that these values were changed.
val bundle = Bundle()
// list of recovery accounts
val recoveryAccounts = arrayOf(
"115273111154663031432",
"110369192556268846321",
)
bundle.putStringArray("factoryResetProtectionAdmin", recoveryAccounts)
mAdminComponentName = DeviceAdminReceiver.getComponentName(context)
// set restrictions
mDevicePolicyManager.setApplicationRestrictions(mAdminComponentName, "com.google.android.gms", bundle)
// send broadcast
val broadcastIntent = Intent("com.google.android.gms.auth.FRP_CONFIG_CHANGED")
broadcastIntent.setPackage("com.google.android.gms")
broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
applicationContext.sendBroadcast(broadcastIntent)
Off topic.
To get the id of recovery accounts try this: https://developers.google.com/people/api/rest/v1/people/get?apix=true&apix_params={"resourceName":"people/me","personFields":"metadata"}
Push "Execute" and login with needed account. It'll be shown in "id" field of response.
Related
I want the users of my app to sign in through a single device only at the same time. How do I achieve this?
You may add device id in Firebase on register and check it on login. You can get the device id as follows:
private String android_id = Secure.getString(
getContext().getContentResolver(), Secure.ANDROID_ID
);
Or you can browse here.
My play store account has over 100 apps published and all of them have this common user generation process which includes OTP verification. Interesting to note is all the apps have same user object with same properties for a particular OTP verified number, which gets stored in the respective SharedPreferences as string.
For better User Experience I would like to trim down the user generation process if there is any one app installed in the device and has done OTP verification. I want to share this user object, which is saved as string in each app's SharedPreferences.
So here's what I want when I install com.domain.app.cX app:
1) com.domain.app.cX -> (Do you have a verified user?) -> com.domain.app.cY
2.1) com.domain.app.cY -> (Yes I have, here is it "user json") -> com.domain.app.cX
or
2.2) com.domain.app.cY -> (No I don't have any user) -> com.domain.app.cX
3) Move to check if com.domain.app.cZ is installed and do over from step 1
Options I have:
1) I have read about ContentProvider and understood that you need to put in a URI of ContentProvider which is package name specific.
2) Use package name with createPackageContext and get SharedPreferences for any app.
In both the solutions I don't know which app is already installed on device and hence URIs of all ContentProvider and package name of the app.
Is there any solution in which I can leverage the signature of the app, since all the app are signed with same certificate.
Using Broadcast receivers and Custom Broadcasts.
with redundant common data across all apps with shared preferences.
All the apps contain a pair of broadcast receiver and sender.
The app which wants verification status will send a broadcast.
The other apps which listen to the broadcast will receive it and add the verification status in the intent and send again as a broadcast.
Now the 1st app which send the broadcast for verification status will receive the latest status and update the UI accordingly. If the default value is false then show the verification screen.
I've been looking for a solution to this problem for a while (days, not minutes), but it eludes me quite effectively.
Please note that this is NOT a question about starting up the registration procedure. This must happen automatically without any user interaction.
I would like to add a Google account to my custom device (1000's of them). The account will mostly be used to activate Google Play store on the device so that the app can update when newer versions are available.
My existing code (the shortest snippet of those I tried):
AccountManager mgr = AccountManager.get(this);
Account acc = new Account("email#gmail.com", "com.google");
mgr.addAccountExplicitly(acc, "password", new Bundle()));
naturally yields a
java.lang.SecurityException: caller uid 10047 is different than the authenticator's uid
So how would I go about actually achieving this? My device is rooted so that's not an obstacle if it's the only way.
It is not possible to add/create a Google account using addAccountExplicitly(). You can only add accounts for your own services. even your device is rooted because it will rejected by Google web server. For more detail check this link
Warning: this solution doesn't work well. See comments for explanation.
Well, as it turns out, this is not something easily solved. I ended up registering one device, then pulled the users file from it. Location of users file : /data/system/users/0/accounts.db (if there are multiple user profiles on the device, the last directory may differ according to profile in question).
I stored this file into my app's assets (gzipped, make sure the extension is not something.gz because that gets lost during packaging - didn't bother checking out why).
First I check if my user already exists:
AccountManager mgr = AccountManager.get(this);
for (Account acc: mgr.getAccountsByType("com.google")) {
if (acc.name.equalsIgnoreCase("email#gmail.com"))
return;
}
If it does, I just skip the step. Otherwise I unpack the users file and overwrite existing one (using su). I then also do a reboot to make sure changes are registered.
i am trying to add google account programmatically to android using a app that takes username and password and logins the user in background. But i m having problem as it is showing error...
Error: Caller uid 10024 is different than authenticator's uid .
I had already included all permissions and authenticator xml but it is not responding...
plz help i want to add google account in backgroundwith one click ..
Thanks in advance..
Account acc = new Account("mygmailid#gmail.com", "com.google");
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");
if (am.addAccountExplicitly(acc, "mypass", userdata)) {
// success message..
}
Basically this would be impossible to do because adding an new google account without the prior information of the user itself would definetely be a kind of malware or theft app.
Therefore according to Google this would lead to violate the user freedom and its trust towards Android operating system.
But you can add new google account and can ask user to enter the password for that account. So there will be no permission violation.
I recently noticed that when a Device Owner application is set, it's not possible to create a restricted profile.
First case : When my device owner app is not set.
From Settings>Users : I can "Add user or Profile", and then choose between a User or a Restricted Profile.
Second case : When my device owner app is set.
From Settings>Users : I can only "Add user", and then i get the confirmation to create a new user. In this second case, it's not possible to create a restricted profile.
I'd like to know why it's not available in this case and how I could possibly create a restricted profile in this case ?
The second part of my question is : how can I programmatically create a restricted profile - or an equivalent behavior - using the existing DevicePolicyManager API (as far as I can see, there's no public API to create restricted profile) ?
UPDATE:
I made a sample app to illustrate this. It's available on Github.
Steps to reproduce :
Compile the app
Upload the application to your device
Set the application as device owner using dpm command line tool: adb shell dpm set-device-owner com.mytest.minimalistdeviceowner/.DeviceAdminRcvr.
Check that the creation of profile is not available in Settings>Users
Unset the application as device owner by clicking, in the app, on "Unset Device Owner".
Check that the creation is now available in Settings>Users
Restricted profiles are not available for tablets with a device owner, or phones. It's shown in the Settings app source code available here :
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
Context.DEVICE_POLICY_SERVICE);
// No restricted profiles for tablets with a device owner, or phones.
if (dpm.getDeviceOwner() != null || Utils.isVoiceCapable(context)) {
mCanAddRestrictedProfile = false;
mAddUser.setTitle(R.string.user_add_user_menu);
}
So that's not a bug, but a functionnality. It's probably disabled to avoid to interfere with your Device Owner App.
You should be aware of that and because you have more power with your Device Owner App, means you’ll have to restrict your user by yourself from this Device Owner App.
To do that, you could use all restrictions API provided through DevicePolicyManager.addUserRestriction(), DevicePolicyManager.setGlobalSetting(), DevicePolicyManager.setSecureSetting() to configure settings, and also DevicePolicyManager.setApplicationHidden() to limit applications access for your user.
Why can't I create a restricted profile when an owner device app is
set?
Probably because the device owner app manages the profiles already. I guess it was easier to do like that without bypassing the device owner app restrictions.
How can I programmatically create a restricted profile?
The method DevicePolicyManager.createAndInitializeUser() can be used to create a managed profile. This profile cannot be managed directly in the settings, but the device owner app can access nearly the same features.
One feature that I cannot find is the ability to share an app from the owner profile to managed one.