开发者

android preferences problems and assistance needed

Another question about my implementation. I am fairly new to java/android coming from a c/c++ back ground. I already have this implemented in my code, i am just having a couple issues with it and was also wondering if this was the best solution and if anyone had any suggestions or could help me with my problem. Here is the problem and my questions:

My android application needs to have the capabilities of loading settings from an xml file and the application needs to allow the user to change those settings and remember the changed settings. I also need my application to reference those changes and detect when the user has changed one of the settings.

I currently have the above working, except that i want the default settings loaded from my xml file instead of the method used in my code (view the code to see what im talking about). I have searched around for this and can not seem to find a solution.

Once a change is detected i need it to load the value into my DataRobot class variables. I have accessor functions for this (see code). However, when i attempt to change any of the settings it does not change the value in my DataRobot class.

Those two block quotes are explaining what i need, basically. I am using android preferences to solve this problem currently. Would this be the best way to solve this problem?

If you need any additional information please let me know. Thanks for your assistance in advance, it is greatly appreciated!


Also, i am currently experiencing a few errors with the current setup, listed below is an explanation of when the error is occurring and the log cat of said error.

The log cat output below happens when the application is first launching. It appears that it is having trouble converting a string and threw a ClassCastException. I am not sure where or why this is occurring. All the code is at the bottom of the post.

02-03 20:05:50.731: INFO/System.out(279): debugger has settled (1384)
02-03 20:05:52.080: INFO/ActivityManager(59): Displayed activity com.android.launcher/com.android.launcher2.Launcher: 38755 ms (total 38755 ms)
02-03 20:05:52.480: WARN/Resources(279): Converting to string: TypedValue{t=0x10/d=0x3c a=-1}
02-03 20:05:52.669: WARN/System.err(279): java.lang.ClassCastException: java.lang.String
02-03 20:05:52.689: WARN/System.err(279):     at android.app.ContextImpl$SharedPreferencesImpl.getInt(ContextImpl.java:2706)
02-03 20:05:52.689: WARN/System.err(279):     at cpe495.smartapp.SmartApp.onCreate(SmartApp.java:61)
02-03 20:05:52.701: WARN/System.err(279):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-03 20:05:52.715: WARN/System.err(279):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-03 20:05:52.720: WARN/System.err(279):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-03 20:05:52.729: WARN/System.err(279):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-03 20:05:52.729: WARN/System.err(279):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-03 20:05:52.750: WARN/System.err(279):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 20:05:52.750: WARN/System.err(279):     at android.os.Looper.loop(Looper.java:123)
02-03 20:05:52.760: WARN/System.err(279):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-03 20:05:52.771: WARN/System.err(279):     at java.lang.reflect.Method.invokeNative(Native Method)
02-03 20:05:52.781: WARN/System.err(279):     at java.lang.reflect.Method.invoke(Method.java:521)
02-03 20:05:52.781: WARN/System.err(279):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-03 20:05:52.799: WARN/System.err(279):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-03 20:05:52.799: WARN/System.err(279):     at dalvik.system.NativeStart.main(Native Method)
02-03 20:05:57.439: DEBUG/KeyguardViewMediator(59): pokeWakelock(5000)
02-03 20:05:57.630: DEBUG/KeyguardViewMediator(59): pokeWakelock(5000)
02-03 20:05:57.759: INFO/ActivityManager(59): Displayed activity cpe495.smartapp/.SmartApp: 10694 ms (total 10694 ms)
02-03 20:05:57.940: INFO/ARMAssembler(59): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x2bd108:0x2bd214] in 2142171 ns
02-03 20:05:58.029: INFO/ARMAssembler(59): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x2bd218:0x2bd3e0] in 1052927 ns   

The log cat below is printed out after the user uses the preferences menu to change the HeartRateBase value in the preferences. It appears to be happening inside the onpreferenceschanged function.

