diff options
author | Yuichi Araki <yaraki@google.com> | 2015-01-19 14:51:32 +0900 |
---|---|---|
committer | Yuichi Araki <yaraki@google.com> | 2015-03-24 17:57:57 +0900 |
commit | 801f6992d533f888b51aad8b99d017246e273fbf (patch) | |
tree | 966ee688187beace5ef3f2c3da213e8956ab51a3 | |
parent | 72a5ab0293b66c4ce48b6465fa0db5320db446af (diff) | |
download | android-801f6992d533f888b51aad8b99d017246e273fbf.tar.gz |
DeviceOwner: Add a new sample
This sample demonstrates device owner feature of Android for Work.
Change-Id: I5cb35e2be8a115e8187d0d90180be5ecdb58c03e
28 files changed, 1234 insertions, 0 deletions
diff --git a/admin/DeviceOwner/Application/.gitignore b/admin/DeviceOwner/Application/.gitignore new file mode 100644 index 00000000..1bac3a5f --- /dev/null +++ b/admin/DeviceOwner/Application/.gitignore @@ -0,0 +1,16 @@ +# Copyright 2015 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. +src/template/ +src/common/ +build.gradle diff --git a/admin/DeviceOwner/Application/README-fragmentview.txt b/admin/DeviceOwner/Application/README-fragmentview.txt new file mode 100644 index 00000000..b346a5fd --- /dev/null +++ b/admin/DeviceOwner/Application/README-fragmentview.txt @@ -0,0 +1,37 @@ +<!-- + Copyright 2015 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. +--> + +Steps to implement FragmentView template: +-in template-params.xml.ftl: + -add the following line to common imports + <common src="activities"/> + +-Add a Fragment to show behavior. In your MainActivity.java class, it will reference a Fragment + called (yourProjectName)Fragment.java. Create that file in your project, using the "main" source + folder instead of "common" or "templates". + For instance, if your package name is com.example.foo, create the file + src/main/java/com/example/foo/FooFragment.java + + +-Within this fragment, make sure that the onCreate method has the line + "setHasOptionsMenu(true);", to enable the fragment to handle menu events. + +-In order to override menu events, override onOptionsItemSelected. + +-refer to sampleSamples/fragmentViewSample for a reference implementation of a +project built on this template. + + diff --git a/admin/DeviceOwner/Application/README-singleview.txt b/admin/DeviceOwner/Application/README-singleview.txt new file mode 100644 index 00000000..57fa1341 --- /dev/null +++ b/admin/DeviceOwner/Application/README-singleview.txt @@ -0,0 +1,47 @@ +<#-- + Copyright 2015 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. +--> + +Steps to implement SingleView template: +-in template-params.xml.ftl: + -add the following line to common imports + <common src="activities"/> + + -add a string for the action button's text using the element name "sample_action". + This element should be a child of <strings>: + <strings> + ... + <sample_action>ButtonText</sample_action> + ... + </strings> + + + +-Add a Fragment to handle behavior. In your MainActivity.java class, it will reference a Fragment + called (yourProjectName)Fragment.java. Create that file in your project, using the "main" source + folder instead of "common" or "templates". + For instance, if your package name is com.example.foo, create the file + src/main/java/com/example/foo/FooFragment.java + + +-Within this fragment, make sure that the onCreate method has the line + "setHasOptionsMenu(true);", to enable the fragment to handle menu events. + +-In order to override menu events, override onOptionsItemSelected. + +-refer to sampleSamples/singleViewSample for a reference implementation of a +project built on this template. + + diff --git a/admin/DeviceOwner/Application/proguard-project.txt b/admin/DeviceOwner/Application/proguard-project.txt new file mode 100644 index 00000000..f2fe1559 --- /dev/null +++ b/admin/DeviceOwner/Application/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/admin/DeviceOwner/Application/src/main/AndroidManifest.xml b/admin/DeviceOwner/Application/src/main/AndroidManifest.xml new file mode 100644 index 00000000..fb61ac9a --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/AndroidManifest.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2015 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 + package="com.example.android.deviceowner" + xmlns:android="http://schemas.android.com/apk/res/android" + android:versionCode="1" + android:versionName="1.0"> + + <application + android:allowBackup="true" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" + android:theme="@style/AppTheme"> + + <activity + android:name=".MainActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + + <receiver + android:name=".DeviceOwnerReceiver" + android:description="@string/app_name" + android:label="@string/app_name" + android:permission="android.permission.BIND_DEVICE_ADMIN"> + <meta-data + android:name="android.app.device_admin" + android:resource="@xml/device_owner_receiver"/> + <intent-filter> + <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/> + </intent-filter> + </receiver> + + </application> + + +</manifest> diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java new file mode 100644 index 00000000..b5c62548 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2015 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.android.deviceowner; + +import android.app.Activity; +import android.app.Fragment; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.SimpleAdapter; +import android.widget.Spinner; +import android.widget.Switch; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Demonstrates the usage of the most common device management APIs for the device owner case. + * In addition to various features available for profile owners, device owners can perform extra + * actions, such as configuring global settings and enforcing a preferred Activity for a specific + * IntentFilter. + */ +public class DeviceOwnerFragment extends Fragment { + + // Keys for SharedPreferences + private static final String PREFS_DEVICE_OWNER = "DeviceOwnerFragment"; + private static final String PREF_LAUNCHER = "launcher"; + + private DevicePolicyManager mDevicePolicyManager; + + // View references + private Switch mSwitchAutoTime; + private Switch mSwitchAutoTimeZone; + private Spinner mAvailableLaunchers; + private Button mButtonLauncher; + + // Adapter for the spinner to show list of available launchers + private LauncherAdapter mAdapter; + + /** + * Handles events on the Switches. + */ + private Switch.OnCheckedChangeListener mOnCheckedChangeListener + = new Switch.OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + switch (buttonView.getId()) { + case R.id.switch_auto_time: + setBooleanGlobalSetting(Settings.Global.AUTO_TIME, isChecked); + retrieveCurrentSettings(getActivity()); + break; + case R.id.switch_auto_time_zone: + setBooleanGlobalSetting(Settings.Global.AUTO_TIME_ZONE, isChecked); + retrieveCurrentSettings(getActivity()); + break; + } + } + + }; + + /** + * Handles click events on the Button. + */ + private View.OnClickListener mOnClickListener + = new View.OnClickListener() { + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.set_preferred_launcher: + if (loadPersistentPreferredLauncher(getActivity()) == null) { + setPreferredLauncher(); + } else { + clearPreferredLauncher(); + } + retrieveCurrentSettings(getActivity()); + break; + } + } + + }; + + /** + * @return A newly instantiated {@link DeviceOwnerFragment}. + */ + public static DeviceOwnerFragment newInstance() { + return new DeviceOwnerFragment(); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_device_owner, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + // Retain references + mSwitchAutoTime = (Switch) view.findViewById(R.id.switch_auto_time); + mSwitchAutoTimeZone = (Switch) view.findViewById(R.id.switch_auto_time_zone); + mAvailableLaunchers = (Spinner) view.findViewById(R.id.available_launchers); + mButtonLauncher = (Button) view.findViewById(R.id.set_preferred_launcher); + // Bind event handlers + mSwitchAutoTime.setOnCheckedChangeListener(mOnCheckedChangeListener); + mSwitchAutoTimeZone.setOnCheckedChangeListener(mOnCheckedChangeListener); + mButtonLauncher.setOnClickListener(mOnClickListener); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mDevicePolicyManager = + (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE); + } + + @Override + public void onDetach() { + mDevicePolicyManager = null; + super.onDetach(); + } + + @Override + public void onResume() { + super.onResume(); + Activity activity = getActivity(); + if (activity != null) { + retrieveCurrentSettings(activity); + } + } + + /** + * Retrieves the current global settings and changes the UI accordingly. + * + * @param activity The activity + */ + private void retrieveCurrentSettings(Activity activity) { + // Global settings + setCheckedSafely(mSwitchAutoTime, + getBooleanGlobalSetting(activity.getContentResolver(), Settings.Global.AUTO_TIME)); + setCheckedSafely(mSwitchAutoTimeZone, + getBooleanGlobalSetting(activity.getContentResolver(), + Settings.Global.AUTO_TIME_ZONE)); + + // Launcher + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + List<ResolveInfo> list = activity.getPackageManager() + .queryIntentActivities(intent, /* default flags */ 0); + mAdapter = new LauncherAdapter(activity, list); + mAvailableLaunchers.setAdapter(mAdapter); + String packageName = loadPersistentPreferredLauncher(activity); + if (packageName == null) { // No preferred launcher is set + mAvailableLaunchers.setEnabled(true); + mButtonLauncher.setText(R.string.set_as_preferred); + } else { + int position = -1; + for (int i = 0; i < list.size(); ++i) { + if (list.get(i).activityInfo.packageName.equals(packageName)) { + position = i; + break; + } + } + if (position != -1) { + mAvailableLaunchers.setSelection(position); + mAvailableLaunchers.setEnabled(false); + mButtonLauncher.setText(R.string.clear_preferred); + } + } + } + + /** + * Retrieves the current boolean value of the specified global setting. + * + * @param resolver The ContentResolver + * @param setting The setting to be retrieved + * @return The current boolean value + */ + private static boolean getBooleanGlobalSetting(ContentResolver resolver, String setting) { + return 0 != Settings.Global.getInt(resolver, setting, 0); + } + + /** + * Sets the boolean value of the specified global setting. + * + * @param setting The setting to be set + * @param value The value to be set + */ + private void setBooleanGlobalSetting(String setting, boolean value) { + mDevicePolicyManager.setGlobalSetting( + // The ComponentName of the device owner + DeviceOwnerReceiver.getComponentName(getActivity()), + // The settings to be set + setting, + // The value we write here is a string representation for SQLite + value ? "1" : "0"); + } + + /** + * A utility method to set the checked state of the button without invoking its listener. + * + * @param button The button + * @param checked The value to be set + */ + private void setCheckedSafely(CompoundButton button, boolean checked) { + button.setOnCheckedChangeListener(null); + button.setChecked(checked); + button.setOnCheckedChangeListener(mOnCheckedChangeListener); + } + + /** + * Loads the package name from SharedPreferences. + * + * @param activity The activity + * @return The package name of the launcher currently set as preferred, or null if there is no + * preferred launcher. + */ + private static String loadPersistentPreferredLauncher(Activity activity) { + return activity.getSharedPreferences(PREFS_DEVICE_OWNER, Context.MODE_PRIVATE) + .getString(PREF_LAUNCHER, null); + } + + /** + * Saves the package name into SharedPreferences. + * + * @param activity The activity + * @param packageName The package name to be saved. Pass null to remove the preferred launcher. + */ + private static void savePersistentPreferredLauncher(Activity activity, String packageName) { + SharedPreferences.Editor editor = activity.getSharedPreferences(PREFS_DEVICE_OWNER, + Context.MODE_PRIVATE).edit(); + if (packageName == null) { + editor.remove(PREF_LAUNCHER); + } else { + editor.putString(PREF_LAUNCHER, packageName); + } + editor.apply(); + } + + /** + * Sets the selected launcher as preferred. + */ + private void setPreferredLauncher() { + Activity activity = getActivity(); + if (activity == null) { + return; + } + IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); + filter.addCategory(Intent.CATEGORY_HOME); + filter.addCategory(Intent.CATEGORY_DEFAULT); + ComponentName componentName = mAdapter.getComponentName( + mAvailableLaunchers.getSelectedItemPosition()); + mDevicePolicyManager.addPersistentPreferredActivity( + DeviceOwnerReceiver.getComponentName(activity), filter, componentName); + savePersistentPreferredLauncher(activity, componentName.getPackageName()); + } + + /** + * Clears the launcher currently set as preferred. + */ + private void clearPreferredLauncher() { + Activity activity = getActivity(); + if (activity == null) { + return; + } + mDevicePolicyManager.clearPackagePersistentPreferredActivities( + DeviceOwnerReceiver.getComponentName(activity), + loadPersistentPreferredLauncher(activity)); + savePersistentPreferredLauncher(activity, null); + } + + /** + * Shows list of {@link ResolveInfo} in a {@link Spinner}. + */ + private static class LauncherAdapter extends SimpleAdapter { + + private static final String KEY_PACKAGE_NAME = "package_name"; + private static final String KEY_ACTIVITY_NAME = "activity_name"; + + public LauncherAdapter(Context context, List<ResolveInfo> list) { + super(context, createData(list), android.R.layout.simple_list_item_1, + new String[]{KEY_PACKAGE_NAME}, + new int[]{android.R.id.text1}); + } + + private static List<HashMap<String, String>> createData(List<ResolveInfo> list) { + List<HashMap<String, String>> data = new ArrayList<>(); + for (ResolveInfo info : list) { + HashMap<String, String> map = new HashMap<>(); + map.put(KEY_PACKAGE_NAME, info.activityInfo.packageName); + map.put(KEY_ACTIVITY_NAME, info.activityInfo.name); + data.add(map); + } + return data; + } + + public ComponentName getComponentName(int position) { + @SuppressWarnings("unchecked") + HashMap<String, String> map = (HashMap<String, String>) getItem(position); + return new ComponentName(map.get(KEY_PACKAGE_NAME), map.get(KEY_ACTIVITY_NAME)); + } + + } + +} diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java new file mode 100644 index 00000000..f5969fc2 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 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.android.deviceowner; + +import android.app.admin.DeviceAdminReceiver; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; + +/** + * Handles events related to device owner. + */ +public class DeviceOwnerReceiver extends DeviceAdminReceiver { + + /** + * Called on the new profile when device owner provisioning has completed. Device owner + * provisioning is the process of setting up the device so that its main profile is managed by + * the mobile device management (MDM) application set up as the device owner. + */ + @Override + public void onProfileProvisioningComplete(Context context, Intent intent) { + // Enable the profile + DevicePolicyManager manager = + (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); + ComponentName componentName = getComponentName(context); + manager.setProfileName(componentName, context.getString(R.string.profile_name)); + // Open the main screen + Intent launch = new Intent(context, MainActivity.class); + launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(launch); + } + + /** + * @return A newly instantiated {@link android.content.ComponentName} for this + * DeviceAdminReceiver. + */ + public static ComponentName getComponentName(Context context) { + return new ComponentName(context.getApplicationContext(), DeviceOwnerReceiver.class); + } + +} diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java new file mode 100644 index 00000000..2a889c39 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 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.android.deviceowner; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Shows instruction about this device owner. + */ +public class InstructionFragment extends Fragment { + + /** + * @return A newly instantiated {@link InstructionFragment}. + */ + public static InstructionFragment newInstance() { + return new InstructionFragment(); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_instruction, container, false); + } + +} diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java new file mode 100644 index 00000000..5a331abc --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 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.android.deviceowner; + +import android.app.Activity; +import android.app.Fragment; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MainActivity extends Activity { + + private static final String TAG = "MainActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main_real); + if (savedInstanceState == null) { + DevicePolicyManager manager = + (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); + if (manager.isDeviceOwnerApp(getApplicationContext().getPackageName())) { + // This app is set up as the device owner. Show the main features. + Log.d(TAG, "The app is the device owner."); + showFragment(DeviceOwnerFragment.newInstance()); + } else { + // This app is not set up as the device owner. Show instructions. + Log.d(TAG, "The app is not the device owner."); + showFragment(InstructionFragment.newInstance()); + } + } + } + + private void showFragment(Fragment fragment) { + getFragmentManager().beginTransaction() + .replace(R.id.container, fragment) + .commit(); + } + +} diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..282e5400 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..4ecfdf61 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..dfb6cabe --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..650302ed --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml b/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml new file mode 100644 index 00000000..384e9f98 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 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. +--> +<FrameLayout + android:id="@+id/container" + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context="com.example.android.deviceowner.MainActivity" + tools:ignore="MergeRootFrame"/> diff --git a/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml b/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml new file mode 100644 index 00000000..aeae2194 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 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. +--> +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context="com.example.android.deviceowner.DeviceOwnerFragment"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="@dimen/margin_medium" + android:text="@string/label_global_settings" + android:textAppearance="?android:attr/textAppearanceLarge"/> + + <Switch + android:id="@+id/switch_auto_time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="@dimen/margin_medium" + android:paddingEnd="@dimen/margin_medium" + android:paddingStart="@dimen/margin_medium" + android:text="@string/label_auto_time" + android:textAppearance="?android:attr/textAppearanceMedium"/> + + <Switch + android:id="@+id/switch_auto_time_zone" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="@dimen/margin_medium" + android:paddingEnd="@dimen/margin_medium" + android:paddingStart="@dimen/margin_medium" + android:text="@string/label_auto_time_zone" + android:textAppearance="?android:attr/textAppearanceMedium"/> + + <Space + android:layout_width="match_parent" + android:layout_height="@dimen/margin_medium"/> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="@dimen/margin_medium" + android:text="@string/label_launcher" + android:textAppearance="?android:attr/textAppearanceLarge"/> + + <Spinner + android:id="@+id/available_launchers" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/margin_medium" + android:layout_marginTop="@dimen/margin_medium"/> + + <Button + android:id="@+id/set_preferred_launcher" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/margin_medium" + android:text="@string/set_as_preferred"/> + + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml b/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml new file mode 100644 index 00000000..9d09e393 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 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" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:context="com.example.android.deviceowner.InstructionFragment"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="@dimen/margin_medium" + android:text="@string/set_up_instruction" + android:textAppearance="?android:attr/textAppearanceMedium"/> + +</LinearLayout> diff --git a/admin/DeviceOwner/Application/src/main/res/values/strings.xml b/admin/DeviceOwner/Application/src/main/res/values/strings.xml new file mode 100644 index 00000000..af7d038b --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/values/strings.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 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="set_up_instruction"> + The app is not set up as the device owner of this device. Use NfcProvisioning sample to set + up this app as the device owner of this device (This requires factory resetting the device). + </string> + + <string name="profile_name">Sample Device Owner</string> + + <string name="label_global_settings">Global settings</string> + <string name="label_auto_time">Automatic date & time</string> + <string name="label_auto_time_zone">Automatic time zone</string> + + <string name="label_launcher">Home Launcher</string> + <string name="set_as_preferred">Set as preferred</string> + <string name="clear_preferred">Clear preferred</string> + +</resources> diff --git a/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml b/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml new file mode 100644 index 00000000..20109f06 --- /dev/null +++ b/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 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. +--> +<device-admin> + <uses-policies> + <limit-password/> + <watch-login/> + <reset-password/> + <force-lock/> + <wipe-data/> + <expire-password/> + <encrypted-storage/> + <disable-camera/> + </uses-policies> +</device-admin> diff --git a/admin/DeviceOwner/build.gradle b/admin/DeviceOwner/build.gradle new file mode 100644 index 00000000..2b8d1ef1 --- /dev/null +++ b/admin/DeviceOwner/build.gradle @@ -0,0 +1,11 @@ + +// BEGIN_EXCLUDE +import com.example.android.samples.build.SampleGenPlugin +apply plugin: SampleGenPlugin + +samplegen { + pathToBuild "../../../../build" + pathToSamplesCommon "../../common" +} +apply from: "../../../../build/build.gradle" +// END_EXCLUDE diff --git a/admin/DeviceOwner/buildSrc/build.gradle b/admin/DeviceOwner/buildSrc/build.gradle new file mode 100644 index 00000000..8c294c23 --- /dev/null +++ b/admin/DeviceOwner/buildSrc/build.gradle @@ -0,0 +1,15 @@ +repositories { + mavenCentral() +} +dependencies { + compile 'org.freemarker:freemarker:2.3.20' +} + +sourceSets { + main { + groovy { + srcDir new File(rootDir, "../../../../../build/buildSrc/src/main/groovy") + } + } +} + diff --git a/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 00000000..8c0fb64a --- /dev/null +++ b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar diff --git a/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0973c316 --- /dev/null +++ b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Jan 20 16:50:15 JST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/admin/DeviceOwner/gradlew b/admin/DeviceOwner/gradlew new file mode 100755 index 00000000..91a7e269 --- /dev/null +++ b/admin/DeviceOwner/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/admin/DeviceOwner/gradlew.bat b/admin/DeviceOwner/gradlew.bat new file mode 100644 index 00000000..aec99730 --- /dev/null +++ b/admin/DeviceOwner/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/admin/DeviceOwner/screenshots/1-main.png b/admin/DeviceOwner/screenshots/1-main.png Binary files differnew file mode 100644 index 00000000..db827d1e --- /dev/null +++ b/admin/DeviceOwner/screenshots/1-main.png diff --git a/admin/DeviceOwner/screenshots/icon-web.png b/admin/DeviceOwner/screenshots/icon-web.png Binary files differnew file mode 100755 index 00000000..ac670daf --- /dev/null +++ b/admin/DeviceOwner/screenshots/icon-web.png diff --git a/admin/DeviceOwner/settings.gradle b/admin/DeviceOwner/settings.gradle new file mode 100644 index 00000000..9464a359 --- /dev/null +++ b/admin/DeviceOwner/settings.gradle @@ -0,0 +1 @@ +include 'Application' diff --git a/admin/DeviceOwner/template-params.xml b/admin/DeviceOwner/template-params.xml new file mode 100644 index 00000000..27930d08 --- /dev/null +++ b/admin/DeviceOwner/template-params.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2015 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. +--> +<sample> + <name>DeviceOwner</name> + <group>Admin</group> + <package>com.example.android.deviceowner</package> + <minSdk>21</minSdk> + + <strings> + <intro> +<![CDATA[ +This app demonstrates how to use device owner features. Use the NfcProvisioning sample to set up +this app as the device owner of your test device (This requires wiping out the device and resseting +it as an unprovisioned device). As a device owner, this app can configure global settings, and +enforce use of a specific launcher. +]]> + </intro> + </strings> + + <template src="base"/> + + <metadata> + <status>PUBLISHED</status> + <categories>Device Admin</categories> + <technologies>Android</technologies> + <languages>Java</languages> + <solutions>Mobile</solutions> + <level>ADVANCED</level> + <icon>screenshots/icon-web.png</icon> + <screenshots> + <img>screenshots/1-main.png</img> + </screenshots> + <api_refs> + <android>android.app.admin.DevicePolicyManager</android> + <android>android.provider.Settings</android> + </api_refs> + + <description> +<![CDATA[ +This sample demonstrates how to use some device owner features. As a device owner, you can configure +global settings such as automatic time and timezone. You can mandate a specific launcher by +preferred intent handler. +]]> + </description> + + <intro> +<![CDATA[ +In order to set global settings, use [DevicePolicyManager#setGlobalSetting][1] and specify one of +the [Settings.Global][2] keys available. Note that you need to specify its value as a String. As +most of the keys accept boolean values, you will mostly use "1" for true and "0" for false. + +You can mandate a specific launcher by adding a persistent preferred activity for an IntentFilter +with Intent.CATEGORY_HOME category. Call [DevicePolicyManager#addPersistentPreferredActivity][3] to +register the activity. You can clear the registration with +[clearPackagePersistentPreferredActivities][4]. + +As a device owner, you can also use the features available for managed profile owner. See +[BasicManagedProfile][5]. + +[1]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String) +[2]: http://developer.android.com/reference/android/provider/Settings.Global.html +[3]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName) +[4]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String) +[5]: https://developer.android.com/samples/BasicManagedProfile/index.html +]]> + </intro> + </metadata> +</sample> |