1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.apprestrictions; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import android.app.Activity; 20*90c8c64dSAndroid Build Coastguard Worker import android.content.Context; 21*90c8c64dSAndroid Build Coastguard Worker import android.content.Intent; 22*90c8c64dSAndroid Build Coastguard Worker import android.content.RestrictionEntry; 23*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle; 24*90c8c64dSAndroid Build Coastguard Worker import android.os.UserManager; 25*90c8c64dSAndroid Build Coastguard Worker import android.preference.CheckBoxPreference; 26*90c8c64dSAndroid Build Coastguard Worker import android.preference.ListPreference; 27*90c8c64dSAndroid Build Coastguard Worker import android.preference.MultiSelectListPreference; 28*90c8c64dSAndroid Build Coastguard Worker import android.preference.Preference; 29*90c8c64dSAndroid Build Coastguard Worker import android.preference.PreferenceFragment; 30*90c8c64dSAndroid Build Coastguard Worker 31*90c8c64dSAndroid Build Coastguard Worker import java.util.ArrayList; 32*90c8c64dSAndroid Build Coastguard Worker import java.util.Collections; 33*90c8c64dSAndroid Build Coastguard Worker import java.util.HashSet; 34*90c8c64dSAndroid Build Coastguard Worker import java.util.List; 35*90c8c64dSAndroid Build Coastguard Worker import java.util.Set; 36*90c8c64dSAndroid Build Coastguard Worker 37*90c8c64dSAndroid Build Coastguard Worker /** 38*90c8c64dSAndroid Build Coastguard Worker * This fragment is included in {@code CustomRestrictionsActivity}. It demonstrates how an app 39*90c8c64dSAndroid Build Coastguard Worker * can integrate its own custom app restriction settings with the restricted profile feature. 40*90c8c64dSAndroid Build Coastguard Worker * 41*90c8c64dSAndroid Build Coastguard Worker * This sample app maintains custom app restriction settings in shared preferences. Your app 42*90c8c64dSAndroid Build Coastguard Worker * can use other methods to maintain the settings. When this activity is invoked 43*90c8c64dSAndroid Build Coastguard Worker * (from Settings > Users > Restricted Profile), the shared preferences are used to initialize 44*90c8c64dSAndroid Build Coastguard Worker * the custom configuration on the user interface. 45*90c8c64dSAndroid Build Coastguard Worker * 46*90c8c64dSAndroid Build Coastguard Worker * Three sample input types are shown: checkbox, single-choice, and multi-choice. When the 47*90c8c64dSAndroid Build Coastguard Worker * settings are modified by the user, the corresponding restriction entries are saved in the 48*90c8c64dSAndroid Build Coastguard Worker * platform. The saved restriction entries are retrievable when the app is launched under a 49*90c8c64dSAndroid Build Coastguard Worker * restricted profile. 50*90c8c64dSAndroid Build Coastguard Worker */ 51*90c8c64dSAndroid Build Coastguard Worker public class CustomRestrictionsFragment extends PreferenceFragment 52*90c8c64dSAndroid Build Coastguard Worker implements Preference.OnPreferenceChangeListener { 53*90c8c64dSAndroid Build Coastguard Worker 54*90c8c64dSAndroid Build Coastguard Worker // Shared preference key for the boolean restriction. 55*90c8c64dSAndroid Build Coastguard Worker private static final String KEY_BOOLEAN_PREF = "pref_boolean"; 56*90c8c64dSAndroid Build Coastguard Worker // Shared preference key for the single-select restriction. 57*90c8c64dSAndroid Build Coastguard Worker private static final String KEY_CHOICE_PREF = "pref_choice"; 58*90c8c64dSAndroid Build Coastguard Worker // Shared preference key for the multi-select restriction. 59*90c8c64dSAndroid Build Coastguard Worker private static final String KEY_MULTI_PREF = "pref_multi"; 60*90c8c64dSAndroid Build Coastguard Worker 61*90c8c64dSAndroid Build Coastguard Worker 62*90c8c64dSAndroid Build Coastguard Worker private List<RestrictionEntry> mRestrictions; 63*90c8c64dSAndroid Build Coastguard Worker private Bundle mRestrictionsBundle; 64*90c8c64dSAndroid Build Coastguard Worker 65*90c8c64dSAndroid Build Coastguard Worker // Shared preferences for each of the sample input types. 66*90c8c64dSAndroid Build Coastguard Worker private CheckBoxPreference mBooleanPref; 67*90c8c64dSAndroid Build Coastguard Worker private ListPreference mChoicePref; 68*90c8c64dSAndroid Build Coastguard Worker private MultiSelectListPreference mMultiPref; 69*90c8c64dSAndroid Build Coastguard Worker 70*90c8c64dSAndroid Build Coastguard Worker // Restriction entries for each of the sample input types. 71*90c8c64dSAndroid Build Coastguard Worker private RestrictionEntry mBooleanEntry; 72*90c8c64dSAndroid Build Coastguard Worker private RestrictionEntry mChoiceEntry; 73*90c8c64dSAndroid Build Coastguard Worker private RestrictionEntry mMultiEntry; 74*90c8c64dSAndroid Build Coastguard Worker 75*90c8c64dSAndroid Build Coastguard Worker @Override onCreate(Bundle savedInstanceState)76*90c8c64dSAndroid Build Coastguard Worker public void onCreate(Bundle savedInstanceState) { 77*90c8c64dSAndroid Build Coastguard Worker super.onCreate(savedInstanceState); 78*90c8c64dSAndroid Build Coastguard Worker addPreferencesFromResource(R.xml.custom_prefs); 79*90c8c64dSAndroid Build Coastguard Worker 80*90c8c64dSAndroid Build Coastguard Worker // This sample app uses shared preferences to maintain app restriction settings. Your app 81*90c8c64dSAndroid Build Coastguard Worker // can use other methods to maintain the settings. 82*90c8c64dSAndroid Build Coastguard Worker mBooleanPref = (CheckBoxPreference) findPreference(KEY_BOOLEAN_PREF); 83*90c8c64dSAndroid Build Coastguard Worker mChoicePref = (ListPreference) findPreference(KEY_CHOICE_PREF); 84*90c8c64dSAndroid Build Coastguard Worker mMultiPref = (MultiSelectListPreference) findPreference(KEY_MULTI_PREF); 85*90c8c64dSAndroid Build Coastguard Worker 86*90c8c64dSAndroid Build Coastguard Worker mBooleanPref.setOnPreferenceChangeListener(this); 87*90c8c64dSAndroid Build Coastguard Worker mChoicePref.setOnPreferenceChangeListener(this); 88*90c8c64dSAndroid Build Coastguard Worker mMultiPref.setOnPreferenceChangeListener(this); 89*90c8c64dSAndroid Build Coastguard Worker 90*90c8c64dSAndroid Build Coastguard Worker setRetainInstance(true); 91*90c8c64dSAndroid Build Coastguard Worker } 92*90c8c64dSAndroid Build Coastguard Worker 93*90c8c64dSAndroid Build Coastguard Worker @Override onActivityCreated(Bundle savedInstanceState)94*90c8c64dSAndroid Build Coastguard Worker public void onActivityCreated(Bundle savedInstanceState) { 95*90c8c64dSAndroid Build Coastguard Worker super.onActivityCreated(savedInstanceState); 96*90c8c64dSAndroid Build Coastguard Worker final Activity activity = getActivity(); 97*90c8c64dSAndroid Build Coastguard Worker 98*90c8c64dSAndroid Build Coastguard Worker // BEGIN_INCLUDE (GET_CURRENT_RESTRICTIONS) 99*90c8c64dSAndroid Build Coastguard Worker // Existing app restriction settings, if exist, can be retrieved from the Bundle. 100*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle = 101*90c8c64dSAndroid Build Coastguard Worker activity.getIntent().getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE); 102*90c8c64dSAndroid Build Coastguard Worker 103*90c8c64dSAndroid Build Coastguard Worker if (mRestrictionsBundle == null) { 104*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle = 105*90c8c64dSAndroid Build Coastguard Worker ((UserManager) activity.getSystemService(Context.USER_SERVICE)) 106*90c8c64dSAndroid Build Coastguard Worker .getApplicationRestrictions(activity.getPackageName()); 107*90c8c64dSAndroid Build Coastguard Worker } 108*90c8c64dSAndroid Build Coastguard Worker 109*90c8c64dSAndroid Build Coastguard Worker if (mRestrictionsBundle == null) { 110*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle = new Bundle(); 111*90c8c64dSAndroid Build Coastguard Worker } 112*90c8c64dSAndroid Build Coastguard Worker 113*90c8c64dSAndroid Build Coastguard Worker mRestrictions = activity.getIntent().getParcelableArrayListExtra( 114*90c8c64dSAndroid Build Coastguard Worker Intent.EXTRA_RESTRICTIONS_LIST); 115*90c8c64dSAndroid Build Coastguard Worker // END_INCLUDE (GET_CURRENT_RESTRICTIONS) 116*90c8c64dSAndroid Build Coastguard Worker 117*90c8c64dSAndroid Build Coastguard Worker // Transfers the saved values into the preference hierarchy. 118*90c8c64dSAndroid Build Coastguard Worker if (mRestrictions != null) { 119*90c8c64dSAndroid Build Coastguard Worker for (RestrictionEntry entry : mRestrictions) { 120*90c8c64dSAndroid Build Coastguard Worker if (entry.getKey().equals(GetRestrictionsReceiver.KEY_BOOLEAN)) { 121*90c8c64dSAndroid Build Coastguard Worker mBooleanPref.setChecked(entry.getSelectedState()); 122*90c8c64dSAndroid Build Coastguard Worker mBooleanEntry = entry; 123*90c8c64dSAndroid Build Coastguard Worker } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_CHOICE)) { 124*90c8c64dSAndroid Build Coastguard Worker mChoicePref.setValue(entry.getSelectedString()); 125*90c8c64dSAndroid Build Coastguard Worker mChoiceEntry = entry; 126*90c8c64dSAndroid Build Coastguard Worker } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_MULTI_SELECT)) { 127*90c8c64dSAndroid Build Coastguard Worker HashSet<String> set = new HashSet<>(); 128*90c8c64dSAndroid Build Coastguard Worker Collections.addAll(set, entry.getAllSelectedStrings()); 129*90c8c64dSAndroid Build Coastguard Worker mMultiPref.setValues(set); 130*90c8c64dSAndroid Build Coastguard Worker mMultiEntry = entry; 131*90c8c64dSAndroid Build Coastguard Worker } 132*90c8c64dSAndroid Build Coastguard Worker } 133*90c8c64dSAndroid Build Coastguard Worker } else { 134*90c8c64dSAndroid Build Coastguard Worker mRestrictions = new ArrayList<>(); 135*90c8c64dSAndroid Build Coastguard Worker 136*90c8c64dSAndroid Build Coastguard Worker // Initializes the boolean restriction entry and updates its corresponding shared 137*90c8c64dSAndroid Build Coastguard Worker // preference value. 138*90c8c64dSAndroid Build Coastguard Worker mBooleanEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_BOOLEAN, 139*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle.getBoolean(GetRestrictionsReceiver.KEY_BOOLEAN, false)); 140*90c8c64dSAndroid Build Coastguard Worker mBooleanEntry.setType(RestrictionEntry.TYPE_BOOLEAN); 141*90c8c64dSAndroid Build Coastguard Worker mBooleanPref.setChecked(mBooleanEntry.getSelectedState()); 142*90c8c64dSAndroid Build Coastguard Worker 143*90c8c64dSAndroid Build Coastguard Worker // Initializes the single choice restriction entry and updates its corresponding 144*90c8c64dSAndroid Build Coastguard Worker // shared preference value. 145*90c8c64dSAndroid Build Coastguard Worker mChoiceEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_CHOICE, 146*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle.getString(GetRestrictionsReceiver.KEY_CHOICE)); 147*90c8c64dSAndroid Build Coastguard Worker mChoiceEntry.setType(RestrictionEntry.TYPE_CHOICE); 148*90c8c64dSAndroid Build Coastguard Worker mChoicePref.setValue(mChoiceEntry.getSelectedString()); 149*90c8c64dSAndroid Build Coastguard Worker 150*90c8c64dSAndroid Build Coastguard Worker // Initializes the multi-select restriction entry and updates its corresponding 151*90c8c64dSAndroid Build Coastguard Worker // shared preference value. 152*90c8c64dSAndroid Build Coastguard Worker mMultiEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_MULTI_SELECT, 153*90c8c64dSAndroid Build Coastguard Worker mRestrictionsBundle.getStringArray( 154*90c8c64dSAndroid Build Coastguard Worker GetRestrictionsReceiver.KEY_MULTI_SELECT)); 155*90c8c64dSAndroid Build Coastguard Worker mMultiEntry.setType(RestrictionEntry.TYPE_MULTI_SELECT); 156*90c8c64dSAndroid Build Coastguard Worker if (mMultiEntry.getAllSelectedStrings() != null) { 157*90c8c64dSAndroid Build Coastguard Worker HashSet<String> set = new HashSet<>(); 158*90c8c64dSAndroid Build Coastguard Worker final String[] values = mRestrictionsBundle.getStringArray( 159*90c8c64dSAndroid Build Coastguard Worker GetRestrictionsReceiver.KEY_MULTI_SELECT); 160*90c8c64dSAndroid Build Coastguard Worker if (values != null) { 161*90c8c64dSAndroid Build Coastguard Worker Collections.addAll(set, values); 162*90c8c64dSAndroid Build Coastguard Worker } 163*90c8c64dSAndroid Build Coastguard Worker mMultiPref.setValues(set); 164*90c8c64dSAndroid Build Coastguard Worker } 165*90c8c64dSAndroid Build Coastguard Worker mRestrictions.add(mBooleanEntry); 166*90c8c64dSAndroid Build Coastguard Worker mRestrictions.add(mChoiceEntry); 167*90c8c64dSAndroid Build Coastguard Worker mRestrictions.add(mMultiEntry); 168*90c8c64dSAndroid Build Coastguard Worker } 169*90c8c64dSAndroid Build Coastguard Worker // Prepares result to be passed back to the Settings app when the custom restrictions 170*90c8c64dSAndroid Build Coastguard Worker // activity finishes. 171*90c8c64dSAndroid Build Coastguard Worker Intent intent = new Intent(getActivity().getIntent()); 172*90c8c64dSAndroid Build Coastguard Worker intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS_LIST, 173*90c8c64dSAndroid Build Coastguard Worker new ArrayList<>(mRestrictions)); 174*90c8c64dSAndroid Build Coastguard Worker getActivity().setResult(Activity.RESULT_OK, intent); 175*90c8c64dSAndroid Build Coastguard Worker } 176*90c8c64dSAndroid Build Coastguard Worker 177*90c8c64dSAndroid Build Coastguard Worker @Override onPreferenceChange(Preference preference, Object newValue)178*90c8c64dSAndroid Build Coastguard Worker public boolean onPreferenceChange(Preference preference, Object newValue) { 179*90c8c64dSAndroid Build Coastguard Worker if (preference == mBooleanPref) { 180*90c8c64dSAndroid Build Coastguard Worker mBooleanEntry.setSelectedState((Boolean) newValue); 181*90c8c64dSAndroid Build Coastguard Worker } else if (preference == mChoicePref) { 182*90c8c64dSAndroid Build Coastguard Worker mChoiceEntry.setSelectedString((String) newValue); 183*90c8c64dSAndroid Build Coastguard Worker } else if (preference == mMultiPref && newValue instanceof Set) { 184*90c8c64dSAndroid Build Coastguard Worker // newValue is a Set<String>, skip the lint warning. 185*90c8c64dSAndroid Build Coastguard Worker //noinspection unchecked 186*90c8c64dSAndroid Build Coastguard Worker String[] selectedStrings = new String[((Set<String>) newValue).size()]; 187*90c8c64dSAndroid Build Coastguard Worker int i = 0; 188*90c8c64dSAndroid Build Coastguard Worker //noinspection unchecked 189*90c8c64dSAndroid Build Coastguard Worker for (String value : (Set<String>) newValue) { 190*90c8c64dSAndroid Build Coastguard Worker selectedStrings[i++] = value; 191*90c8c64dSAndroid Build Coastguard Worker } 192*90c8c64dSAndroid Build Coastguard Worker mMultiEntry.setAllSelectedStrings(selectedStrings); 193*90c8c64dSAndroid Build Coastguard Worker } 194*90c8c64dSAndroid Build Coastguard Worker 195*90c8c64dSAndroid Build Coastguard Worker // Saves all the app restriction configuration changes from the custom activity. 196*90c8c64dSAndroid Build Coastguard Worker Intent intent = new Intent(getActivity().getIntent()); 197*90c8c64dSAndroid Build Coastguard Worker intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS_LIST, 198*90c8c64dSAndroid Build Coastguard Worker new ArrayList<>(mRestrictions)); 199*90c8c64dSAndroid Build Coastguard Worker getActivity().setResult(Activity.RESULT_OK, intent); 200*90c8c64dSAndroid Build Coastguard Worker return true; 201*90c8c64dSAndroid Build Coastguard Worker } 202*90c8c64dSAndroid Build Coastguard Worker } 203