02-03 20:06:19.000: VERBOSE/onsharedpreferencechanged(279): inside
02-03 20:06:19.009: WARN/System.err(279): java.lang.ClassCastException: java.lang.String
02-03 20:06:19.019: WARN/System.err(279):     at android.app.ContextImpl$SharedPreferencesImpl.getInt(ContextImpl.java:2706)
02-03 20:06:19.031: WARN/System.err(279):     at cpe495.smartapp.SmartApp.onSharedPreferenceChanged(SmartApp.java:131)
02-03 20:06:19.040: WARN/System.err(279):     at android.app.ContextImpl$SharedPreferencesImpl$EditorImpl.commit(ContextImpl.java:2830)
02-03 20:06:19.040: WARN/System.err(279):     at android.preference.Preference.tryCommit(Preference.java:1198)
02-03 20:06:19.050: WARN/System.err(279):     at android.preference.Preference.persistString(Preference.java:1225)
02-03 20:06:19.060: WARN/System.err(279):     at android.preference.ListPreference.setValue(ListPreference.java:126)
02-03 20:06:19.070: WARN/System.err(279):     at android.preference.ListPreference.onDialogClosed(ListPreference.java:220)
02-03 20:06:19.120: WARN/System.err(279):     at android.preference.DialogPreference.onDismiss(DialogPreference.java:384)
02-03 20:06:19.139: WARN/System.err(279):     at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1047)
02-03 20:06:19.149: WARN/System.err(279):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 20:06:19.149: WARN/System.err(279):     at android.os.Looper.loop(Looper.java:123)
02-03 20:06:19.170: WARN/System.err(279):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-03 20:06:19.170: WARN/System.err(279):     at java.lang.reflect.Method.invokeNative(Native Method)
02-03 20:06:19.180: WARN/System.err(279):     at java.lang.reflect.Method.invoke(Method.java:521)
02-03 20:06:19.190: WARN/System.err(279):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-03 20:06:19.200: WARN/System.err(279):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-03 20:06:19.200: WARN/System.err(279):     at dalvik.system.NativeStart.main(Native Method)
02-03 20:06:19.320: WARN/InputManagerService(59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@43e60f18   

Starting here is the code that i have for these issues.


//The Main Class, mainly my gui class
public class SmartApp extends Activity implements OnSharedPreferenceChangeListener {

    private DataRobot dR = new DataRobot();
    public SmartApp() {}
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.intro);

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        PreferenceManager.setDefaultValues(this, R.xml.settings, false);
        prefs.registerOnSharedPreferenceChangeListener(this);

        //set remembered preferences
        try {
            dR.sethRB(prefs.getInt("heartRateBaseKey", 60));
            dR.sethRVMax(prefs.getInt("hRVMaxKey", 100));
            dR.sethRVMin(prefs.getInt("hRVMinKey", 0));
            dR.setsI1(prefs.getInt("sI1Key", 50));
            dR.setsI2(prefs.getInt("sI2Key", 80));
            dR.setW1(prefs.getInt("weight1Key", 20));
            dR.setW2(prefs.getInt("weight2Key", 40));
            dR.setW3(prefs.getInt("weight3Key", 60));
        }
        catch (ClassCastException e) {
            e.printStackTrace();
        }

        final Button smartConnectionSettingsButton = (Button) findViewById(R.id.smartConnectionSettingsButton);
        smartConnectionSettingsButton.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Intent settingsIntent = new Intent(v.getContext(), Settings.class);
                        startActivityForResult(settingsIntent, 0);
                    }
                });
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs,
            String key) {
        // TODO Auto-g开发者_开发问答enerated method stub
        Log.v("onsharedpreferencechanged", "inside");
        try {
            if(key.equals("heartRateBaseKey")) {
                dR.sethRB(prefs.getInt("heartRateBaseKey", 60));
            }
            else if(key.equals("hRVMaxKey")) {
                dR.sethRVMax(prefs.getInt("hRVMaxKey", 100));
            }
            else if(key.equals("hRVMinKey")) {
                dR.sethRVMin(prefs.getInt("hRVMinKey", 0));
            }
            else if(key.equals("sI1Key")) {
                dR.setsI1(prefs.getInt("sI1Key", 50));
            }
            else if(key.equals("sI2Key")) {
                dR.setsI2(prefs.getInt("sI2Key", 80));
            }
            else if(key.equals("weight1Key")) {
                dR.setW1(prefs.getInt("weight1Key", 20));
            }
            else if(key.equals("weight2Key")) {
                dR.setW2(prefs.getInt("weight2Key", 40));
            }
            else if(key.equals("weight3Key")) {
                dR.setW3(prefs.getInt("weight3Key", 60));
            }
        }
        catch (ClassCastException e) {
            e.printStackTrace();
        }

    }
}    

This class is where i am analyzing the data and i need the privates here to be set at application launch time. Currently i am doing that in the onCreate method in SmartApp. I also need the values changed in real time if a user changes any of the preferences during run time.

public class DataRobot {
    /* This class is for analyzing the data */
    private SmartDataObject data;

    private int sI1;
    private int sI2;
    private int w1;
    private int w2;
    private int w3;
    private int hRB;
    private int hRVMin;
    private int hRVMax;
    public boolean analyzeData(SmartDataObject temp) {}

