diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferenceValueType.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferenceValueType.cs
new file mode 100644
index 0000000..461baae
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferenceValueType.cs
@@ -0,0 +1,32 @@
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 定义PreferencesValue的数据类型。
+///
+public enum PreferenceValueType
+{
+ ///
+ /// 空类型。
+ ///
+ PREFERENCE_TYPE_NULL = 0,
+
+ ///
+ /// 整型类型。
+ ///
+ PREFERENCE_TYPE_INT,
+
+ ///
+ /// 布尔类型。
+ ///
+ PREFERENCE_TYPE_BOOL,
+
+ ///
+ /// 字符串类型。
+ ///
+ PREFERENCE_TYPE_STRING,
+
+ ///
+ /// 结束类型。
+ ///
+ PREFERENCE_TYPE_BUTT
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesErrCode.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesErrCode.cs
new file mode 100644
index 0000000..d4f1d83
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesErrCode.cs
@@ -0,0 +1,52 @@
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 声明首选项模块统一使用的错误码信息。
+///
+public enum PreferencesErrCode
+{
+ ///
+ /// 操作执行成功。
+ ///
+ PREFERENCES_OK = 0,
+
+ ///
+ /// 参数不合法。
+ ///
+ PREFERENCES_ERROR_INVALID_PARAM = 401,
+
+ ///
+ /// 系统能力不支持。
+ ///
+ PREFERENCES_ERROR_NOT_SUPPORTED = 801,
+
+ ///
+ /// 基准错误码。
+ ///
+ PREFERENCES_ERROR_BASE = 15500000,
+
+ ///
+ /// 删除文件失败。
+ ///
+ PREFERENCES_ERROR_DELETE_FILE = 15500010,
+
+ ///
+ /// 存储异常。
+ ///
+ PREFERENCES_ERROR_STORAGE = 15500011,
+
+ ///
+ /// 申请内存失败。
+ ///
+ PREFERENCES_ERROR_MALLOC = 15500012,
+
+ ///
+ /// Key不存在。
+ ///
+ PREFERENCES_ERROR_KEY_NOT_FOUND = 15500013,
+
+ ///
+ /// 获取数据变更订阅服务失败。
+ ///
+ PREFERENCES_ERROR_GET_DATAOBSMGRCLIENT = 15500019
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesStorageType.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesStorageType.cs
new file mode 100644
index 0000000..5657d9b
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Enums/PreferencesStorageType.cs
@@ -0,0 +1,17 @@
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 首选项配置选项的存储模式枚举。
+///
+public enum PreferencesStorageType
+{
+ ///
+ /// XML存储模式,对数据的操作发生在内存中,调用OH_Preferences_Close时落盘,不支持多进程。
+ ///
+ PREFERENCES_STORAGE_XML = 0,
+
+ ///
+ /// GSKV存储模式,对数据的操作实时落盘,可支持多进程
+ ///
+ PREFERENCES_STORAGE_GSKV,
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/Preferences.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/Preferences.cs
new file mode 100644
index 0000000..1521f7c
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/Preferences.cs
@@ -0,0 +1,391 @@
+using System.Runtime.InteropServices;
+
+using OpenHarmony.NDK.Bindings.Native;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 表示首选项数据变更的委托
+///
+/// 发生变更的键列表
+public delegate void PreferencesDataChangedHandler(PreferencesPair keys);
+
+///
+/// 提供访问 对象的接口与数据结构。
+///
+public unsafe partial class Preferences : IDisposable
+{
+ ///
+ /// 指向原生Preferences实例的指针。
+ ///
+ internal OH_Preferences* NativeInstance;
+
+ ///
+ /// 存储注册的观察者回调
+ ///
+ private static readonly Dictionary _observers = [];
+
+ ///
+ /// 用于生成订阅唯一标识符的计数器
+ ///
+ private static ulong _nextId = 0;
+
+ ///
+ /// 指示是否已释放资源。
+ ///
+ private bool _disposedValue;
+
+ private Preferences(OH_Preferences* preferences)
+ {
+ NativeInstance = preferences;
+ }
+
+ ///
+ /// 打开一个Preferences实例对象并创建指向它的指针。当不再需要使用指针时,请使用OH_Preferences_Close关闭实例对象。
+ ///
+ ///
+ ///
+ ///
+ public static Preferences Open(PreferencesOption option, ref int errCode)
+ {
+ fixed (int* errCodePtr = &errCode)
+ {
+ var preferences = OH_NativeApi.OH_Preferences_Open(option.NativeInstance, errCodePtr);
+
+ return new Preferences(preferences);
+ }
+ }
+
+ ///
+ /// 关闭一个Preferences实例对象。
+ ///
+ ///
+ ///
+ public int Close()
+ {
+ return OH_NativeApi.OH_Preferences_Close(NativeInstance);
+ }
+
+ ///
+ /// 获取Preferences实例对象中Key对应的整型值。
+ ///
+ ///
+ ///
+ ///
+ public int GetInt(string key, ref int value)
+ {
+ using var keyPtr = key.ToPointer();
+ fixed (int* valuePtr = &value)
+ {
+ return OH_NativeApi.OH_Preferences_GetInt(NativeInstance, keyPtr, valuePtr);
+ }
+ }
+
+ ///
+ /// 获取Preferences实例对象中Key对应的布尔值。
+ ///
+ ///
+ ///
+ ///
+ public int GetBool(string key, ref bool value)
+ {
+ using var keyPtr = key.ToPointer();
+ fixed (bool* valuePtr = &value)
+ {
+ return OH_NativeApi.OH_Preferences_GetBool(NativeInstance, keyPtr, valuePtr);
+ }
+ }
+
+ ///
+ /// 获取Preferences实例对象中Key对应的字符串。
+ ///
+ ///
+ ///
+ ///
+ public int GetString(string key, ref string value)
+ {
+ using var keyPtr = key.ToPointer();
+ char* stringPtr = null;
+ uint stringLen = 0;
+
+ // 调用正确的底层方法
+ int result = OH_NativeApi.OH_Preferences_GetString(NativeInstance, key, &stringPtr, &stringLen);
+
+ if (result == 0 && stringPtr != null)
+ {
+ // 将 char* 转换为 managed string
+ value = Marshal.PtrToStringUTF8((IntPtr)stringPtr, (int)stringLen);
+
+ // 释放原生字符串内存
+ OH_NativeApi.OH_Preferences_FreeString(stringPtr);
+ }
+
+ return result;
+ }
+
+ /* 此处由于不向C#传递非托管string, 因此不再需要释放
+ ///
+ /// 释放从Preferences实例对象中获取的字符串。
+ ///
+ ///
+ ///
+ public void OH_Preferences_FreeString(char* @string);
+ */
+
+ ///
+ /// 根据Key设置Preferences实例对象中的整型值。
+ ///
+ ///
+ ///
+ ///
+ public int SetInt(string key, int value)
+ {
+ using var keyPtr = key.ToPointer();
+ return OH_NativeApi.OH_Preferences_SetInt(NativeInstance, keyPtr, value);
+ }
+
+ ///
+ /// 根据Key设置Preferences实例对象中的布尔值。
+ ///
+ ///
+ ///
+ ///
+ public int SetBool(string key, bool value)
+ {
+ using var keyPtr = key.ToPointer();
+ return OH_NativeApi.OH_Preferences_SetBool(NativeInstance, keyPtr, value);
+ }
+
+ ///
+ /// 根据Key设置Preferences实例对象中的字符串。
+ ///
+ ///
+ ///
+ ///
+ public int SetString(string key, string value)
+ {
+ using var keyPtr = key.ToPointer();
+ using var valuePtr = value.ToPointer();
+ return OH_NativeApi.OH_Preferences_SetString(NativeInstance, keyPtr, valuePtr);
+ }
+
+ ///
+ /// 在Preferences实例对象中删除Key对应的KV数据。
+ ///
+ ///
+ ///
+ public int Delete(string key)
+ {
+ using var keyPtr = key.ToPointer();
+ return OH_NativeApi.OH_Preferences_Delete(NativeInstance, keyPtr);
+ }
+
+ ///
+ /// 本地回调的静态桥接方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static unsafe void NativeObserverCallback(ulong id, void* context, OH_PreferencesPair* keys, uint count)
+ {
+ if (_observers.TryGetValue(id, out var observerData))
+ {
+ var pairs = new PreferencesPair(keys, count);
+ // 调用托管回调
+ observerData.Callback?.Invoke(pairs);
+ }
+ }
+
+ ///
+ /// 对选取的Key注册数据变更订阅。订阅的Key的值发生变更后,在调用OH_Preferences_Close()后触发回调。
+ ///
+ /// 当数据变更时要执行的回调
+ /// 要监听的键数组
+ /// 操作结果代码,0表示成功
+ public unsafe int RegisterDataObserver(PreferencesDataChangedHandler callback, string[] keys)
+ {
+ if (keys == null || keys.Length == 0 || callback == null)
+ {
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM;
+ }
+
+ // 创建唯一的回调标识符
+ var id = Interlocked.Increment(ref _nextId);
+
+ // 创建并存储静态委托实例,防止被垃圾回收
+ OH_PreferencesDataObserver nativeCallback = new((context, pairs, count) => NativeObserverCallback(id, context, pairs, count));
+ var observerHandle = Marshal.GetFunctionPointerForDelegate(nativeCallback);
+
+ // 存储回调和委托句柄以防垃圾回收
+ _observers[id] = (callback, nativeCallback, observerHandle);
+
+ // 创建非托管字符串数组
+ char*[] unmanagedKeys = new char*[keys.Length];
+
+ try
+ {
+ // 为每个字符串分配内存并复制
+ for (int i = 0; i < keys.Length; i++)
+ {
+ if (keys[i] != null)
+ {
+ using var ptr = keys[i].ToPointer();
+ var keyPtr = (char*)ptr.Pointer;
+ int len = keys[i].Length;
+ unmanagedKeys[i] = (char*)Marshal.AllocHGlobal((len + 1) * sizeof(char));
+ for (int j = 0; j < len; j++)
+ {
+ unmanagedKeys[i][j] = keyPtr[j];
+ }
+ unmanagedKeys[i][len] = '\0';
+ }
+ }
+
+ return OH_NativeApi.OH_Preferences_RegisterDataObserver(NativeInstance, null, observerHandle, unmanagedKeys, (uint)keys.Length);
+ }
+ catch
+ {
+ // 发生异常时,清理资源
+ if (_observers.TryGetValue(id, out var observerData))
+ {
+ _observers.Remove(id);
+ }
+ return -1;
+ }
+ finally
+ {
+ // 释放分配的内存
+ for (int i = 0; i < unmanagedKeys.Length; i++)
+ {
+ if (unmanagedKeys[i] != null)
+ {
+ Marshal.FreeHGlobal((IntPtr)unmanagedKeys[i]);
+ }
+ }
+ }
+ }
+
+ ///
+ /// 取消注册选取Key的数据变更订阅。
+ ///
+ /// 之前注册的回调
+ /// 要取消监听的键数组
+ /// 操作结果代码,0表示成功
+ public unsafe int UnregisterDataObserver(PreferencesDataChangedHandler callback, string[] keys)
+ {
+ if (keys == null || keys.Length == 0 || callback == null)
+ {
+ Hilog.OH_LOG_DEBUG(LogType.LOG_APP, "Preferences", $"UnregisterDataObserver: Invalid parameters, {keys == null} {keys?.Length == 0} {callback == null} ");
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM;
+ }
+
+ // 查找对应的上下文标识符
+ ulong? contextToRemove = null;
+ foreach (var entry in _observers)
+ {
+ if (entry.Value.Callback == callback)
+ {
+ contextToRemove = entry.Key;
+ break;
+ }
+ }
+
+ if (!contextToRemove.HasValue)
+ {
+ // 未找到匹配的观察者
+ return (int)PreferencesErrCode.PREFERENCES_OK;
+ }
+
+ // 创建非托管字符串数组
+ char*[] unmanagedKeys = new char*[keys.Length];
+
+ try
+ {
+ // 为每个字符串分配内存并复制
+ for (int i = 0; i < keys.Length; i++)
+ {
+ if (keys[i] != null)
+ {
+ using var ptr = keys[i].ToPointer();
+ var keyPtr = (char*)ptr.Pointer;
+ int len = keys[i].Length;
+ unmanagedKeys[i] = (char*)Marshal.AllocHGlobal((len + 1) * sizeof(char));
+ for (int j = 0; j < len; j++)
+ {
+ unmanagedKeys[i][j] = keyPtr[j];
+ }
+ unmanagedKeys[i][len] = '\0';
+
+ }
+ }
+
+ // 获取与此回调关联的原生委托
+ if (_observers.TryGetValue(contextToRemove.Value, out var observerData))
+ {
+ int result = OH_NativeApi.OH_Preferences_UnregisterDataObserver(NativeInstance, null, observerData.ObserverHandle, unmanagedKeys, (uint)keys.Length);
+
+ // 释放委托句柄并从字典中移除
+ _observers.Remove(contextToRemove.Value);
+ return result;
+ }
+
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM; ;
+ }
+ finally
+ {
+ // 释放分配的内存
+ for (int i = 0; i < unmanagedKeys.Length; i++)
+ {
+ if (unmanagedKeys[i] != null)
+ {
+ Marshal.FreeHGlobal((IntPtr)unmanagedKeys[i]);
+ }
+ }
+ }
+ }
+
+ ///
+ /// 校验当前平台是否支持对应存储模式。
+ ///
+ ///
+ ///
+ ///
+ public int IsStorageTypeSupported(PreferencesStorageType type, ref bool isSupported)
+ {
+ fixed (bool* isSupportedPtr = &isSupported)
+ {
+ return OH_NativeApi.OH_Preferences_IsStorageTypeSupported(type, isSupportedPtr);
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // TODO: 释放托管状态(托管对象)
+
+ }
+
+ // TODO: 释放未托管的资源(未托管的对象)并重写终结器
+ // TODO: 将大型字段设置为 null
+ _disposedValue = true;
+ }
+ }
+
+ // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
+ ~Preferences()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesOption.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesOption.cs
new file mode 100644
index 0000000..82976da
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesOption.cs
@@ -0,0 +1,127 @@
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 提供访问 对象的接口与数据结构。
+///
+public unsafe partial class PreferencesOption : IDisposable
+{
+ internal OH_PreferencesOption* NativeInstance;
+ private bool _disposedValue;
+
+ ///
+ /// 创建一个Preferences配置选项。当不再需要使用时,请使用Destroy销毁实例对象,否则会导致内存泄漏。
+ ///
+ public PreferencesOption()
+ {
+ NativeInstance = OH_NativeApi.OH_PreferencesOption_Create();
+ }
+
+ ///
+ /// 设置Preferences配置选项的文件名称。
+ ///
+ ///
+ ///
+ public int SetFileName(string fileName)
+ {
+ ObjectDisposedException.ThrowIf(_disposedValue, this);
+
+ fixed (char* fileNameBuffer = fileName)
+ {
+ return OH_NativeApi.OH_PreferencesOption_SetFileName(NativeInstance, fileNameBuffer);
+ }
+ }
+
+ ///
+ /// 设置Preferences配置选项的包名称。
+ ///
+ ///
+ ///
+ public int SetBundleName(string bundleName)
+ {
+ ObjectDisposedException.ThrowIf(_disposedValue, this);
+
+ fixed (char* bundleNameBuffer = bundleName)
+ {
+ return OH_NativeApi.OH_PreferencesOption_SetBundleName(NativeInstance, bundleNameBuffer);
+ }
+ }
+
+ ///
+ /// 设置Preferences配置选项的应用组ID。设置应用组ID后,会指定在此应用组ID对应的沙箱路径下创建Preferences实例。应用组ID需要向应用市场获取,暂不支持。当传入的应用组ID为空字符串时,默认在本应用沙箱目录下创建Preferences实例。
+ ///
+ ///
+ ///
+ public int SetDataGroupId(string dataGroupId)
+ {
+ ObjectDisposedException.ThrowIf(_disposedValue, this);
+
+ fixed (char* dataGroupIdBuffer = dataGroupId)
+ {
+ return OH_NativeApi.OH_PreferencesOption_SetDataGroupId(NativeInstance, dataGroupIdBuffer);
+ }
+ }
+
+ ///
+ /// 设置Preferences实例的存储模式。
+ ///
+ ///
+ ///
+ public int SetStorageType(PreferencesStorageType type)
+ {
+ ObjectDisposedException.ThrowIf(_disposedValue, this);
+
+ return OH_NativeApi.OH_PreferencesOption_SetStorageType(NativeInstance, type);
+ }
+
+ ///
+ /// 销毁Preferences配置选项实例。
+ ///
+ ///
+ public int Destroy()
+ {
+ if (null != NativeInstance)
+ {
+ var retCode = OH_NativeApi.OH_PreferencesOption_Destroy(NativeInstance);
+ NativeInstance = null;
+ return retCode;
+ }
+
+ return 0;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // TODO: 释放托管状态(托管对象)
+ }
+
+ // TODO: 释放未托管的资源(未托管的对象)并重写终结器
+ // TODO: 将大型字段设置为 null
+
+ if (null != NativeInstance)
+ {
+ _ = OH_NativeApi.OH_PreferencesOption_Destroy(NativeInstance);
+ NativeInstance = null;
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
+ ~PreferencesOption()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesPair.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesPair.cs
new file mode 100644
index 0000000..43ddb4a
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesPair.cs
@@ -0,0 +1,131 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 提供访问 对象的接口与数据结构。
+///
+public unsafe partial class PreferencesPair
+{
+ internal OH_PreferencesPair* NativeInstance;
+
+ ///
+ /// 创建一个 PreferencesPair 实例
+ ///
+ /// 原生键值对数组指针
+ /// 键值对数量
+ public PreferencesPair(OH_PreferencesPair* nativePairs, uint count)
+ {
+ NativeInstance = nativePairs;
+ Count = count;
+ }
+
+ ///
+ /// 键值对的数量
+ ///
+ public uint Count { get; }
+
+ ///
+ /// 获取指定索引位置的键。
+ ///
+ /// 索引位置
+ /// 键的字符串,如果失败返回null
+ public string? GetKey(uint index)
+ {
+ if (NativeInstance == null || index >= Count)
+ {
+ return null;
+ }
+
+ char* keyPtr = OH_NativeApi.OH_PreferencesPair_GetKey(NativeInstance, index);
+ return Marshal.PtrToStringUTF8((IntPtr)keyPtr);
+ }
+
+ ///
+ /// 获取指定索引位置的值。
+ ///
+ /// 索引位置
+ /// 值
+ public PreferencesValue? GetValue(uint index)
+ {
+ if (NativeInstance == null || index >= Count)
+ {
+ return null;
+ }
+
+ OH_PreferencesValue* valuePtr = OH_NativeApi.OH_PreferencesPair_GetPreferencesValue(NativeInstance, index);
+ if (valuePtr == null)
+ {
+ return null;
+ }
+
+ return new PreferencesValue(valuePtr);
+ }
+}
+
+///
+/// 提供对 的扩展方法。
+///
+public static class PreferencesPairExtensions
+{
+ ///
+ /// 获取指定索引位置的值类型。
+ ///
+ /// 索引位置
+ /// 值的类型
+ public unsafe static PreferenceValueType GetValueType(this PreferencesPair pairs, uint index)
+ {
+ if (pairs == null || pairs.NativeInstance == null || index >= pairs.Count)
+ {
+ return PreferenceValueType.PREFERENCE_TYPE_NULL;
+ }
+
+ OH_PreferencesValue* valuePtr = OH_NativeApi.OH_PreferencesPair_GetPreferencesValue(pairs.NativeInstance, index);
+ if (valuePtr == null)
+ {
+ return PreferenceValueType.PREFERENCE_TYPE_NULL;
+ }
+
+ return OH_NativeApi.OH_PreferencesValue_GetValueType(valuePtr);
+ }
+
+ ///
+ /// 获取指定索引位置的值。
+ ///
+ /// PreferencesPair 实例
+ /// 索引位置
+ /// 值
+ public unsafe static (string key, PreferenceValueType type, object? value) GetValue(this PreferencesPair pairs, uint index)
+ {
+ if (pairs == null || pairs.NativeInstance == null || index >= pairs.Count)
+ {
+ return (string.Empty, PreferenceValueType.PREFERENCE_TYPE_NULL, null);
+ }
+ string key = pairs.GetKey(index) ?? string.Empty;
+ PreferenceValueType type = pairs.GetValueType(index);
+ PreferencesValue? value = pairs.GetValue(index);
+ object? valueData = null;
+ if (value != null)
+ {
+ switch (type)
+ {
+ case PreferenceValueType.PREFERENCE_TYPE_INT:
+ int intValue = 0;
+ value.GetInt(ref intValue);
+ valueData = intValue;
+ break;
+ case PreferenceValueType.PREFERENCE_TYPE_BOOL:
+ bool boolValue = false;
+ value.GetBool(ref boolValue);
+ valueData = boolValue;
+ break;
+ case PreferenceValueType.PREFERENCE_TYPE_STRING:
+ string stringValue = string.Empty;
+ value.GetString(ref stringValue);
+ valueData = stringValue;
+ break;
+ }
+ }
+ return (key, type, valueData);
+ }
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesValue.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesValue.cs
new file mode 100644
index 0000000..9f065ae
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Managed/PreferencesValue.cs
@@ -0,0 +1,96 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 提供访问 对象的接口与数据结构。
+///
+public unsafe partial class PreferencesValue
+{
+ internal OH_PreferencesValue* NativeInstance;
+
+ ///
+ /// 创建一个 PreferencesValue 实例
+ ///
+ /// 原生 PreferencesValue 指针
+ internal PreferencesValue(OH_PreferencesValue* nativeValue)
+ {
+ NativeInstance = nativeValue;
+ }
+
+ ///
+ /// 获取当前值的数据类型。
+ ///
+ /// 值的数据类型
+ public PreferenceValueType GetValueType()
+ {
+ if (NativeInstance == null)
+ {
+ return PreferenceValueType.PREFERENCE_TYPE_NULL;
+ }
+
+ return OH_NativeApi.OH_PreferencesValue_GetValueType(NativeInstance);
+ }
+
+ ///
+ /// 获取整型值。
+ ///
+ /// 输出的整型值
+ /// 操作结果,0表示成功
+ public int GetInt(ref int value)
+ {
+ if (NativeInstance == null)
+ {
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM;
+ }
+
+ fixed (int* valuePtr = &value)
+ {
+ return OH_NativeApi.OH_PreferencesValue_GetInt(NativeInstance, valuePtr);
+ }
+ }
+
+ ///
+ /// 获取布尔值。
+ ///
+ /// 输出的布尔值
+ /// 操作结果,0表示成功
+ public int GetBool(ref bool value)
+ {
+ if (NativeInstance == null)
+ {
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM;
+ }
+
+ fixed (bool* valuePtr = &value)
+ {
+ return OH_NativeApi.OH_PreferencesValue_GetBool(NativeInstance, valuePtr);
+ }
+ }
+
+ ///
+ /// 获取字符串值。
+ ///
+ /// 输出的字符串值
+ /// 操作结果,0表示成功
+ public int GetString(ref string value)
+ {
+ if (NativeInstance == null)
+ {
+ return (int)PreferencesErrCode.PREFERENCES_ERROR_INVALID_PARAM;
+ }
+
+ char* stringPtr = null;
+ uint stringLen = 0;
+
+ int result = OH_NativeApi.OH_PreferencesValue_GetString(NativeInstance, &stringPtr, &stringLen);
+
+ if (result == 0 && stringPtr != null)
+ {
+ // 将 char* 转换为 managed string
+ value = Marshal.PtrToStringUTF8((IntPtr)stringPtr, (int)stringLen);
+ }
+
+ return result;
+ }
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_NativeApi.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_NativeApi.cs
new file mode 100644
index 0000000..ca79a4a
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_NativeApi.cs
@@ -0,0 +1,237 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings
+{
+ ///
+ /// 提供 OpenHarmony NativeApi 的 P/Invoke 方法封装
+ ///
+ public static unsafe partial class OH_NativeApi
+ {
+ #region OH_Preferences
+
+ ///
+ /// 打开一个Preferences实例对象并创建指向它的指针。当不再需要使用指针时,请使用OH_Preferences_Close关闭实例对象。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial OH_Preferences* OH_Preferences_Open(OH_PreferencesOption* option, int* errCode);
+
+ ///
+ /// 关闭一个Preferences实例对象。
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_Close(OH_Preferences* preference);
+ ///
+ /// 获取Preferences实例对象中Key对应的整型值。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_GetInt(OH_Preferences* preference, char* key, int* value);
+
+ ///
+ /// 获取Preferences实例对象中Key对应的布尔值。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_GetBool(OH_Preferences* preference, char* key, bool* value);
+
+ ///
+ /// 获取Preferences实例对象中Key对应的字符串。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so", StringMarshalling = StringMarshalling.Utf8)]
+ public static partial int OH_Preferences_GetString(OH_Preferences* preference, string key, char** value, uint* valueLen);
+
+ ///
+ /// 释放从Preferences实例对象中获取的字符串。
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial void OH_Preferences_FreeString(char* @string);
+
+ ///
+ /// 根据Key设置Preferences实例对象中的整型值。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_SetInt(OH_Preferences* preference, char* key, int value);
+
+ ///
+ /// 根据Key设置Preferences实例对象中的布尔值。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_SetBool(OH_Preferences* preference, char* key, [MarshalAs(UnmanagedType.Bool)] bool value);
+
+ ///
+ /// 根据Key设置Preferences实例对象中的字符串。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_SetString(OH_Preferences* preference, char* key, char* value);
+
+ ///
+ /// 在Preferences实例对象中删除Key对应的KV数据。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_Delete(OH_Preferences* preference, char* key);
+
+ ///
+ /// 对选取的Key注册数据变更订阅。订阅的Key的值发生变更后,在调用OH_Preferences_Close()后触发回调。
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_RegisterDataObserver(OH_Preferences* preference, void* context, IntPtr observer, char*[] keys, uint keyCount);
+
+ ///
+ /// 取消注册选取Key的数据变更订阅。
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_UnregisterDataObserver(OH_Preferences* preference, void* context, IntPtr observer, char*[] keys, uint keyCount);
+
+ ///
+ /// 校验当前平台是否支持对应存储模式。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_Preferences_IsStorageTypeSupported(PreferencesStorageType type, bool* isSupported);
+ #endregion
+
+ #region OH_PreferencesOption
+
+ ///
+ /// 创建一个Preferences配置选项的OH_PreferencesOption实例对象以及指向它的指针。当不再需要使用指针时,请使用OH_PreferencesOption_Destroy销毁实例对象,否则会导致内存泄漏。
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial OH_PreferencesOption* OH_PreferencesOption_Create();
+
+ ///
+ /// 设置Preferences配置选项OH_PreferencesOption实例对象的文件名称。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesOption_SetFileName(OH_PreferencesOption* option, char* fileName);
+
+ ///
+ /// 设置Preferences配置选项OH_PreferencesOption实例对象的包名称。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesOption_SetBundleName(OH_PreferencesOption* option, char* bundleName);
+
+ ///
+ /// 设置Preferences配置选项OH_PreferencesOption实例对象的应用组ID。设置应用组ID后,会指定在此应用组ID对应的沙箱路径下创建Preferences实例。应用组ID需要向应用市场获取,暂不支持。当传入的应用组ID为空字符串时,默认在本应用沙箱目录下创建Preferences实例。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesOption_SetDataGroupId(OH_PreferencesOption* option, char* dataGroupId);
+
+ ///
+ /// 设置Preferences实例对象的存储模式。
+ ///
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesOption_SetStorageType(OH_PreferencesOption* option, PreferencesStorageType type);
+
+ ///
+ /// 销毁Preferences配置选项OH_PreferencesOption实例。
+ ///
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesOption_Destroy(OH_PreferencesOption* option);
+
+ #endregion
+
+ #region OH_PreferencesPair
+
+ ///
+ /// 获取KV数据中索引对应数据的键。
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial char* OH_PreferencesPair_GetKey(OH_PreferencesPair* pairs, uint index);
+
+ ///
+ /// 获取KV数据数组中索引对应的值。
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial OH_PreferencesValue* OH_PreferencesPair_GetPreferencesValue(OH_PreferencesPair* pairs, uint index);
+
+ #endregion
+
+ #region OH_PreferencesValue
+
+ ///
+ /// 获取PreferencesValue对象的数据类型。
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial PreferenceValueType OH_PreferencesValue_GetValueType(OH_PreferencesValue* @object);
+
+ ///
+ /// 从PreferencesValue对象OH_PreferencesValue中获取一个整型值。
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesValue_GetInt(OH_PreferencesValue* @object, int* value);
+
+ ///
+ /// 从PreferencesValue对象OH_PreferencesValue中获取一个布尔值。
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesValue_GetBool(OH_PreferencesValue* @object, bool* value);
+
+ ///
+ /// 从PreferencesValue对象OH_PreferencesValue中获取字符串。
+ ///
+ ///
+ [LibraryImport("libohpreferences.so")]
+ public static partial int OH_PreferencesValue_GetString(OH_PreferencesValue* @object, char** value, uint* valueLen);
+
+ #endregion
+ }
+}
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_Preferences.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_Preferences.cs
new file mode 100644
index 0000000..4449c82
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_Preferences.cs
@@ -0,0 +1,18 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 定义Preferences对象类型。
+///
+[StructLayout(LayoutKind.Sequential)]
+public struct OH_Preferences;
+
+///
+/// Preferences数据变更观察者回调函数类型。
+///
+/// 用户上下文数据
+/// 变更的键值对数组
+/// 变更的键值对数量
+[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+public unsafe delegate void OH_PreferencesDataObserver(void* context, OH_PreferencesPair* pairs, uint count);
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesOption.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesOption.cs
new file mode 100644
index 0000000..894b69e
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesOption.cs
@@ -0,0 +1,9 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 定义Preferences配置选项的数据结构。
+///
+[StructLayout(LayoutKind.Sequential)]
+public struct OH_PreferencesOption;
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesPair.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesPair.cs
new file mode 100644
index 0000000..94ee640
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesPair.cs
@@ -0,0 +1,9 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 定义Preferences使用的KV数据对象类型。
+///
+[StructLayout(LayoutKind.Sequential)]
+public struct OH_PreferencesPair;
diff --git a/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesValue.cs b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesValue.cs
new file mode 100644
index 0000000..d2ff127
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/ArkData/Preferences/Native/OH_PreferencesValue.cs
@@ -0,0 +1,9 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings;
+
+///
+/// 定义PreferencesValue对象类型。
+///
+[StructLayout(LayoutKind.Sequential)]
+public struct OH_PreferencesValue;
diff --git a/OpenHarmony.NDK.Bindings/Extension/DisposablePointer.cs b/OpenHarmony.NDK.Bindings/Extension/DisposablePointer.cs
new file mode 100644
index 0000000..4462bb6
--- /dev/null
+++ b/OpenHarmony.NDK.Bindings/Extension/DisposablePointer.cs
@@ -0,0 +1,108 @@
+using System.Runtime.InteropServices;
+
+namespace OpenHarmony.NDK.Bindings
+{
+ ///
+ /// 提供字符串到 的转换扩展方法
+ ///
+ public static class DisposablePointerExtension
+ {
+ ///
+ /// 将字符串转换为 ,分配非托管内存
+ ///
+ ///
+ ///
+ public static DisposablePointer ToPointer(this string str)
+ {
+ if (str == null)
+ {
+ return new DisposablePointer(IntPtr.Zero);
+ }
+
+ // 分配非托管内存
+ IntPtr ptr = Marshal.StringToHGlobalAnsi(str);
+ return new DisposablePointer(ptr);
+ }
+ }
+
+ ///
+ /// MarshalPtr类用于管理非托管内存的分配和释放
+ ///
+ public class DisposablePointer : IDisposable
+ {
+ ///
+ /// 指示是否已释放资源
+ ///
+ private bool _disposedValue;
+
+ ///
+ /// 指向分配的非托管内存的指针
+ ///
+ public IntPtr Pointer { get; private set; }
+
+ ///
+ /// 构造函数,初始化指针
+ ///
+ /// 非托管内存的指针
+ public DisposablePointer(IntPtr ptr)
+ {
+ Pointer = ptr;
+ }
+
+ ///
+ /// 提供从DisposablePointer到IntPtr的隐式转换
+ ///
+ /// 可释放的指针对象
+ public static implicit operator IntPtr(DisposablePointer disposablePointer)
+ {
+ return disposablePointer?.Pointer ?? IntPtr.Zero;
+ }
+
+ ///
+ /// 提供从DisposablePointer到char*的隐式转换
+ ///
+ /// 可释放的指针对象
+ public static unsafe implicit operator char*(DisposablePointer disposablePointer)
+ {
+ if (disposablePointer == null || disposablePointer.Pointer == IntPtr.Zero)
+ {
+ return null;
+ }
+
+ return (char*)disposablePointer.Pointer;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (Pointer != IntPtr.Zero)
+ {
+ // 释放分配的非托管内存
+ Marshal.FreeHGlobal(Pointer);
+
+ // 将指针重置为零
+ Pointer = IntPtr.Zero;
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ ///
+ /// 析构函数,释放非托管资源
+ ///
+ ~DisposablePointer()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}