B4A Library Device Administrator library

Status
Not open for further replies.
Starting from Android 2.2 (api level 8), Android allows application to be registered as administrators.
Administrator apps have the following special features:
- Manually lock the screen
- Set the minimum password length and quality
- Wipe the entire device
- Set the maximum allowed time before the device locks
- Request the user to change password
- Manually set a new password
- Disable the camera
- Track password changes
- Some other security features as described here.

Note that the password is the screen lock password (other passwords are not affected).

The user needs to enable the admin app before it can have any special privileges.
This is done either by calling Manager.Enable or from the Security settings page.
The user will see a message with the policies that this app requests:

SS-2012-07-02_17.35.01.png


The user can always disable an administrator app from the Security settings page. The idea is that in your app you should check whether the admin is enabled and the password meets the requirements. If they don't then you do not give access to some resource such as the company's server.

How to
A working example is attached to this project. It is recommended to start with it.
Add the following code to the manifest editor:

B4X:
AddApplicationText(<receiver android:name="anywheresoftware.b4a.objects.AdminReceiver2"
  android:permission="android.permission.BIND_DEVICE_ADMIN"
  android:exported="true">
  <meta-data android:name="android.app.device_admin"
  android:resource="@xml/device_admin" />
  <intent-filter>
  <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
  </intent-filter>
</receiver>)

CreateResource(xml, device_admin.xml,
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
  <limit-password />
  <reset-password />
  <force-lock />
  </uses-policies>
</device-admin>
)

3. Declare an AdminManager object. With this object you can ask the user to enable the admin app and access the special privileges.

4. (optional) Add a service named ManagerService. This service will allow you to track password changes and changes to the admin app enabled status. See the attached example.


The latest version of this library is included in the IDE.

Upgrading from v1.00

The receiver name has changed. You need to update the manifest editor code.
The user will probably need to re-enable the admin app. V1.00 library is attached to allow developers to keep the previous version if prefered.
 

Attachments

  • Administrator1.00.zip
    4.8 KB · Views: 1,107
  • AdminExample.zip
    8.2 KB · Views: 168
Last edited:

hursta

Member
Licensed User
Longtime User
Erel, maybe with this built-in policy I can do the same, but how can I code this in b4a?

public void setMaximumFailedPasswordsForWipe (ComponentName admin, int num)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can use this reflection code:
B4X:
Dim r As Reflector
r.Target = Admin
Dim rec As Object = r.GetField("rec")
Dim dm As Object = r.GetField("dm")
r.Target = dm
r.RunMethod4("setMaximumFailedPasswordsForWipe", Array As Object(rec, numberOfFailedPasswords), _
   Array As String("android.content.ComponentName", "java.lang.int")
 

hursta

Member
Licensed User
Longtime User
How can I encrypt my mobile device (same as "Settings -> Encrypt phone")?
When I use setStorageEncryption nothing will be encrypted and I do not see any error message. I will be sure that all my Exchange/ActiveSync and user data is saved encrypted.

Thanks.


B4X:
If manager.Enabled = True Then
    Dim r As Reflector
    r.Target = manager
    Dim rec As Object = r.GetField("rec")
    Dim dm As Object = r.GetField("dm")
    r.Target = dm
    r.RunMethod4("setStorageEncryption", Array As Object(rec, True), Array As String("android.content.ComponentName", "java.lang.boolean"))
End If
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can get the value with reflection:
B4X:
    Dim r As Reflector
    r.Target = manager
    Dim rec As Object = r.GetField("rec")
    Dim dm As Object = r.GetField("dm")
    r.Target = dm
    Log(r.RunMethod4("getMaximumToLock", Array As Object(rec), Array As String("android.content.ComponentName")))
End If

Please start a new thread about the second question.
 

aeropic

Active Member
Licensed User
Longtime User
You can get the value with reflection:


Hi Erel,

I have tested this code
B4X:
  If manager.Enabled = False Then
     manager.Enable("Please enable in order to get access to the secured server.")
  End If
  If manager.Enabled = True Then
       Dim rr As Reflector
       rr.Target = manager
     Dim rec As Object = rr.GetField("rec")
       Dim dm As Object = rr.GetField("dm")
     rr.Target = dm
     Log(rr.RunMethod4("getMaximumToLock", Array As Object(rec), Array As String("android.content.ComponentName")))
   End If
End If

Everything works almost fine .
The App connects as admin and checks for security rules
But just after the codes stops on the Log line


And I get an error :
B4X:
main_bt_wifi_click (B4A line: 122)
Log(rr.RunMethod4("getMaximumToLock", Array As Object(rec), Array As String("android.content.ComponentName")))
java.lang.NoSuchMethodException: getMaximumToLock [class android.content.ComponentName]
   at java.lang.Class.getConstructorOrMethod(Class.java:472)
   at java.lang.Class.getDeclaredMethod(Class.java:640)
   at anywheresoftware.b4a.agraham.reflection.Reflection.runmethod(Reflection.java:214)
   at anywheresoftware.b4a.agraham.reflection.Reflection.RunMethod4(Reflection.java:857)
   at anywheresoftware.b4a.samples.homewidgets.main._bt_wifi_click(main.java:447)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
   at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:63)
   at android.view.View.performClick(View.java:4438)
   at android.view.View$PerformClick.run(View.java:18422)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:136)
   at android.app.ActivityThread.main(ActivityThread.java:5017)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.NoSuchMethodException: getMaximumToLock [class android.content.ComponentName]


