What i am looking for, is a way to switch between existing profiles under some specific user, using DevicePolicyManager Class for android lollipop.
I googled it from last two days but doesn't get a way to make it happen. I also looked on some previously asked questions on Stack-overflow and other similar forums but not found anything useful. It would be great for me, if any one can atleast answer me whether am looking for something impossible, or is there some other alternative way to do that, like by calling settings intent or similar.
Also there is method switchUser(ComponentName admin, UserHandle userHandle) in DevicePolicyManager class to switch in between users. But similar is not exist for profiles.
Thank You.
I don't think that is possible. However, I don't understand why you want to switch between profiles. If the managed profile is set up, the app which started the provisioning process is copied to the profile and set as profile owner app. The profile owner app runs then in its own process. You cannot switch from the primary user app to the managed process.
Perhaps you could explain why you want to change to a profile.
Edit:
Definition of Device Owner and Profile Owner:
Is it possible to have a "Profile Owner" app in Android Lollipop that is not co-present
The DeviceOwner example shows how the Device Owner is set up on Android. http://android-developers.blogspot.co.at/2015/04/new-android-code-samples.html
Another good post about provisioning a Device Owner with NFC: Device Owner on Android 5.0 (and others) whitout rooted devices, device provisioning by NFC
You can set a Device Owner using the command line tool dpm:
How to make my app a device owner?
After your app (widget) is Device Owner you can use the method switchUser of the DevicePoliyManager to switch between user profiles. The UserManager provides you with a list of all profiles on the device.
UserManager um = (UserManager) getSystemService(USER_SERVICE);
List<UserHandle> userProfiles = um.getUserProfiles();
Related
We are developing a locked down "kiosk-style" Android app on a stock Samsung tablet, which is mounted in customer vehicles. We would like to be able to allow customers to edit their wifi settings, without giving them access to the rest of the Settings app (e.g. Launcher, accounts, etc)
We have been able to launch the Wifi Settings activity, but it allows the user to go into other areas.
I'm not sure whether it's possible to create a custom interface for connecting to wifi, but even if it were possible, this seems fragile and a lot of work for something quite simple.
Is there any way to solve this well?
I would create a device policy controller app that is provisioned on the device as a device owner using Android Enterprise (Android for Work) APIs.
https://developers.google.com/android/work/dpc/build-dpc
As a device owner, you can set your app in lock task mode which is generally used for kiosks.
https://developer.android.com/work/cosu.html
Then, you can set user restrictions:
addUserRestriction api
user restrictions list
The user restrictions don't cover everything in the settings app, but the coverage is pretty good.
Then I would provision it using NFC or QR code reader from the Google Setup Wizard welcome screen.
https://github.com/googlesamples/android-NfcProvisioning
You might want to also look at existing open source EMM/MDM implementations that already exist such as WSO2.
Other references:
How to enable task locking in Android 5.0 production devices
How to make sure there is only one app
I was also working on Kiosk Type applications and we have to give options for Change wifi and Display Settings So we have used these commands on Button click for Wifi And Display
Settings
btnWifiSetting.setOnClickListener {
startActivityForResult( Intent(android.provider.Settings.ACTION_WIFI_SETTINGS), 0);
}
And For Display Setting
btnDisplay.setOnClickListener {
startActivityForResult(Intent(android.provider.Settings.ACTION_DISPLAY_SETTINGS),0)
}
And you can also check the full list of Available Commands here
https://ourcodeworld.com/articles/read/318/how-to-open-android-settings-programmatically-with-java
try LineAgeOS
https://lineageos.org/
Your requirement needs to access OS System level, this way you have access and customize the WIFI settings before releasing the phone itself
can you try this way.
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
Tools_WiFi.setImageResource(R.drawable.tool_wifi_off);
} else {
wifiManager.setWifiEnabled(true);
Tools_WiFi.setImageResource(R.drawable.tool_wifi_on);
}
You can try this:
startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
Hope it helps you.
Not able to understand WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, which is introduced in Android M. .However the definition in android developer site is very ambiguous.Please anyone clarify about this varible
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN - is the defined user wifi configuration state (true means its locked, false means its changeable).
from android documentation :
http://developer.android.com/reference/android/provider/Settings.Global.html
This setting controls whether WiFi configurations created by a Device
Owner app should be locked down (that is, be editable or removable
only by the Device Owner App, not even by Settings app).
since Marshmallow this configurations have been changed and now are accessible only if you produce your own configuration per application using specific API's.
please refer to Android 6.0 Changes.
https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html
Your apps can now change the state of WifiConfiguration objects only
if you created these objects. You are not permitted to modify or
delete WifiConfiguration objects created by the user or by other apps.
hope it clarifies a bit.
My app is working fine, until Android 5.0.2 doesn't allow third party app to connect to HID device over Bluetooth low energy.
myGatt.setCharacteristicNotification(gattChar, true);
06-01 17:39:35.356: W/BluetoothGatt(21599):
java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission:Neither
user 10157 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
BLUETOOTH_PRIVILEGED permission doesn't work on a third party app. It's only for system or manufacturer apps.
The latest changes from Android note:
Enforce BLUETOOTH_PRIVILEGED permission for HID-over-GATT
https://android.googlesource.com/platform/packages/apps/Bluetooth/+/02bebee
Code snippet:
private static final UUID[] HID_UUIDS = {
UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB") };
if (isHidUuid(charUuid)) enforcePrivilegedPermission();
My question: is there a way to overwrite HID_UUIDS or enforcePrivilegedPermission? Can I use reflection to by pass it?
Every times Android released a new version, it breaks the previous code.
Thanks!
The question is old, but still worth answering.
The HID (and FIDO https://fidoalliance.org/) service is protected and indeed requires system permission source. Only apps signed with the system key may use this service, that is only Bluetooth settings. This is to ensure that 3rd party apps are not able to listen to keys typed on a wireless keyboards, as all notifications and indications are transferred to all BluetoothGatt objects. Without this protection you would be able to connect to a HID device (you still can), enable notifications using gatt.setCharacteristicNotification(.., true) and receive updates whenever a key is typed. With a bit of knowledge about Report characteristics you can then get all the keys and mouse positions, including passwords, etc. So it's not a break, but a bug fix. On KitKat you still may do this.
The only solution is to compile your own AOSP Android version and sign your app with the same key. Otherwise it would be useless protection.
Btw, starting form Android 8 or perhaps earlier you don't get SecurityException. The call just returns true as if any other and you never get any callback.
This might have been changed here: https://android.googlesource.com/platform/packages/apps/Bluetooth/+/32dc7a6b919375aede777f3c821fa316d85449ae%5E%21/#F2
Alright here's the deal. I got two Galaxy Nexus phones both with bluetooth enabled.
I've written a bluetooth connection management app that I use for device discovery and connectivity. It also outputs all the available UUIDs the devices can support.
Looking from http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm the following standard UUIDs are exposed from Galaxy Nexus devices.
0x1116 - NAP
0x112f - PBAP (Phonebook Access Profile)
0x111f - HFP (Hands free)
0x1105 - OPP (Object Push Profile)
0x1112 - HSP (Headset Profile)
0x110c - AVRCP
0x110a - A2DP
I am trying to connect via the OPP profile (UUID 00001105-0000-1000-8000-00805F9B34FB) and push objects (files) between the devices. I've gone though the entire Android API documentation on how to discover, pair/bond (threading etc.) and manage all bluetooth connections. I've managed to successfully connect and talk to a legacy board device via the SPP (0x1101) profile.
However, when I try to use socket.connect() between the two galaxy nexus phones, the pairing dialog shows up and I click Pair button on both devices. After that, I immediately get a Connection Refused IOException. Note that after pairing has occurred once I never get asked again which makes sense since the secure link is cached.
If I can't connect to these standard profiles using these standard UUIDs why are they exposed? How can I connect from my app to any of these profiles and interact with them? Is it because my app is not somehow trusted? What's weird is that even the Share functionality on Android does not work at all either. Is this something completely broken on Android?
Please avoid giving me hints to use the "well known UUID SPP one 0x1101" like the docs say. This is not what I want. I have a fairly good understanding of how this stuff works and I am looking for a real solution or explanation of the problem.
I've seen the typical "reflection" solution but I do not understand why is this still a problem on Android? Why do people use reflection to make this work? Can we file a bug on Android to fix this?
If those UUIDs are standard any app should be able to connect and interact with them. Why is this an issue and why do I get this exception?
Thanks in advance.
UPDATE
So for some reason the object push in the Android system started working. I actually attempted to connect via my app and it was not working. Then, I went to the Contacts app and tried to share a contact which magically worked. Then, I went back to my app and it now it works...wow. That is very weird and there must be an explanation to this.
I ran into this same issue and managed to find a solution that worked for me.
In my case I using three different test devices (Nexus 5, Galaxy S4, Note 2) and for some reason, the Note 2 wouldn't connect to my Bluetooth module yet the other two would.
The reasoning I've found is that Bluetooth drivers vary, and slightly different connection methods are needed to create a connection between different devices.
The three methods I use are called 'Secure', 'Insecure' and 'Reflection method'/'hax'.
switch(connType)
{
case Secure:
tmpSocket = device.createRfcommSocketToServiceRecord(_uuid);
break;
case Insecure:
tmpSocket = device.createInsecureRfcommSocketToServiceRecord(_uuid);
break;
case Hax:
Method createSocket = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmpSocket = (BluetoothSocket)createSocket.invoke(device, Integer.valueOf(1));
break;
}
In my case, the Secure mode worked for both the Nexus 5 and Galaxy S4 however it didn't work for the Note 2.
After some testing I discovered the Note 2 only works using 'Insecure' mode, so to cater to this, I basically attempt a connection and cycle through the different modes if necessary. When attempting a different connection mode I simply prompt 'retrying connection'. So, if the connection fails using secure, then I will attempt using Insecure and then using the reflection method.
I haven't run into the case where one of these three methods haven't worked.
Have you tried using a nonstandard profile? i.e. a custom UUID just for your app. This will also help you know your are (most likely) only connecting to your own app rather than some other app that is registered with the same profile.
From my experience, Bluetooth pairing is very buggy for the first pair attempt. However, using a custom UUID helps this somewhat.
The reflection method (I think) was originally an attempt to fix a bug with a specific device, however I think some people found success in using it elsewhere as well. The device was called the Spica or something similar.
As one of the comments also posted, I would also try connecting again after failing.
Basically write code that plans to fail the first attempt, but then the code tries to connect again in 5 seconds if there was a failure.
These are imperfect solutions but Bluetooth implementation on Android is also imperfect (IMHO). Hope that helps
EDIT
Based on the question update and comments:
I agree something is definitely buggy. Part of the problem I think is the BT drivers vary and each has a different BT stack with different quirks. I also found a question that makes use of both the reflection method AND custom UUID, AND other standard methods. This seems extreme to me but it does cover the most ground. Unfortunately as app developers we have no control over the low level stack/code/drivers.
I have found with my two Bluetooth sharing apps that the first pairing is always tricky.
I'm glad to know it's not just me.
I'm trying (wondering if it's even possible) to write an app, that would change the network selection mode automatically, based on some criteria. E.g. change the network operator from Vodafone to T-Mobile (assuming that the SIM card registration will succeed, but I'm not worried about it atm)
Unfortunately, I can't seem to find any way in the API to do it. Anyone has any idea?
I assume, since it's not in the public APIs, there might still be a way to do it, if the phone is rooted. Is that true? If so, where should I look?
Thanks in advance
Sorry but you can't.
You can have a look into the TelephonyManager .
You can know the current operator: getSimOperator(Name) / getNetworkOperator(Name).
You can also check this thread saying "I learn that for the sake of security there aren't any public APIs to manage this so the only option is to send the user to the system PreferenceScreen within my app."
How about using android.telephony.CarrierConfigManager? I read about it on https://developer.android.com/reference/android/telephony/CarrierConfigManager.html and it seems to allow you to change alot of carrier-specific parameters, although the app must be signed with the certificate that has a matching signature to one on the SIM, so it can usually only be implemented by the carrier issuing the SIM. See also https://source.android.com/devices/tech/config/carrier.
I havent found an actual method to actively switch carrier, but if anywhere, I'd expect it to be there.