When I try my app with Android KitKat I have an error in PreferenceActivity.
Subclasses of PreferenceActivity must override isValidFragment(String) to ve
I found I could grab a copy of my fragment names from my header resource as it was loaded:
public class MyActivity extends PreferenceActivity
{
private static List<String> fragments = new ArrayList<String>();
@Override
public void onBuildHeaders(List<Header> target)
{
loadHeadersFromResource(R.xml.headers,target);
fragments.clear();
for (Header header : target) {
fragments.add(header.fragment);
}
}
...
@Override
protected boolean isValidFragment(String fragmentName)
{
return fragments.contains(fragmentName);
}
}
This way I don't need to remember to update a list of fragments buried in the code if I want to update them.
I had hoped to use getHeaders()
and the existing list of headers directly, but it seems the activity is destroyed after onBuildHeaders()
and recreated before isValidFragment()
is called.
This may be because the Nexus 7 I'm testing on doesn't actually do two-pane preference activities. Hence the need for the static list member as well.
This API was added due to a newly discovered vulnerability. Please see http://ibm.co/1bAA8kF or http://ibm.co/IDm2Es
December 10, 2013 "We have recently disclosed a new vulnerability to the Android Security Team. [...] To be more accurate, any App which extended the PreferenceActivity class using an exported activity was automatically vulnerable. A patch has been provided in Android KitKat. If you wondered why your code is now broken, it is due to the Android KitKat patch which requires applications to override the new method, PreferenceActivity.isValidFragment, which has been added to the Android Framework." -- From the first link above
Here's my headers_preferences.xml file:
<?xml version="1.0" encoding="utf-8"?>
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.gammazero.signalrocket.AppPreferencesFragment$Prefs1Fragment"
android:title="Change Your Name" />
<header
android:fragment="com.gammazero.signalrocket.AppPreferencesFragment$Prefs2Fragment"
android:title="Change Your Group''s Name" />
<header
android:fragment="com.gammazero.signalrocket.AppPreferencesFragment$Prefs3Fragment"
android:title="Change Map View" />
</preference-headers>
In my PreferencesActivity where the isValidFragment code occurs, I just turned it on its head:
@Override
protected boolean isValidFragment(String fragmentName)
{
// return AppPreferencesFragment.class.getName().contains(fragmentName);
return fragmentName.contains (AppPreferencesFragment.class.getName());
}
As long as I use the AppPreferencesFragment string at the start of all my fragment names, they all validate just fine.