It seems that the getMaximumToLock method doesn't exist
I am running it on a Nexus5 with kitkat 4.4.2
Should I check with a Galaxy S3 4.2 version ?


Thank you again for your precious help
 

aeropic

Active Member
Licensed User
Longtime User
It doesn't crash now but gives always 0 instead of the right value :(

Alain

Well this site gives more explanations : http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#getMaximumTimeToLock(android.content.ComponentName)

It seems that there is an admin parameter missing.
I probably get my own process admin value which was not set (so "no restriction")
What I wanted to see is the strongest policy that is "the max time t unlock for all admins"

It seems that I have to pass the admin parameter to "Null" but I don't know how to do it !


public long getMaximumTimeToLock (ComponentName admin)
Added in API level 8
Retrieve the current maximum time to unlock for all admins or a particular one.

Parameters
admin The name of the admin component to check, or null to aggregate all admins.
 
Last edited:

aeropic

Active Member
Licensed User
Longtime User
Just change rec to Null.

Erel you are a genius !

It seems to work as now I get the answer 300000.
300000 is 300s = 5 minutes which is exactly the settings of my mail policy (the strongest admin policy on my phone)

However I have now another question...
On my Nexus5 in the security screen I can only setup the timetolock up to 2min (and the screen lock is set to 1 min).
It should be 4 min according that the max time out is shared between screen and lock... (which is the case with my Samsung S3)

Any idea why a different behavior between S3 and kitkat ?

Another question (I hope the last one !) do you know where is stored the current value selected by the user (on the attached picture "2 min" value) ?
And do you know if there is a way to programmatically read and set it ?

thanks
Alain
 

Attachments

  • Screenshot_2013-12-16-22-45-38[1].png
    Screenshot_2013-12-16-22-45-38[1].png
    160.9 KB · Views: 303

yk1012001

New Member
Licensed User
Longtime User
Can you tell me the error , when I use code below:
'------------------------------------------------------------------
'Disable the cameraDim r AsReflector
r.Target = AdminDim cm AsObject
cm = r.GetField("rec")
r.Target = r.GetField("dm")
r.RunMethod4("setCameraDisabled", ArrayAsObject(cm, True), _ArrayAsString("android.content.ComponentName", "java.lang.boolean") 'change to False to enable camera
'------------------------------------------------------------------
but it show Error description: Undeclared variable 'admin' is used before it was assigned any value.
Occurred on line: 44
r.Target = admin
 
Status
Not open for further replies.
Top