    public void setsI1(int temp) {
        sI1 = temp;
    }
    public void setsI2(int temp) {
        sI2 = temp;
    }
    public void setW1(int temp) {
        w1 = temp;
    }
    public void setW2(int temp) {
        w2 = temp;
    }
    public void setW3(int temp) {
        w3 = temp;
    }
    public void sethRB(int temp) {
        hRB = temp;
    }
    public void sethRVMin(int temp) {
        hRVMin = temp;
    }
    public void sethRVMax(int temp) {
        hRVMax = temp;
    }
}   

Below is the preferences class

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Preferences extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }
}

Below is the XML file for my preferences named "settings.xml".

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Profile Settings">
<EditTextPreference 
android:title="First Name" 
android:key="firstNameKey" 
android:selectable="false"></EditTextPreference>
<EditTextPreference 
android:title="Last Name" 
android:key="lastNameKey" 
android:selectable="false"></EditTextPreference>
<EditTextPreference 
android:title="User Name" 
android:key="userNameKey" 
android:selectable="false"></EditTextPreference>
<EditTextPreference 
android:title="Birth Date" 
android:key="birthDateKey" 
android:selectable="false"></EditTextPreference>
</PreferenceCategory>
<PreferenceCategory 
android:title="Configuration Settings">
<ListPreference 
android:title="Medium Stress Index Threshold" 
android:entryValues="@array/sI1Values" 
android:entries="@array/sI1Array" 
android:key="sI1Key"></ListPreference>
<ListPreference 
android:title="High Stress Index Threshold" 
android:entryValues="@array/sI1Values" 
android:entries="@array/sI1Array" 
android:key="sI2Key"></ListPreference>
<EditTextPreference 
android:title="Weight 1" 
android:key="weight1Key"></EditTextPreference>
<EditTextPreference 
android:title="Weight 2" 
android:key="weight2Key"></EditTextPreference>
<EditTextPreference 
android:title="Weight 3" 
android:key="weight3Key"></EditTextPreference>    
<ListPreference
android:entryValues="@array/heartRateBaseValues" 
android:entries="@array/heartRateBaseArray" 
android:defaultValue="60" 
android:key="heartRateBaseKey" 
android:title="Heart Rate Base"></ListPreference>
<EditTextPreference 
android:title="Heart Rate Variability Minimum" 
android:key="hRVMinKey"></EditTextPreference>
<EditTextPreference 
android:title="Heart Rate Variability Maximum" 
android:key="hRVMaxKey"></EditTextPreference>    
</PreferenceCategory>
</PreferenceScreen>   

Below is the "arrayValues.xml" file that holds some values for some stuff.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="heartRateBaseArray">
<item>10 bpm</item>
<item>20 bpm</item>
<item>30 bpm</item>
<item>40 bpm</item>
<item>50 bpm</item>
<item>60 bpm</item>
<item>70 bpm</item>
<item>80 bpm</item>
<item>90 bpm</item>
<item>100 bpm</item>
</string-array>
<string-array name="heartRateBaseValues">
<item>10</item>
<item>20</item>
<item>30</item>
<item>40</item>
<item>50</item>
<item>60</item>
<item>70</item>
<item>80</item>
<item>90</item>
<item>100</item>
</string-array>
<string-array name="sI1Array">
<item>0</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>20</item>
<item>25</item>
<item>30</item>
<item>35</item>
<item>40</item>
<item>45</item>
<item>50</item>
<item>55</item>
<item>60</item>
<item>65</item>
<item>70</item>
<item>75</item>
<item>80</item>
<item>85</item>
<item>90</item>
<item>95</item>
<item>100</item>
</string-array>
<string-array name="sI1Values">
<item>0</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>20</item>
<item>25</item>
<item>30</item>
<item>35</item>
<item>40</item>
<item>45</item>
<item>50</item>
<item>55</item>
<item>60</item>
<item>65</item>
<item>70</item>
<item>75</item>
<item>80</item>
<item>85</item>
<item>90</item>
<item>95</item>
<item>100</item>
</string-array>
</resources>   


Without going into great depth in your code. I'd start by looking at lines 61 and 131 in your SmartApp code. This is where the exception is starting in both cases. If in both cases this points to a call using prefs.getInt(), I'd guess that it has something to do with you asking for a int when in fact the original XML entries are Strings.


For your error, I have had a similar problem with my applications and the way I got around this was retrieving the preferences as String objects and then using Integer.parse() to convert the String to a number. It's a bit of a hack but it got the job done for me.

As for your initial question could you maybe have your PreferenceActivity write to a certain specific file when a change is made that the other Activity can check periodically or on it's creation and adjust/pull information accordingly?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