From 447d1e3d6c607323d2f47eaf2e9313e892cc3dbf Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 29 Mar 2013 17:46:22 -0700 Subject: [PATCH] App limits sample Shows how to expose app restrictions for both simple types and custom intents. Change-Id: I95d422d1d637bd4bdb4f731d862975a160b65a50 --- samples/AppLimits/Android.mk | 17 ++ samples/AppLimits/AndroidManifest.xml | 42 +++++ samples/AppLimits/res/values/strings.xml | 49 ++++++ samples/AppLimits/res/xml/custom_prefs.xml | 33 ++++ .../applimits/CustomRestrictionsActivity.java | 118 ++++++++++++++ .../applimits/GetRestrictionsReceiver.java | 150 ++++++++++++++++++ 6 files changed, 409 insertions(+) create mode 100644 samples/AppLimits/Android.mk create mode 100644 samples/AppLimits/AndroidManifest.xml create mode 100644 samples/AppLimits/res/values/strings.xml create mode 100644 samples/AppLimits/res/xml/custom_prefs.xml create mode 100644 samples/AppLimits/src/com/example/android/applimits/CustomRestrictionsActivity.java create mode 100644 samples/AppLimits/src/com/example/android/applimits/GetRestrictionsReceiver.java diff --git a/samples/AppLimits/Android.mk b/samples/AppLimits/Android.mk new file mode 100644 index 000000000..27252761a --- /dev/null +++ b/samples/AppLimits/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := samples tests + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := AppLimits + +LOCAL_SDK_VERSION := current + +include $(BUILD_PACKAGE) + +LOCAL_PROGUARD_FLAG_FILES := proguard.flags + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/samples/AppLimits/AndroidManifest.xml b/samples/AppLimits/AndroidManifest.xml new file mode 100644 index 000000000..8133fe9b3 --- /dev/null +++ b/samples/AppLimits/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/AppLimits/res/values/strings.xml b/samples/AppLimits/res/values/strings.xml new file mode 100644 index 000000000..c8451e15d --- /dev/null +++ b/samples/AppLimits/res/values/strings.xml @@ -0,0 +1,49 @@ + + + + AppLimits Demo + Custom app restrictions + App Limits + Test Custom Restrictions + Test choice type + Test multi-select type + + + + 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/samples/AppLimits/res/xml/custom_prefs.xml b/samples/AppLimits/res/xml/custom_prefs.xml new file mode 100644 index 000000000..2b4512582 --- /dev/null +++ b/samples/AppLimits/res/xml/custom_prefs.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/samples/AppLimits/src/com/example/android/applimits/CustomRestrictionsActivity.java b/samples/AppLimits/src/com/example/android/applimits/CustomRestrictionsActivity.java new file mode 100644 index 000000000..a1daa2118 --- /dev/null +++ b/samples/AppLimits/src/com/example/android/applimits/CustomRestrictionsActivity.java @@ -0,0 +1,118 @@ +/* + * 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. + */ + +package com.example.android.applimits; + +import android.content.Intent; +import android.content.RestrictionEntry; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.MultiSelectListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceActivity; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +public class CustomRestrictionsActivity extends PreferenceActivity + implements OnPreferenceChangeListener { + + private static final String KEY_CUSTOM_PREF = "custom"; + private static final String KEY_CHOICE_PREF = "choice"; + private static final String KEY_MULTI_PREF = "multi"; + + ArrayList mRestrictions; + + CheckBoxPreference mCustomPref; + ListPreference mChoicePref; + MultiSelectListPreference mMultiPref; + + RestrictionEntry mCustomEntry; + RestrictionEntry mChoiceEntry; + RestrictionEntry mMultiEntry; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mRestrictions = getIntent().getParcelableArrayListExtra( + Intent.EXTRA_RESTRICTIONS); + + if (savedInstanceState != null + && savedInstanceState.containsKey(Intent.EXTRA_RESTRICTIONS)) { + mRestrictions = savedInstanceState.getParcelableArrayList(Intent.EXTRA_RESTRICTIONS); + } + + this.addPreferencesFromResource(R.xml.custom_prefs); + mCustomPref = (CheckBoxPreference) findPreference(KEY_CUSTOM_PREF); + mChoicePref = (ListPreference) findPreference(KEY_CHOICE_PREF); + mMultiPref = (MultiSelectListPreference) findPreference(KEY_MULTI_PREF); + + // Transfer the saved values into the preference hierarchy + for (RestrictionEntry entry : mRestrictions) { + if (entry.getKey().equals(GetRestrictionsReceiver.KEY_CUSTOM)) { + mCustomPref.setChecked(entry.getSelectedState()); + mCustomEntry = entry; + } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_CHOICE)) { + mChoicePref.setValue(entry.getSelectedString()); + mChoiceEntry = entry; + } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_MULTI_SELECT)) { + HashSet set = new HashSet(); + for (String value : entry.getAllSelectedStrings()) { + set.add(value); + } + mMultiPref.setValues(set); + mMultiEntry = entry; + } + } + mCustomPref.setOnPreferenceChangeListener(this); + mChoicePref.setOnPreferenceChangeListener(this); + mMultiPref.setOnPreferenceChangeListener(this); + Intent intent = new Intent(getIntent()); + intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS, + mRestrictions); + setResult(RESULT_OK, intent); + } + + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS, mRestrictions); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference == mCustomPref) { + mCustomEntry.setSelectedState((Boolean) newValue); + } else if (preference == mChoicePref) { + mChoiceEntry.setSelectedString((String) newValue); + } else if (preference == mMultiPref) { + String[] selectedStrings = new String[((Set)newValue).size()]; + int i = 0; + for (String value : (Set) newValue) { + selectedStrings[i++] = value; + } + mMultiEntry.setAllSelectedStrings(selectedStrings); + } + Intent intent = new Intent(getIntent()); + intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS, + mRestrictions); + setResult(RESULT_OK, intent); + return true; + } +} diff --git a/samples/AppLimits/src/com/example/android/applimits/GetRestrictionsReceiver.java b/samples/AppLimits/src/com/example/android/applimits/GetRestrictionsReceiver.java new file mode 100644 index 000000000..9cd3fc2be --- /dev/null +++ b/samples/AppLimits/src/com/example/android/applimits/GetRestrictionsReceiver.java @@ -0,0 +1,150 @@ +/* + * 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. + */ + +package com.example.android.applimits; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.RestrictionEntry; +import android.content.BroadcastReceiver.PendingResult; +import android.content.res.Resources; +import android.os.Bundle; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +public class GetRestrictionsReceiver extends BroadcastReceiver { + private static final String TAG = "AppLimits$GetRestrictionsReceiver"; + + static final String KEY_CUSTOM = "custom_or_not"; + static final String KEY_CHOICE = "choice"; + static final String KEY_MULTI_SELECT = "multi"; + + @Override + public void onReceive(final Context context, Intent intent) { + final PendingResult result = goAsync(); + final ArrayList oldRestrictions = + intent.getParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS); + Log.i(TAG, "oldRestrictions = " + oldRestrictions); + new Thread() { + public void run() { + createRestrictions(context, result, oldRestrictions); + } + }.start(); + } + + public static void populateCustomEntry(Resources res, RestrictionEntry entry) { + entry.setType(RestrictionEntry.TYPE_BOOLEAN); + entry.setTitle(res.getString(R.string.custom_or_not_title)); + } + + public static void populateChoiceEntry(Resources res, RestrictionEntry reSingleChoice) { + String[] choiceEntries = res.getStringArray(R.array.choice_entry_entries); + String[] choiceValues = res.getStringArray(R.array.choice_entry_values); + if (reSingleChoice.getSelectedString() == null) { + reSingleChoice.setSelectedString(choiceValues[0]); + } + reSingleChoice.setTitle(res.getString(R.string.choice_entry_title)); + reSingleChoice.setChoiceEntries(choiceEntries); + reSingleChoice.setChoiceValues(choiceValues); + reSingleChoice.setType(RestrictionEntry.TYPE_CHOICE); + } + + public static void populateMultiEntry(Resources res, RestrictionEntry reMultiSelect) { + String[] multiEntries = res.getStringArray(R.array.multi_entry_entries); + String[] multiValues = res.getStringArray(R.array.multi_entry_values); + if (reMultiSelect.getAllSelectedStrings() == null) { + reMultiSelect.setAllSelectedStrings(new String[0]); + } + reMultiSelect.setTitle(res.getString(R.string.multi_entry_title)); + reMultiSelect.setChoiceEntries(multiEntries); + reMultiSelect.setChoiceValues(multiValues); + reMultiSelect.setType(RestrictionEntry.TYPE_MULTI_SELECT); + } + + private ArrayList initRestrictions(Context context) { + ArrayList newRestrictions = new ArrayList(); + Resources res = context.getResources(); + + RestrictionEntry reCustomOrNot = new RestrictionEntry(KEY_CUSTOM, false); + populateCustomEntry(res, reCustomOrNot); + newRestrictions.add(reCustomOrNot); + + 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, ArrayList old) { + Resources res = context.getResources(); + + ArrayList newEntries = initRestrictions(context); + // If this is the first time, create the default restrictions entries and return them. + if (old == null) { + Bundle extras = new Bundle(); + extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS, newEntries); + result.setResult(Activity.RESULT_OK, null, extras); + result.finish(); + return; + } + + boolean custom = false; + for (RestrictionEntry entry : old) { + if (entry.getKey().equals(KEY_CUSTOM)) { + if (entry.getSelectedState()) { + custom = true; + } + RestrictionEntry newEntry = find(newEntries, KEY_CUSTOM); + newEntry.setSelectedState(entry.getSelectedState()); + } else if (entry.getKey().equals(KEY_CHOICE)) { + RestrictionEntry newEntry = find(newEntries, KEY_CHOICE); + newEntry.setSelectedString(entry.getSelectedString()); + } else if (entry.getKey().equals(KEY_MULTI_SELECT)) { + RestrictionEntry newEntry = find(newEntries, KEY_MULTI_SELECT); + newEntry.setAllSelectedStrings(entry.getAllSelectedStrings()); + } + } + + Bundle extras = new Bundle(); + if (custom) { + Intent customIntent = new Intent(); + customIntent.setClass(context, CustomRestrictionsActivity.class); + extras.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, customIntent); + } + extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS, newEntries); + result.setResult(Activity.RESULT_OK, null, extras); + result.finish(); + } + + private RestrictionEntry find(ArrayList entries, String key) { + for (RestrictionEntry entry : entries) { + if (entry.getKey().equals(key)) { + return entry; + } + } + return null; + } +}