简体   繁体   English

将PreferenceCategory动态添加到PreferenceScreen时出现错误

[英]Getting an error when dynamically adding PreferenceCategory to PreferenceScreen

I'm currently planning to implement dynamic notification settings in my app. 我目前正计划在我的应用中实施动态通知设置。 If the current device is running Android Oreo, show Notification Channel settings. 如果当前设备正在运行Android Oreo,请显示“通知频道”设置。 If it's not Android Oreo, then show another setting ( PreferenceCategory ) 如果不是Android Oreo,请显示其他设置( PreferenceCategory

Here's a snippet of my code used for displaying when the device's version is not Oreo: 这是我的代码片段,用于在设备版本不是Oreo时显示:

for (MyNotificationChannel notificationChannel : notificationChannels) {
    System.out.println("Notification channel created at index " + notificationChannel.getIndex());
    PreferenceCategory preferenceCategory = new PreferenceCategory(preferenceScreen.getContext());
    preferenceCategory.setTitle(notificationChannel.getNotificationTitle());
    preferenceCategory.setSummary(notificationChannel.getNotificationDesc());
    SwitchPreference enableNotificationPreference = new SwitchPreference(preferenceScreen.getContext());
    enableNotificationPreference.setDefaultValue(true);
    enableNotificationPreference.setTitle("Enable notification channel");
    enableNotificationPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            System.out.println("Preference change: " + newValue);
            return true;
        }
    });
    preferenceCategory.addPreference(enableNotificationPreference);
    SwitchPreference enableVibratePreference = new SwitchPreference(preferenceScreen.getContext());
    enableVibratePreference.setTitle("Vibrate");
    enableVibratePreference.setSummary("Whether to vibrate when there are notifications available");
    enableVibratePreference.setDefaultValue(true);
    enableVibratePreference.setIcon(R.drawable.ic_vibrate_white_24dp);
    enableVibratePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            System.out.println("Preference change: " + newValue);
            return true;
        }
    });
    RingtonePreference notificationRingtonePreference = new RingtonePreference(preferenceScreen.getContext());
    notificationRingtonePreference.setIcon(R.drawable.ic_music_white_24dp);
    notificationRingtonePreference.setTitle("Set ringtone");
    bindPreferenceSummaryToValue(notificationRingtonePreference);
    preferenceCategory.addPreference(notificationRingtonePreference);
    preferenceScreen.addPreference(preferenceCategory);
}

(By the way, MyNotificationChannel is just a class meant as an interface for my notification settings to make it easier to get stuff from strings.xml ) (顺便说一句, MyNotificationChannel只是一个类,它用作我的通知设置的接口,以使从strings.xml获取内容更加容易)

However, I'm getting this error when I attempt to navigate to the notification fragment: 但是,当我尝试导航到通知片段时出现此错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'long android.preference.PreferenceManager.getNextId()' on a null object reference
  at android.preference.Preference.onAttachedToHierarchy(Preference.java:1326)
  at android.preference.PreferenceGroup.addPreference(PreferenceGroup.java:163)
  at com.edricchan.studybuddy.SettingsActivity$NotificationPreferenceFragment.onCreate(SettingsActivity.java:345)
  at android.app.Fragment.performCreate(Fragment.java:2489)
  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237)
  at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407)
  at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186)
  at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142)
  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043)
  at android.app.FragmentManagerImpl$1.run(FragmentManager.java:719)
  at android.os.Handler.handleCallback(Handler.java:790)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:164)
  at android.app.ActivityThread.main(ActivityThread.java:6494)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

EDIT: Here's my preferences file: 编辑:这是我的首选项文件:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- This preference screen will be filled in via code -->
</PreferenceScreen>

EDIT #2: When I revert back to my original implementation (for Android Oreo), it works: 编辑#2:当我恢复到原始实现(对于Android Oreo)时,它可以正常工作:

PreferenceCategory notificationPrefCategory = new PreferenceCategory(preferenceScreen.getContext());
notificationPrefCategory.setTitle("Notification Channels");
preferenceScreen.addPreference(notificationPrefCategory);
Preference allNotificationsPreference = new Preference(preferenceScreen.getContext());
allNotificationsPreference.setTitle(R.string.notification_channel_all_channels_title);
allNotificationsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
    @Override
    public boolean onPreferenceClick(Preference preference) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, getActivity().getPackageName());
            startActivity(intent);
        }
        return false;
    }
});
notificationPrefCategory.addPreference(allNotificationsPreference);
for (MyNotificationChannel notificationChannel : notificationChannels) {
    Preference notificationPreference = new Preference(preferenceScreen.getContext());
    notificationPreference.setTitle(notificationChannel.getNotificationTitle());
    notificationPreference.setSummary(notificationChannel.getNotificationDesc());
    notificationPreference.setKey(notificationChannelIds[notificationChannel.getIndex()]);
    notificationPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
        @Override
        public boolean onPreferenceClick(Preference preference) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, getActivity().getPackageName());
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, preference.getKey());
                startActivity(intent);
            }
            return false;
        }
    });
    notificationPrefCategory.addPreference(notificationPreference);
}

I fixed the issue by moving up the line that adds the preference category to the preference screen to before all the other preferences are defined: 我通过在定义所有其他首选项之前向上移动将首选项类别添加到首选项屏幕的行来解决此问题:

// This line
preferenceScreen.addPreference(preferenceCategory);

(PS I moved it to after I defined the PreferenceCategory ) (PS我在定义PreferenceCategory之后将其移至)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM