-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] [platform/android] [area-essentials] Shared Preference Android #24397
Comments
Hi I'm an AI powered bot that finds similar issues based off the issue title. Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you! Closed similar issues:
|
The interface clearly states what the return value is based on: T Get<T>(string key, T defaultValue, string? sharedName = null); So in your case, as you found out yourself, you need to use it with the appropriate default value as it controls the return type as well.
How will you infer the type if you are not specifying it explicitly? If you want to cover your behind, then always use the API like: var myVal = Preferences.Get<YourType>("key", defaultValue); Is this even a bug? |
It would be clearer if the Preferences.Get(Shared Name, default value) was changed to Preferences.Get(Shared Name, default value, Type) But that's just my impression. |
How would that work, then the signature would be what exactly? What your impression is, is already implied by the signature of var myValue = Preferences.Get(key, defaultValue); Then you can achieve what you want with: var myValue = Preferences.Get<long>(key, defaultValue); or long myValue = Preferences.Get(key, defaultValue); |
We could also detect thigs like loading an int/short and then load as a long. Then check to see if it fits in the int/short and if it does we can cast to that. Not sure if Android supports storing an int and then loading as long... |
I find that a bit problematic. If you store a long, then cast it to int, what happens if that value is overflowing the int? Runtime error? Something else? |
Description
Error when trying to read a shared preference of type long
Steps to Reproduce
1 - The shared preference is created.
new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds() is of type long
Preferences.Set("SYNC_MASTER_DATE", new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds());
2 - An attempt is made to read the shared preference.
var SyncMasterLast = Preferences.Get("SYNC_MASTER_DATE", 0)
Error
ex {Java.Lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at Java.Interop.JniEnvironment.InstanceMethods.CallIntMethod(JniObjectReference instance, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20203
at Android.Runtime.JNIEnv.CallIntMethod(IntPtr jobject, IntPtr jmethod, JValue* parms) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNIEnv.g.cs:line 192
at Android.Content.ISharedPreferencesInvoker.GetInt(String key, Int32 defValue) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.Content.ISharedPreferences.cs:line 830
at Microsoft.Maui.Storage.PreferencesImplementation.Get[Int32](String key, Int32 defaultValue, String sharedName) in //src/Essentials/src/Preferences/Preferences.android.cs:line 110
at Microsoft.Maui.Storage.Preferences.Get(String key, Int32 defaultValue, String sharedName) in //src/Essentials/src/Preferences/Preferences.shared.cs:line 185
at Microsoft.Maui.Storage.Preferences.Get(String key, Int32 defaultValue) in /_/src/Essentials/src/Preferences/Preferences.shared.cs:line 116
at SelfInspectionMaui.Services.SyncMaster.SyncMasterLogica() in D:\DevRd\SelfInspectionMaui\SelfInspectionMaui\Services\SyncMaster.cs:line 96
--- End of managed Java.Lang.ClassCastException stack trace ---
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at android.app.SharedPreferencesImpl.getInt(SharedPreferencesImpl.java:321)
at mono.java.lang.RunnableImplementor.n_run(Native Method)
at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
--- End of managed Java.Lang.ClassCastException stack trace ---
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at android.app.SharedPreferencesImpl.getInt(SharedPreferencesImpl.java:321)
at mono.java.lang.RunnableImplementor.n_run(Native Method)
at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:31)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
} Java.Lang.ClassCastException
Link to public reproduction project repository
No response
Version with bug
8.0.80 SR8
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
Android
Affected platform versions
Android 14, Android 13
Did you find any workaround?
Why does this error occur?
When trying to read the shared preference, the following code is executed for [Android]
https://github.com/dotnet/maui/blob/cf42c193957a530af1a0551284c40e72e55780f9/src/Essentials/src/Preferences/Preferences.android.cs
On line 17 -
value = sharedPreferences.GetInt(key, i);
- the error occurs because you are trying to read an integer when the shared preference has a long type data.The solution is to read the shared preference with the following code:
var SyncMasterLast = Preferences.Get("SYNC_MASTER_DATE", (long)0)
So, either the documentation is wrong:
https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/storage/preferences?view=net-maui-8.0&tabs=android
Where it says that the second parameter corresponds to the default value, it should say the default value and the type of data to be obtained will be taken from that value.
Or you should fix the code for each of the platform.
Relevant log output
No response
The text was updated successfully, but these errors were encountered: