Open AugPav opened 3 months ago
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!
Note: You can give me feedback by thumbs upping or thumbs downing this comment.
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.
Or you should fix the code for each of the platform
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?
The interface clearly states what the return value is based on:
T Get
(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. Or you should fix the code for each of the platform
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
("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.
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 T Get<T>(...)
. You can be explicit and specify a specific type rather than rely on defaultValue
to imply the return type and generic type. So instead of writing:
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);
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