Merge "Sample app for Android U lesson: Building apps for enterprise - Device administration." into ics-mr0
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.training.deviceadmin"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="8"
|
||||||
|
android:targetSdkVersion="14" />
|
||||||
|
|
||||||
|
<application android:label="@string/app_name">
|
||||||
|
<activity android:name=".PolicySetupActivity" android:label="@string/app_name">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name="com.example.training.deviceadmin.SecureActivity"
|
||||||
|
android:label="@string/app_name"/>
|
||||||
|
<receiver android:name="com.example.training.deviceadmin.Policy$PolicyAdmin"
|
||||||
|
android:label="@string/app_policy_admin_name"
|
||||||
|
android:permission="android.permission.BIND_DEVICE_ADMIN">
|
||||||
|
<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>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
3
samples/training/device-management-policy/_index.html
Executable file
3
samples/training/device-management-policy/_index.html
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
<p>This is a security-aware sample application that demonstrates the enforcement of device administration policies on Android 2.2 or above platforms.</p>
|
||||||
|
|
||||||
|
<p>Refer to the <a href="/training/enterprise/device-management-policy.html" />Enhancing Security with Device Management Policies</a> class for detail.
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ScrollView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" >
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/top_padding"
|
||||||
|
android:paddingLeft="@dimen/side_padding"
|
||||||
|
android:paddingRight="@dimen/side_padding" >
|
||||||
|
<TextView android:id="@+id/policy_instructions"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/setup_policy_instruction"
|
||||||
|
android:textSize="@dimen/text_size_medium" />
|
||||||
|
<!-- Password type -->
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/setup_password_quality"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<Spinner android:id="@+id/policy_password_quality"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:prompt="@string/setup_password_quality"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:focusable="true" >
|
||||||
|
<requestFocus/>
|
||||||
|
</Spinner>
|
||||||
|
<!-- Minimum password length -->
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/setup_password_length"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<EditText android:id="@+id/policy_password_length"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:hint="@string/setup_password_length"
|
||||||
|
android:inputType="number" />
|
||||||
|
<!-- Minimum password uppercase characters -->
|
||||||
|
<LinearLayout android:id="@+id/password_uppercase_view"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone" >
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/setup_password_uppercase"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<EditText android:id="@+id/policy_password_uppercase"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:hint="@string/setup_password_uppercase"
|
||||||
|
android:inputType="number" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<TextView android:id="@+id/setup_message"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingLeft="@dimen/side_padding"
|
||||||
|
android:paddingRight="@dimen/side_padding" />
|
||||||
|
<Button android:id="@+id/setup_action_btn"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:minWidth="200dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginBottom="@dimen/top_padding" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:text="@string/secure_message"
|
||||||
|
android:textSize="@dimen/text_size_large"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:gravity="center_vertical|center_horizontal" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ScrollView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" >
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/top_padding"
|
||||||
|
android:paddingLeft="@dimen/side_padding"
|
||||||
|
android:paddingRight="@dimen/side_padding" >
|
||||||
|
<TextView android:id="@+id/policy_instructions"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_policy_instruction"
|
||||||
|
android:textSize="@dimen/text_size_medium" />
|
||||||
|
<!-- Password type -->
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_password_quality"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<TextView android:id="@+id/policy_password_quality"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:paddingLeft="3dp" />
|
||||||
|
<!-- Minimum password length -->
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_password_length"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<TextView android:id="@+id/policy_password_length"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:paddingLeft="3dp" />
|
||||||
|
<!-- Minimum password uppercase characters -->
|
||||||
|
<LinearLayout android:id="@+id/password_uppercase_view"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone" >
|
||||||
|
<TextView android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_password_uppercase"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:paddingTop="3dp" />
|
||||||
|
<TextView android:id="@+id/policy_password_uppercase"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:paddingLeft="3dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<TextView android:id="@+id/setup_message"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingLeft="@dimen/side_padding"
|
||||||
|
android:paddingRight="@dimen/side_padding" />
|
||||||
|
<Button android:id="@+id/setup_action_btn"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:minWidth="200dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginBottom="@dimen/top_padding" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string-array name="password_types">
|
||||||
|
<item>Anything</item>
|
||||||
|
<item>Something</item>
|
||||||
|
<item>Numeric</item>
|
||||||
|
<item>Alphabetic</item>
|
||||||
|
<item>Alphanumeric</item>
|
||||||
|
<item>Complex</item>
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<!-- UI elements -->
|
||||||
|
<dimen name="top_padding">60dp</dimen>
|
||||||
|
<dimen name="side_padding">100dp</dimen>
|
||||||
|
|
||||||
|
<!-- body content -->
|
||||||
|
<dimen name="text_size_small">18sp</dimen>
|
||||||
|
<dimen name="text_size_medium">24sp</dimen>
|
||||||
|
<dimen name="text_size_large">26sp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string-array name="password_types">
|
||||||
|
<item>Anything</item>
|
||||||
|
<item>Something</item>
|
||||||
|
<item>Numeric</item>
|
||||||
|
<item>Alphabetic</item>
|
||||||
|
<item>Alphanumeric</item>
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<declare-styleable name="AppTheme">
|
||||||
|
<attr name="actionbarCompatTitleStyle" format="reference" />
|
||||||
|
<attr name="actionbarCompatButtonStyle" format="reference" />
|
||||||
|
<attr name="actionbarCompatButtonHomeStyle" format="reference" />
|
||||||
|
<attr name="actionbarCompatProgressIndicatorStyle" format="reference" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
<!-- Mostly taken from frameworks/base.git/core/res/res/values/attrs.xml -->
|
||||||
|
<declare-styleable name="TextAppearance">
|
||||||
|
<attr name="textColor" format="color" />
|
||||||
|
<attr name="textSize" format="dimension" />
|
||||||
|
|
||||||
|
<attr name="textStyle">
|
||||||
|
<flag name="normal" value="0" />
|
||||||
|
<flag name="bold" value="1" />
|
||||||
|
<flag name="italic" value="2" />
|
||||||
|
</attr>
|
||||||
|
|
||||||
|
<attr name="typeface">
|
||||||
|
<enum name="normal" value="0" />
|
||||||
|
<enum name="sans" value="1" />
|
||||||
|
<enum name="serif" value="2" />
|
||||||
|
<enum name="monospace" value="3" />
|
||||||
|
</attr>
|
||||||
|
|
||||||
|
<attr name="shadowRadius" format="float" />
|
||||||
|
<attr name="shadowDx" format="float" />
|
||||||
|
<attr name="shadowDy" format="float" />
|
||||||
|
<attr name="shadowColor" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<color name="accent_1">#224894</color>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<!-- UI elements -->
|
||||||
|
<dimen name="top_padding">10dp</dimen>
|
||||||
|
<dimen name="side_padding">5dp</dimen>
|
||||||
|
|
||||||
|
<!-- body content -->
|
||||||
|
<dimen name="text_size_small">14sp</dimen>
|
||||||
|
<dimen name="text_size_medium">18sp</dimen>
|
||||||
|
<dimen name="text_size_large">20sp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2011 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Device Admin Lesson</string>
|
||||||
|
<string name="app_policy_admin_name">Policy Admin Receiver</string>
|
||||||
|
|
||||||
|
<!-- Setup activity -->
|
||||||
|
<string name="setup_policy_instruction">Set up device administration policy:</string>
|
||||||
|
<string name="setup_password_quality">Select a password quality</string>
|
||||||
|
<string name="setup_password_length">Set min. pw. length</string>
|
||||||
|
<string name="setup_password_uppercase">Set min. pw. uppercase</string>
|
||||||
|
<string name="setup_action_activate">Activate</string>
|
||||||
|
<string name="setup_message_activate">Press button to activate the device administrator</string>
|
||||||
|
<string name="setup_action_set_policy">Enforce Policy</string>
|
||||||
|
<string name="setup_message_set_policy">Press button to enforce specified policy.</string>
|
||||||
|
<string name="setup_action_enforce_policy">Update Password</string>
|
||||||
|
<string name="setup_message_enforce_policy">Current password doesn\'t conform to the policy.\nPress button to update password.</string>
|
||||||
|
<string name="setup_action_go_secured">Go</string>
|
||||||
|
<string name="setup_message_go_secured">Current password conforms to policy. Device is protected.\nPress button to access secured content.</string>
|
||||||
|
|
||||||
|
<!-- View policy activity -->
|
||||||
|
<string name="view_policy_instruction">Review device administration policy:</string>
|
||||||
|
<string name="view_password_quality">Password quality:</string>
|
||||||
|
<string name="view_password_length">Minimum password length:</string>
|
||||||
|
<string name="view_password_uppercase">Minimum password upper case:</string>
|
||||||
|
|
||||||
|
<string name="secure_message">Device is properly secured. Access is granted to secured content</string>
|
||||||
|
<string name="device_admin_activation_message">Provide a message here explaining why an application needs to become a device administrator.</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-policies>
|
||||||
|
<limit-password />
|
||||||
|
</uses-policies>
|
||||||
|
</device-admin>
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.training.deviceadmin;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.admin.DeviceAdminReceiver;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
public class Policy {
|
||||||
|
public static final int REQUEST_ADD_DEVICE_ADMIN = 1;
|
||||||
|
|
||||||
|
private static final String APP_PREF = "APP_PREF";
|
||||||
|
private static final String KEY_PASSWORD_LENGTH = "PW_LENGTH";
|
||||||
|
private static final String KEY_PASSWORD_QUALITY = "PW_QUALITY";
|
||||||
|
private static final String KEY_PASSWORD_MIN_UPPERCASE = "PW_MIN_UPPERCASE";
|
||||||
|
|
||||||
|
// Password quality values. This list must match the list
|
||||||
|
// found in res/values/arrays.xml
|
||||||
|
final static int[] PASSWORD_QUALITY_VALUES = new int[] {
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
|
||||||
|
};
|
||||||
|
|
||||||
|
private int mPasswordQuality;
|
||||||
|
private int mPasswordLength;
|
||||||
|
private int mPasswordMinUpperCase;
|
||||||
|
private Context mContext;
|
||||||
|
private DevicePolicyManager mDPM;
|
||||||
|
private ComponentName mPolicyAdmin;
|
||||||
|
|
||||||
|
public Policy(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mPasswordQuality = -1;
|
||||||
|
mPasswordLength = 0;
|
||||||
|
mPasswordMinUpperCase = 0;
|
||||||
|
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
mPolicyAdmin = new ComponentName(context, PolicyAdmin.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the policy parameters.
|
||||||
|
*
|
||||||
|
* @param passwordQuality Password quality.
|
||||||
|
* @param passwordLength Password minimum length.
|
||||||
|
* @param passwordUppercase Password minimum number of upper case alphabets.
|
||||||
|
*/
|
||||||
|
public void saveToLocal(int passwordQuality, int passwordLength, int passwordMinUppercase) {
|
||||||
|
SharedPreferences.Editor editor =
|
||||||
|
mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE).edit();
|
||||||
|
if (mPasswordQuality != passwordQuality) {
|
||||||
|
editor.putInt(KEY_PASSWORD_QUALITY, passwordQuality);
|
||||||
|
mPasswordQuality = passwordQuality;
|
||||||
|
}
|
||||||
|
if (mPasswordLength != passwordLength) {
|
||||||
|
editor.putInt(KEY_PASSWORD_LENGTH, passwordLength);
|
||||||
|
mPasswordLength = passwordLength;
|
||||||
|
}
|
||||||
|
if (mPasswordMinUpperCase != passwordMinUppercase) {
|
||||||
|
editor.putInt(KEY_PASSWORD_MIN_UPPERCASE, passwordMinUppercase);
|
||||||
|
mPasswordMinUpperCase = passwordMinUppercase;
|
||||||
|
}
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFromLocal() {
|
||||||
|
SharedPreferences prefs = mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE);
|
||||||
|
mPasswordQuality = prefs.getInt(KEY_PASSWORD_QUALITY, -1);
|
||||||
|
mPasswordLength = prefs.getInt(KEY_PASSWORD_LENGTH, -1);
|
||||||
|
mPasswordMinUpperCase = prefs.getInt(KEY_PASSWORD_MIN_UPPERCASE, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for password quality.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getPasswordQuality() { return mPasswordQuality; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for password length.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getPasswordLength() { return mPasswordLength; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for password minimum upper case alphabets.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getPasswordMinUpperCase() { return mPasswordMinUpperCase; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the policy administrator ComponentName object.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ComponentName getPolicyAdmin() { return mPolicyAdmin; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the device administrator is currently active.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isAdminActive() {
|
||||||
|
return mDPM.isAdminActive(mPolicyAdmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActivePasswordSufficient() {
|
||||||
|
return mDPM.isActivePasswordSufficient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeviceSecured() {
|
||||||
|
return isAdminActive() && isActivePasswordSufficient();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure policy defined in the object.
|
||||||
|
*/
|
||||||
|
public void configurePolicy() {
|
||||||
|
mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]);
|
||||||
|
mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||||
|
mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Through the PolicyAdmin receiver, the app can use this to trap various device
|
||||||
|
* administration events, such as password change, incorrect password entry, etc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class PolicyAdmin extends DeviceAdminReceiver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisabled(Context context, Intent intent) {
|
||||||
|
// Called when the app is about to be deactivated as a device administrator.
|
||||||
|
// Deletes previously stored password policy.
|
||||||
|
super.onDisabled(context, intent);
|
||||||
|
SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
|
||||||
|
prefs.edit().clear().commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.training.deviceadmin;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main Activity for the sample application.
|
||||||
|
*
|
||||||
|
* The Activity maintains and presents 2 different
|
||||||
|
* screens to the user -- a screen for configuring device administration policy and another screen
|
||||||
|
* for viewing configured policy. When it is detected that the screen-lock password satisfies
|
||||||
|
* the password strength required by the policy, the user is sent to an Activity containing
|
||||||
|
* protected content.
|
||||||
|
*/
|
||||||
|
public class PolicySetupActivity extends Activity {
|
||||||
|
private static final int REQ_ACTIVATE_DEVICE_ADMIN = 10;
|
||||||
|
private static final String SCREEN_ID_KEY = "LAYOUT_ID";
|
||||||
|
|
||||||
|
private static final String APP_PREF = "APP_PREF";
|
||||||
|
private static final int UNKNOWN_SCREEN_ID = -1;
|
||||||
|
|
||||||
|
// UI controls in policy setup screen.
|
||||||
|
private Spinner mPasswordQualityInputField;
|
||||||
|
private EditText mPasswordLengthInputField;
|
||||||
|
private EditText mPasswordMinUppercaseInputField;
|
||||||
|
|
||||||
|
private Policy mPolicy;
|
||||||
|
private int mCurrentScreenId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
mPolicy = new Policy(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
SharedPreferences prefs = getSharedPreferences(APP_PREF, MODE_PRIVATE);
|
||||||
|
final int savedScreenId = prefs.getInt(SCREEN_ID_KEY, UNKNOWN_SCREEN_ID);
|
||||||
|
if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) {
|
||||||
|
setScreenContent(R.layout.activity_policy_setup);
|
||||||
|
} else {
|
||||||
|
setScreenContent(savedScreenId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setScreenContent(final int screenId) {
|
||||||
|
mCurrentScreenId = screenId;
|
||||||
|
setContentView(mCurrentScreenId);
|
||||||
|
getSharedPreferences(APP_PREF, MODE_PRIVATE).edit().putInt(
|
||||||
|
SCREEN_ID_KEY, mCurrentScreenId).commit();
|
||||||
|
switch (mCurrentScreenId) {
|
||||||
|
case R.layout.activity_policy_setup:
|
||||||
|
initPolicySetupScreen();
|
||||||
|
initNavigation();
|
||||||
|
break;
|
||||||
|
case R.layout.activity_view_policy:
|
||||||
|
initViewPolicyScreen();
|
||||||
|
initNavigation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN && resultCode == RESULT_OK) {
|
||||||
|
// User just activated the application as a device administrator.
|
||||||
|
setScreenContent(mCurrentScreenId);
|
||||||
|
} else {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (mCurrentScreenId == R.layout.activity_view_policy) {
|
||||||
|
setScreenContent(R.layout.activity_policy_setup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize policy set up screen.
|
||||||
|
private void initPolicySetupScreen() {
|
||||||
|
mPasswordQualityInputField = (Spinner) findViewById(R.id.policy_password_quality);
|
||||||
|
mPasswordLengthInputField = (EditText) findViewById(R.id.policy_password_length);
|
||||||
|
mPasswordMinUppercaseInputField = (EditText) findViewById(R.id.policy_password_uppercase);
|
||||||
|
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
|
||||||
|
R.array.password_types, android.R.layout.simple_spinner_item);
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
mPasswordQualityInputField.setAdapter(adapter);
|
||||||
|
mPasswordQualityInputField.setOnItemSelectedListener(
|
||||||
|
new AdapterView.OnItemSelectedListener() {
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||||
|
LinearLayout passwordMinUppercaseView =
|
||||||
|
(LinearLayout) findViewById(R.id.password_uppercase_view);
|
||||||
|
// The minimum number of upper case field is only applicable for password
|
||||||
|
// qualities: alpha, alphanumeric, or complex.
|
||||||
|
if (pos > 2)
|
||||||
|
passwordMinUppercaseView.setVisibility(View.VISIBLE);
|
||||||
|
else
|
||||||
|
passwordMinUppercaseView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Read previously saved policy and populate on the UI.
|
||||||
|
mPolicy.readFromLocal();
|
||||||
|
mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality());
|
||||||
|
if (mPolicy.getPasswordLength() > 0) {
|
||||||
|
mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength()));
|
||||||
|
} else {
|
||||||
|
mPasswordLengthInputField.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPolicy.getPasswordMinUpperCase() > 0) {
|
||||||
|
mPasswordMinUppercaseInputField.setText(
|
||||||
|
String.valueOf(mPolicy.getPasswordMinUpperCase()));
|
||||||
|
} else {
|
||||||
|
mPasswordMinUppercaseInputField.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize policy viewing screen.
|
||||||
|
private void initViewPolicyScreen() {
|
||||||
|
TextView passwordQualityView = (TextView) findViewById(R.id.policy_password_quality);
|
||||||
|
TextView passwordLengthView = (TextView) findViewById(R.id.policy_password_length);
|
||||||
|
|
||||||
|
// Read previously saved policy and populate on the UI.
|
||||||
|
mPolicy.readFromLocal();
|
||||||
|
int passwordQualitySelection = mPolicy.getPasswordQuality();
|
||||||
|
passwordQualityView.setText(
|
||||||
|
getResources().getStringArray(R.array.password_types)[passwordQualitySelection]);
|
||||||
|
passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength()));
|
||||||
|
if (passwordQualitySelection > 2) {
|
||||||
|
LinearLayout passwordMinUppercaseView =
|
||||||
|
(LinearLayout) findViewById(R.id.password_uppercase_view);
|
||||||
|
passwordMinUppercaseView.setVisibility(View.VISIBLE);
|
||||||
|
((TextView) findViewById(R.id.policy_password_uppercase)).setText(
|
||||||
|
String.valueOf(mPolicy.getPasswordMinUpperCase()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up navigation message and action button.
|
||||||
|
private void initNavigation() {
|
||||||
|
if (!mPolicy.isAdminActive()) {
|
||||||
|
// Activates device administrator.
|
||||||
|
setupNavigation(R.string.setup_message_activate,
|
||||||
|
R.string.setup_action_activate,
|
||||||
|
mActivateButtonListener);
|
||||||
|
} else if (mCurrentScreenId == R.layout.activity_policy_setup) {
|
||||||
|
setupNavigation(R.string.setup_message_set_policy,
|
||||||
|
R.string.setup_action_set_policy,
|
||||||
|
new View.OnClickListener() {
|
||||||
|
public void onClick(View view) {
|
||||||
|
writePolicy();
|
||||||
|
mPolicy.configurePolicy();
|
||||||
|
setScreenContent(R.layout.activity_view_policy);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (!mPolicy.isActivePasswordSufficient()) {
|
||||||
|
// Launches password set-up screen in Settings.
|
||||||
|
setupNavigation(R.string.setup_message_enforce_policy,
|
||||||
|
R.string.setup_action_enforce_policy,
|
||||||
|
mEnforcePolicyListener);
|
||||||
|
} else {
|
||||||
|
// Grants access to secure content.
|
||||||
|
setupNavigation(R.string.setup_message_go_secured,
|
||||||
|
R.string.setup_action_go_secured,
|
||||||
|
new View.OnClickListener() {
|
||||||
|
public void onClick(View view) {
|
||||||
|
startActivity(new Intent(view.getContext(), SecureActivity.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private View.OnClickListener mActivateButtonListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// First, persist the policy. Then, launch intent to trigger the system screen
|
||||||
|
// requesting user to confirm the activation of the device administrator.
|
||||||
|
writePolicy();
|
||||||
|
Intent activateDeviceAdminIntent =
|
||||||
|
new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
|
||||||
|
activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
|
||||||
|
mPolicy.getPolicyAdmin());
|
||||||
|
// It is good practice to include the optional explanation text to explain to
|
||||||
|
// user why the application is requesting to be a device administrator. The system
|
||||||
|
// will display this message on the activation screen.
|
||||||
|
activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
|
||||||
|
getResources().getString(R.string.device_admin_activation_message));
|
||||||
|
startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private View.OnClickListener mEnforcePolicyListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
writePolicy();
|
||||||
|
// The device administration API does not "fix" the password if it is
|
||||||
|
// determined that the current password does not conform to what is requested
|
||||||
|
// by the policy. The caller is responsible for triggering the password set up
|
||||||
|
// screen via the below intent.
|
||||||
|
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup action button text and listener.
|
||||||
|
private void setupNavigation(int messageResId, int buttonTextResId,
|
||||||
|
View.OnClickListener listener) {
|
||||||
|
TextView setupMessage = (TextView) findViewById(R.id.setup_message);
|
||||||
|
setupMessage.setText(messageResId);
|
||||||
|
Button actionBtn = (Button) findViewById(R.id.setup_action_btn);
|
||||||
|
actionBtn.setText(buttonTextResId);
|
||||||
|
actionBtn.setOnClickListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save policy to shared preferences.
|
||||||
|
private void writePolicy() {
|
||||||
|
int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId();
|
||||||
|
|
||||||
|
int passwordLength = 0;
|
||||||
|
try {
|
||||||
|
passwordLength = Integer.valueOf(mPasswordLengthInputField.getText().toString());
|
||||||
|
} catch (NumberFormatException nfe) {} // Defaults to 0.
|
||||||
|
|
||||||
|
int passwordMinUppercase = 0;
|
||||||
|
try {
|
||||||
|
passwordMinUppercase =
|
||||||
|
Integer.valueOf(mPasswordMinUppercaseInputField.getText().toString());
|
||||||
|
} catch (NumberFormatException nfe) {} // Defaults to 0.
|
||||||
|
|
||||||
|
mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.training.deviceadmin;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
public class SecureActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
// Check to see if the device is properly secured as per the policy. Send user
|
||||||
|
// back to policy set up screen if necessary.
|
||||||
|
Policy policy = new Policy(this);
|
||||||
|
policy.readFromLocal();
|
||||||
|
if (!policy.isDeviceSecured()) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setClass(this, PolicySetupActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP |
|
||||||
|
Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
setContentView(R.layout.activity_secure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user