diff --git a/AppRestrictions/AppRestrictions.csproj b/AppRestrictions/AppRestrictions.csproj
new file mode 100644
index 000000000..420afc152
--- /dev/null
+++ b/AppRestrictions/AppRestrictions.csproj
@@ -0,0 +1,77 @@
+
+
+
+ Debug
+ AnyCPU
+ 10.0.0
+ 2.0
+ {6762E9D8-DDEC-4D81-BF13-6549BA8C588D}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ AppRestrictions
+ True
+ Resources\Resource.designer.cs
+ Resource
+ Resources
+ Assets
+ False
+ AppRestrictions
+ v4.3
+ Properties\AndroidManifest.xml
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ None
+ false
+ True
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AppRestrictions/AppRestrictions.sln b/AppRestrictions/AppRestrictions.sln
new file mode 100644
index 000000000..65787c89d
--- /dev/null
+++ b/AppRestrictions/AppRestrictions.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppRestrictions", "AppRestrictions.csproj", "{6762E9D8-DDEC-4D81-BF13-6549BA8C588D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6762E9D8-DDEC-4D81-BF13-6549BA8C588D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6762E9D8-DDEC-4D81-BF13-6549BA8C588D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6762E9D8-DDEC-4D81-BF13-6549BA8C588D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6762E9D8-DDEC-4D81-BF13-6549BA8C588D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = AppRestrictions.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/AppRestrictions/CustomRestrictionsActivity.cs b/AppRestrictions/CustomRestrictionsActivity.cs
new file mode 100644
index 000000000..bfd9dec9f
--- /dev/null
+++ b/AppRestrictions/CustomRestrictionsActivity.cs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+
+namespace AppRestrictions
+{
+ /**
+ * This activity demonstrates how an app can integrate its own custom app restriction settings
+ * with the restricted profile feature.
+ *
+ * This sample app maintains custom app restriction settings in shared preferences. When
+ * the activity is invoked (from Settings > Users), the stored settings are used to initialize
+ * the custom configuration on the user interface. Three sample input types are
+ * shown: checkbox, single-choice, and multi-choice. When the settings are modified by the user,
+ * the corresponding restriction entries are saved, which are retrievable under a restricted
+ * profile.
+ */
+ [Activity (Label = "CustomRestrictionsActivity")]
+ public class CustomRestrictionsActivity : Activity
+ {
+ protected override void OnCreate (Bundle bundle)
+ {
+ base.OnCreate (bundle);
+
+ if (bundle == null) {
+ FragmentManager.BeginTransaction ()
+ .Replace (Android.Resource.Id.Content, new CustomRestrictionsFragment ()).Commit ();
+ }
+ }
+ }
+}
+
diff --git a/AppRestrictions/CustomRestrictionsFragment.cs b/AppRestrictions/CustomRestrictionsFragment.cs
new file mode 100644
index 000000000..56c194d15
--- /dev/null
+++ b/AppRestrictions/CustomRestrictionsFragment.cs
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Util;
+using Android.Views;
+using Android.Widget;
+using Android.Preferences;
+
+namespace AppRestrictions
+{
+ /**
+ * This fragment is included in {@code CustomRestrictionsActivity}. It demonstrates how an app
+ * can integrate its own custom app restriction settings with the restricted profile feature.
+ *
+ * This sample app maintains custom app restriction settings in shared preferences. Your app
+ * can use other methods to maintain the settings. When this activity is invoked
+ * (from Settings > Users > Restricted Profile), the shared preferences are used to initialize
+ * the custom configuration on the user interface.
+ *
+ * Three sample input types are shown: checkbox, single-choice, and multi-choice. When the
+ * settings are modified by the user, the corresponding restriction entries are saved in the
+ * platform. The saved restriction entries are retrievable when the app is launched under a
+ * restricted profile.
+ */
+ public class CustomRestrictionsFragment : PreferenceFragment
+ {
+ // Shared preference key for the boolean restriction.
+ private static readonly String KEY_BOOLEAN_PREF = "pref_boolean";
+ // Shared preference key for the single-select restriction.
+ private static readonly String KEY_CHOICE_PREF = "pref_choice";
+ // Shared preference key for the multi-select restriction.
+ private static readonly String KEY_MULTI_PREF = "pref_multi";
+
+ private List mRestrictions;
+ private Bundle mRestrictionsBundle;
+
+ // Shared preferences for each of the sample input types.
+ private CheckBoxPreference mBooleanPref;
+ private ListPreference mChoicePref;
+ private MultiSelectListPreference mMultiPref;
+
+ // Restriction entries for each of the sample input types.
+ private RestrictionEntry mBooleanEntry;
+ private RestrictionEntry mChoiceEntry;
+ private RestrictionEntry mMultiEntry;
+
+ public override void OnCreate (Bundle savedInstanceState)
+ {
+ base.OnCreate (savedInstanceState);
+
+ AddPreferencesFromResource (Resource.Xml.custom_prefs);
+
+ // This sample app uses shared preferences to maintain app restriction settings. Your app
+ // can use other methods to maintain the settings.
+ mBooleanPref = FindPreference (KEY_BOOLEAN_PREF) as CheckBoxPreference;
+ mChoicePref = FindPreference (KEY_CHOICE_PREF) as ListPreference;
+ mMultiPref = FindPreference (KEY_MULTI_PREF) as MultiSelectListPreference;
+
+ mBooleanPref.PreferenceChange += OnPreferenceChange;
+ mChoicePref.PreferenceChange += OnPreferenceChange;
+ mMultiPref.PreferenceChange += OnPreferenceChange;
+
+ RetainInstance = true;
+ }
+
+ public override void OnActivityCreated (Bundle savedInstanceState)
+ {
+ base.OnActivityCreated (savedInstanceState);
+ Activity act = Activity;
+
+ /* BEGIN_INCLUDE (GET_CURRENT_RESTRICTIONS) */
+ // Existing app restriction settings, if exist, can be retrieved from the Bundle.
+ mRestrictionsBundle = act.Intent.GetBundleExtra (Intent.ExtraRestrictionsBundle);
+
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle = ((UserManager) act.GetSystemService (Context.UserService))
+ .GetApplicationRestrictions (Activity.PackageName);
+ }
+
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle = new Bundle ();
+ }
+
+ mRestrictions = (List) act.Intent.GetParcelableArrayListExtra (Intent.ExtraRestrictionsList);
+ /* END_INCLUDE (GET_CURRENT_RESTRICTIONS) */
+
+ // Transfers the saved values into the preference hierarchy.
+ if (mRestrictions != null) {
+ foreach (RestrictionEntry entry in mRestrictions) {
+ if (entry.Key.Equals (GetRestrictionsReceiver.KEY_BOOLEAN)) {
+ mBooleanPref.Checked = entry.SelectedState;
+ mBooleanEntry = entry;
+
+ } else if (entry.Key.Equals (GetRestrictionsReceiver.KEY_CHOICE)) {
+ mChoicePref.Value = entry.SelectedString;
+ mChoiceEntry = entry;
+
+ } else if (entry.Key.Equals (GetRestrictionsReceiver.KEY_MULTI_SELECT)) {
+ List list = new List ();
+ foreach (String value in entry.GetAllSelectedStrings ()) {
+ list.Add (value);
+ }
+ mMultiPref.Values = list;
+ mMultiEntry = entry;
+ }
+ }
+ } else {
+ mRestrictions = new List ();
+
+ // Initializes the boolean restriction entry and updates its corresponding shared
+ // preference value.
+ mBooleanEntry = new RestrictionEntry (GetRestrictionsReceiver.KEY_BOOLEAN,
+ mRestrictionsBundle.GetBoolean (GetRestrictionsReceiver.KEY_BOOLEAN, false));
+ mBooleanEntry.Type = RestrictionEntryType.Boolean;
+ mBooleanPref.Checked = mBooleanEntry.SelectedState;
+
+ // Initializes the single choice restriction entry and updates its corresponding
+ // shared preference value.
+ mChoiceEntry = new RestrictionEntry (GetRestrictionsReceiver.KEY_CHOICE,
+ mRestrictionsBundle.GetString (GetRestrictionsReceiver.KEY_CHOICE));
+ mChoiceEntry.Type = RestrictionEntryType.Choice;
+ mChoicePref.Value = mChoiceEntry.SelectedString;
+
+ // Initializes the multi-select restriction entry and updates its corresponding
+ // shared preference value.
+ mMultiEntry = new RestrictionEntry (GetRestrictionsReceiver.KEY_MULTI_SELECT,
+ mRestrictionsBundle.GetStringArray (GetRestrictionsReceiver.KEY_MULTI_SELECT));
+ mMultiEntry.Type = RestrictionEntryType.MultiSelect;
+
+ if (mMultiEntry.GetAllSelectedStrings() != null) {
+ List hset = new List ();
+ String[] values = mRestrictionsBundle.GetStringArray (GetRestrictionsReceiver.KEY_MULTI_SELECT);
+
+ if (values != null) {
+ foreach (String value in values) {
+ hset.Add (value);
+ }
+ }
+ mMultiPref.Values = hset;
+ }
+ mRestrictions.Add (mBooleanEntry);
+ mRestrictions.Add (mChoiceEntry);
+ mRestrictions.Add (mMultiEntry);
+ }
+ // Prepares result to be passed back to the Settings app when the custom restrictions
+ // activity finishes.
+ Intent intent = new Intent (Activity.Intent);
+ intent.PutParcelableArrayListExtra (Intent.ExtraRestrictionsList, new List (mRestrictions));
+ Activity.SetResult (Result.Ok, intent);
+ }
+
+ public void OnPreferenceChange (object sender, Preference.PreferenceChangeEventArgs e)
+ {
+ if (e.Preference == mBooleanPref) {
+ mBooleanEntry.SelectedState = (bool) e.NewValue;
+
+ } else if (e.Preference == mChoicePref) {
+ mChoiceEntry.SelectedString = (string) e.NewValue;
+
+ } else if (e.Preference == mMultiPref) {
+ String[] selectedStrings = new String [((IList ) e.NewValue).Count];
+ int i = 0;
+ foreach (String value in (IList) e.NewValue) {
+ selectedStrings[i++] = value;
+ }
+ mMultiEntry.SetAllSelectedStrings (selectedStrings);
+ }
+
+ // Saves all the app restriction configuration changes from the custom activity.
+ Intent intent = new Intent (Activity.Intent);
+ intent.PutParcelableArrayListExtra (Intent.ExtraRestrictionsList, new List (mRestrictions));
+ Activity.SetResult (Result.Ok, intent);
+ }
+ }
+}
+
diff --git a/AppRestrictions/GetRestrictionsReceiver.cs b/AppRestrictions/GetRestrictionsReceiver.cs
new file mode 100644
index 000000000..bead4c6fb
--- /dev/null
+++ b/AppRestrictions/GetRestrictionsReceiver.cs
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using Android.Util;
+using Android.Content.Res;
+using Android.Preferences;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace AppRestrictions
+{
+ [BroadcastReceiver (Name = "com.xamarin.apprestrictions.GetRestrictionsReciever")]
+ [IntentFilter (new[] {Intent.ActionGetRestrictionEntries})]
+ public class GetRestrictionsReceiver : BroadcastReceiver
+ {
+ static readonly String TAG = typeof (GetRestrictionsReceiver).Name;
+
+ // Keys for referencing app restriction settings from the platform.
+ public static readonly String KEY_BOOLEAN = "boolean_key";
+ public static readonly String KEY_CHOICE = "choice_key";
+ public static readonly String KEY_MULTI_SELECT = "multi_key";
+
+ public override void OnReceive (Context context, Intent intent)
+ {
+ PendingResult result = GoAsync ();
+
+ // If app restriction settings are already created, they will be included in the Bundle
+ // as key/value pairs.
+ Bundle existingRestrictions = intent.GetBundleExtra (Intent.ExtraRestrictionsBundle);
+ Log.Info (TAG, "existingRestrictions = " + existingRestrictions);
+
+ Thread thread = new Thread (new ThreadStart (delegate {
+ CreateRestrictions (context, result, existingRestrictions);
+ }));
+
+ thread.Start ();
+ }
+
+ // Initializes a boolean type restriction entry.
+ public static void PopulateBooleanEntry (Resources res, RestrictionEntry entry)
+ {
+ entry.Type = RestrictionEntryType.Boolean;
+ entry.Title = res.GetString (Resource.String.boolean_entry_title);
+ }
+
+ // Initializes a single choice type restriction entry.
+ public static void PopulateChoiceEntry (Resources res, RestrictionEntry reSingleChoice)
+ {
+ String[] choiceEntries = res.GetStringArray (Resource.Array.choice_entry_entries);
+ String[] choiceValues = res.GetStringArray (Resource.Array.choice_entry_values);
+
+ if (reSingleChoice.SelectedString == null)
+ reSingleChoice.SelectedString = choiceValues [0];
+
+ reSingleChoice.Title = res.GetString (Resource.String.choice_entry_title);
+ reSingleChoice.SetChoiceEntries (choiceEntries);
+ reSingleChoice.SetChoiceValues (choiceValues);
+ reSingleChoice.Type = RestrictionEntryType.Choice;
+ }
+
+ // Initializes a multi-select type restriction entry.
+ public static void PopulateMultiEntry (Resources res, RestrictionEntry reMultiSelect)
+ {
+ String[] multiEntries = res.GetStringArray (Resource.Array.multi_entry_entries);
+ String[] multiValues = res.GetStringArray (Resource.Array.multi_entry_values);
+
+ if (reMultiSelect.GetAllSelectedStrings() == null)
+ reMultiSelect.SetAllSelectedStrings (new String[0]);
+
+ reMultiSelect.Title = res.GetString (Resource.String.multi_entry_title);
+ reMultiSelect.SetChoiceEntries (multiEntries);
+ reMultiSelect.SetChoiceValues (multiValues);
+ reMultiSelect.Type = RestrictionEntryType.MultiSelect;
+ }
+
+ // Demonstrates the creation of standard app restriction types: boolean, single choice, and
+ // multi-select.
+ List InitRestrictions (Context context)
+ {
+ List newRestrictions = new List ();
+ Resources res = context.Resources;
+
+ RestrictionEntry reBoolean = new RestrictionEntry (KEY_BOOLEAN, false);
+ PopulateBooleanEntry (res, reBoolean);
+ newRestrictions.Add (reBoolean);
+
+ RestrictionEntry reSingleChoice = new RestrictionEntry (KEY_CHOICE, (String) null);
+ PopulateChoiceEntry (res, reSingleChoice);
+ newRestrictions.Add (reSingleChoice);
+
+ RestrictionEntry reMultiSelect = new RestrictionEntry (KEY_MULTI_SELECT, (String[]) null);
+ PopulateMultiEntry (res, reMultiSelect);
+ newRestrictions.Add (reMultiSelect);
+
+ return newRestrictions;
+ }
+
+ private void CreateRestrictions (Context context, PendingResult result, Bundle existingRestrictions)
+ {
+ // The incoming restrictions bundle contains key/value pairs representing existing app
+ // restrictions for this package. In order to retain existing app restrictions, you need to
+ // construct new restriction entries and then copy in any existing values for the new keys.
+ List newEntries = InitRestrictions (context);
+
+ // If app restrictions were not previously configured for the package, create the default
+ // restrictions entries and return them.
+ if (existingRestrictions == null) {
+ var extras = new Bundle ();
+ extras.PutParcelableArrayList (Intent.ExtraRestrictionsList, newEntries);
+ result.SetResult (Result.Ok, null, extras);
+ result.Finish ();
+ return;
+ }
+
+ // Retains current restriction settings by transferring existing restriction entries to
+ // new ones.
+ foreach (RestrictionEntry entry in newEntries) {
+ String key = entry.Key;
+
+ if (KEY_BOOLEAN.Equals (key)) {
+ entry.SelectedState = existingRestrictions.GetBoolean (KEY_BOOLEAN);
+
+ } else if (KEY_CHOICE.Equals (key)) {
+ if (existingRestrictions.ContainsKey (KEY_CHOICE)) {
+ entry.SelectedString = existingRestrictions.GetString (KEY_CHOICE);
+ }
+
+ } else if (KEY_MULTI_SELECT.Equals (key)) {
+ if (existingRestrictions.ContainsKey (KEY_MULTI_SELECT)) {
+ entry.SetAllSelectedStrings(existingRestrictions.GetStringArray (key));
+ }
+ }
+ }
+
+ var extra = new Bundle();
+
+ // This path demonstrates the use of a custom app restriction activity instead of standard
+ // types. When a custom activity is set, the standard types will not be available under
+ // app restriction settings.
+ //
+ // If your app has an existing activity for app restriction configuration, you can set it
+ // up with the intent here.
+ if (PreferenceManager.GetDefaultSharedPreferences (context)
+ .GetBoolean (MainActivity.CUSTOM_CONFIG_KEY, false)) {
+ var customIntent = new Intent();
+ customIntent.SetClass (context, typeof (CustomRestrictionsActivity));
+ extra.PutParcelable (Intent.ExtraRestrictionsIntent, customIntent);
+ }
+
+ extra.PutParcelableArrayList (Intent.ExtraRestrictionsList, newEntries);
+ result.SetResult (Result.Ok, null, extra);
+ result.Finish ();
+ }
+ }
+}
+
diff --git a/AppRestrictions/MainActivity.cs b/AppRestrictions/MainActivity.cs
new file mode 100644
index 000000000..6f45923c0
--- /dev/null
+++ b/AppRestrictions/MainActivity.cs
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+using System;
+using Android.App;
+using Android.Content;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using Android.OS;
+using Android.Preferences;
+
+namespace AppRestrictions
+{
+ /**
+ * This is the main user interface of the App Restrictions sample app. It demonstrates the use
+ * of the App Restriction feature, which is available on Android 4.3 and above tablet devices
+ * with the multiuser feature.
+ *
+ * When launched under the primary User account, you can toggle between standard app restriction
+ * types and custom. When launched under a restricted profile, this activity displays app
+ * restriction settings, if available.
+ *
+ * Follow these steps to exercise the feature:
+ * 1. If this is the primary user, go to Settings > Users.
+ * 2. Create a restricted profile, if one doesn't exist already.
+ * 3. Open the profile settings, locate the sample app, and tap the app restriction settings
+ * icon. Configure app restrictions for the app.
+ * 4. In the lock screen, switch to the user's restricted profile, launch this sample app,
+ * and see the configured app restrictions displayed.
+ */
+ [Activity (Label = "AppRestrictions", MainLauncher = true)]
+ public class MainActivity : Activity
+ {
+ Bundle mRestrictionsBundle;
+
+ // Checkbox to indicate whether custom or standard app restriction types are selected.
+ CheckBox mCustomConfig;
+
+ public static readonly String CUSTOM_CONFIG_KEY = "custom_config";
+
+ private TextView mMultiEntryValue;
+ private TextView mChoiceEntryValue;
+ private TextView mBooleanEntryValue;
+
+ protected override void OnCreate (Bundle bundle)
+ {
+ base.OnCreate (bundle);
+ SetContentView (Resource.Layout.Main);
+
+ mCustomConfig = FindViewById (Resource.Id.custom_app_limits);
+
+ bool customChecked =
+ PreferenceManager.GetDefaultSharedPreferences (this).GetBoolean (
+ CUSTOM_CONFIG_KEY, false);
+
+ if (customChecked) mCustomConfig.Checked = true;
+
+ mMultiEntryValue = FindViewById (Resource.Id.multi_entry_id);
+ mChoiceEntryValue = FindViewById (Resource.Id.choice_entry_id);
+ mBooleanEntryValue = FindViewById (Resource.Id.boolean_entry_id);
+
+ /**
+ * Saves custom app restriction to the shared preference.
+ *
+ * This flag is used by {@code GetRestrictionsReceiver} to determine if a custom app
+ * restriction activity should be used.
+ *
+ * @param view
+ */
+ mCustomConfig.Click += delegate (object sender, EventArgs e) {
+ var editor = PreferenceManager.GetDefaultSharedPreferences (this).Edit ();
+ editor.PutBoolean (CUSTOM_CONFIG_KEY, mCustomConfig.Checked).Commit ();
+ };
+ }
+
+ protected override void OnResume ()
+ {
+ base.OnResume ();
+
+ // If app restrictions are set for this package, when launched from a restricted profile,
+ // the settings are available in the returned Bundle as key/value pairs.
+ mRestrictionsBundle = ((UserManager) GetSystemService (Context.UserService))
+ .GetApplicationRestrictions (PackageName);
+
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle = new Bundle ();
+ }
+
+ // Reads and displays values from a boolean type restriction entry, if available.
+ // An app can utilize these settings to restrict its content under a restricted profile.
+ String booleanRestrictionValue =
+ mRestrictionsBundle.ContainsKey (GetRestrictionsReceiver.KEY_BOOLEAN) ?
+ mRestrictionsBundle.GetBoolean (GetRestrictionsReceiver.KEY_BOOLEAN) + "":
+ GetString (Resource.String.na);
+ mBooleanEntryValue.Text = booleanRestrictionValue;
+
+ // Reads and displays values from a single choice restriction entry, if available.
+ String singleChoiceRestrictionValue =
+ mRestrictionsBundle.ContainsKey (GetRestrictionsReceiver.KEY_CHOICE) ?
+ mRestrictionsBundle.GetString (GetRestrictionsReceiver.KEY_CHOICE) :
+ GetString (Resource.String.na);
+ mChoiceEntryValue.Text = singleChoiceRestrictionValue;
+
+ // Reads and displays values from a multi-select restriction entry, if available.
+ String[] multiSelectValues =
+ mRestrictionsBundle.GetStringArray (GetRestrictionsReceiver.KEY_MULTI_SELECT);
+
+ if (multiSelectValues == null || multiSelectValues.Length == 0) {
+ mMultiEntryValue.Text = GetString (Resource.String.na);
+
+ } else {
+ String tempValue = "";
+ foreach (String value in multiSelectValues) {
+ tempValue = tempValue + value + " ";
+ }
+ mMultiEntryValue.Text = tempValue ;
+ }
+ }
+ }
+}
+
diff --git a/AppRestrictions/Properties/AndroidManifest.xml b/AppRestrictions/Properties/AndroidManifest.xml
new file mode 100644
index 000000000..e11dea0bb
--- /dev/null
+++ b/AppRestrictions/Properties/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AppRestrictions/Properties/AssemblyInfo.cs b/AppRestrictions/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..d2bd87c71
--- /dev/null
+++ b/AppRestrictions/Properties/AssemblyInfo.cs
@@ -0,0 +1,23 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Android.App;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle ("AppRestrictions")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("petercollins")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion ("1.0.0")]
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/AppRestrictions/README.md b/AppRestrictions/README.md
new file mode 100644
index 000000000..a10b066b5
--- /dev/null
+++ b/AppRestrictions/README.md
@@ -0,0 +1,23 @@
+App Restrictions
+==================
+When launched under the primary User account, you can toggle between standard app restriction
+types and custom. When launched under a restricted profile, this activity displays app
+restriction settings, if available.
+
+This sample app maintains custom app restriction settings in shared preferences. When
+the activity is invoked (from Settings > Users), the stored settings are used to initialize
+the custom configuration on the user interface. Three sample input types are shown:
+checkbox, single-choice, and multi-choice. When the settings are modified by the user,
+the corresponding restriction entries are saved, which are retrievable under a restricted
+profile.
+
+Follow these steps to exercise the feature:
+ 1. If this is the primary user, go to Settings > Users.
+ 2. Create a restricted profile, if one doesn't exist already.
+ 3. Open the profile settings, locate the sample app, and tap the app restriction settings
+ icon. Configure app restrictions for the app.
+ 4. In the lock screen, switch to the user's restricted profile, launch this sample app,
+ and see the configured app restrictions displayed.
+
+Based on the Google Android-18 sample "AppRestrictions".
+Ported by: Peter Collins
\ No newline at end of file
diff --git a/AppRestrictions/Resources/drawable-hdpi/icon.png b/AppRestrictions/Resources/drawable-hdpi/icon.png
new file mode 100755
index 000000000..2e6ef769f
Binary files /dev/null and b/AppRestrictions/Resources/drawable-hdpi/icon.png differ
diff --git a/AppRestrictions/Resources/drawable-mdpi/icon.png b/AppRestrictions/Resources/drawable-mdpi/icon.png
new file mode 100755
index 000000000..edefb8b57
Binary files /dev/null and b/AppRestrictions/Resources/drawable-mdpi/icon.png differ
diff --git a/AppRestrictions/Resources/drawable-xhdpi/icon.png b/AppRestrictions/Resources/drawable-xhdpi/icon.png
new file mode 100755
index 000000000..de4bbc0d9
Binary files /dev/null and b/AppRestrictions/Resources/drawable-xhdpi/icon.png differ
diff --git a/AppRestrictions/Resources/drawable-xxhdpi/icon.png b/AppRestrictions/Resources/drawable-xxhdpi/icon.png
new file mode 100755
index 000000000..5e5182b38
Binary files /dev/null and b/AppRestrictions/Resources/drawable-xxhdpi/icon.png differ
diff --git a/AppRestrictions/Resources/layout/Main.axml b/AppRestrictions/Resources/layout/Main.axml
new file mode 100644
index 000000000..19c8cb337
--- /dev/null
+++ b/AppRestrictions/Resources/layout/Main.axml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AppRestrictions/Resources/values/Strings.xml b/AppRestrictions/Resources/values/Strings.xml
new file mode 100644
index 000000000..2dac3b1bf
--- /dev/null
+++ b/AppRestrictions/Resources/values/Strings.xml
@@ -0,0 +1,65 @@
+
+
+
+ App Restrictions Demo
+ Custom app restrictions
+ Test boolean type
+ Test choice type
+ Test multi-select type
+ If checked, use a custom app restriction Activity. Otherwise,
+ use standard restriction types.
+
+ Note: This sample app requires the restricted profile
+ feature.\n\n
+ 1. If this is the primary user, go to Settings > Users.\n\n
+ 2. Create a restricted profile, if one doesn\'t exist already.\n\n
+ 3. Open the profile settings, locate the sample app, and tap the app restriction settings
+ icon. Configure app restrictions for the app.\n\n
+ 4. In the lock screen, switch to the user\'s restricted profile, launch this sample app,
+ and see the configured app restrictions displayed.\n
+
+ Go to Settings
+ Current app restriction settings:
+ N/A
+ Your app can restrict its content based on these
+ settings, which can be configured through the primary user\'s Users Settings.
+
+
+
+ - Ice Cream
+ - Jelly Bean
+ - More Jelly Bean
+
+
+
+ - 1
+ - 2
+ - 3
+
+
+
+ - Ice Cream
+ - Jelly Bean
+ - More Jelly Bean
+
+
+
+ - 1
+ - 2
+ - 3
+
+
+
\ No newline at end of file
diff --git a/AppRestrictions/Resources/xml/custom_prefs.xml b/AppRestrictions/Resources/xml/custom_prefs.xml
new file mode 100644
index 000000000..5a3cf0df5
--- /dev/null
+++ b/AppRestrictions/Resources/xml/custom_prefs.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AppRestrictions/Screenshots/configure_restrictions.png b/AppRestrictions/Screenshots/configure_restrictions.png
new file mode 100755
index 000000000..1821a3083
Binary files /dev/null and b/AppRestrictions/Screenshots/configure_restrictions.png differ
diff --git a/AppRestrictions/Screenshots/custom_configure_restrictions.png b/AppRestrictions/Screenshots/custom_configure_restrictions.png
new file mode 100755
index 000000000..6ccf6a5d3
Binary files /dev/null and b/AppRestrictions/Screenshots/custom_configure_restrictions.png differ
diff --git a/AppRestrictions/Screenshots/owner_view.png b/AppRestrictions/Screenshots/owner_view.png
new file mode 100755
index 000000000..1e72b1ece
Binary files /dev/null and b/AppRestrictions/Screenshots/owner_view.png differ
diff --git a/AppRestrictions/Screenshots/restricted_view.png b/AppRestrictions/Screenshots/restricted_view.png
new file mode 100755
index 000000000..753424088
Binary files /dev/null and b/AppRestrictions/Screenshots/restricted_view.png differ