Account preferences crashes on ListPreference
I have created an account type using the AccountAuthenticator stuff as done in the SampleSyncAdapter
tutorial. I am now trying to get account preferences working.
I have added the line android:accountPreferences="@xml/account_preferences"
to my account-authenticator
and account_preferences.xml looks like so:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/alum_settings_title"/>
<CheckBoxPreference
android:key="sync_alum"
android:title="@string/sync_alum"
android:sum开发者_如何学CmaryOn="@string/sync_alum_check"
android:summaryOff="@string/sync_alum_nocheck"/>
<ListPreference
android:key="sync_alum_since"
android:title="@string/alum_years"
android:entries="@array/years"
android:entryValues="@array/years"
android:dependency="sync_alum"/>
</PreferenceScreen>
The checkbox preference works exactly like it should but the ListPreference crashes the entire system with the following message:
05-14 22:32:16.794: ERROR/AndroidRuntime(63): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
I get the same error with EditTextPreference and with the custom subclass of DialogPreference I created.
I've finally managed to successfully launch my custom preferences activity. The pit fall was that you have to keep the following XML layout (like above):
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Account settings" />
<PreferenceScreen
android:key="key"
android:title="General settings"
android:summary="Some summary">
<!-- package relative class name-->
<intent
android:action="my.account.preference.MAIN"
android:targetClass="prefs.AccountPreferencesActivity.class">
</intent>
</PreferenceScreen>
</PreferenceScreen>
And the according AndroidManifest.xml entry:
<activity
android:label="Account preferences"
android:name=".prefs.AccountPreferencesActivity">
<intent-filter>
<action
android:name="my.account.preference.MAIN" />
<category
android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
If you look in the Android code you can find the following lines of code:
private void updatePreferenceIntents(PreferenceScreen prefs) {
for (int i = 0; i < prefs.getPreferenceCount(); i++) {
Intent intent = prefs.getPreference(i).getIntent();
if (intent != null) {
intent.putExtra(ACCOUNT_KEY, mAccount);
// This is somewhat of a hack. Since the preference screen we're accessing comes
// from another package, we need to modify the intent to launch it with
// FLAG_ACTIVITY_NEW_TASK.
// TODO: Do something smarter if we ever have PreferenceScreens of our own.
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
}
and these add the flag to the Intent specified in XML. But this only works for all 1st grade children of the PreferenceScreen. My fault was I encapsulated my Intent in the PreferenceCategory and so the flag was never OR-ed.
Hope I could help.
I've got the very same issue and ran into the same Exception mentioned above. After looking into the Android source it seems to be the case that this happens to every preference that wants to create a dialog or new window. This seems to be created as APPLICATION_WINDOW what is wrong.
In the docs to AbstractAccountAuthenticator the example uses an intent on click.
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/title_fmt" />
<PreferenceScreen
android:key="key1"
android:title="@string/key1_action"
android:summary="@string/key1_summary">
<intent
android:action="key1.ACTION"
android:targetPackage="key1.package"
android:targetClass="key1.class" />
</PreferenceScreen>
I think the intention is to launch a new preference activity from the account preferences and not use them in place. The bad thing is this let pop up a new Exception:
10-01 09:33:36.935: ERROR/AndroidRuntime(52): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
The big question is how to give the intent the flag? I've seen no way to set intent flags by XML. I've already created my own preference and launch the intent during onClick(). But it seems that the account preferences are launched in the account & sync settings context and the classloader cannot find my class.
I see two solutions here:
- Set the flags to the intent.
- Subclass Preference and handle onClick() to launch your activity. But how to publish my own class?
Yes this is seems to be a bug. There are some bugs against it at Google.
I can confirm the same issue with Edit and List preferences. So far I can only get CheckBox to work without crashing. The state is persistent but I have no idea where the state is stored.
For grins, try nuking your PreferenceCategory
. It's not doing you much good as-is anyway, since it's not wrapping any preferences. I doubt this is your problem, but it's the only thing odd I see with the XML.
Otherwise, that exception screans "Android bug" to me, so if you can create a project that reproduces the error, post it and this info to http://b.android.com.
Maybe it's because you're using the same array? for your entries
as your entryValues
?
try making another array and trying
android:entries="@array/years"
android:entryValues="@array/years_values"
精彩评论