如何在不同Flutter应用之间共享SharedPreferences存储数据?
Flutter官方维护的shared_preferences插件默认仅支持读取当前应用自身的SharedPreferences数据,未暴露指定第三方应用包名的调用接口,要实现跨Flutter应用的SharedPreferences数据共享,可通过自定义MethodChannel调用原生层能力实现,具体内容如下:
前置注意事项
- 安卓7.0(API 24)及以上系统已官方废弃
MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE权限配置,默认禁止其他应用读取自身应用私有数据,要实现跨应用读写需满足两个条件之一:- 两个应用的
AndroidManifest.xml中配置相同的android:sharedUserId属性,且应用签名完全一致 - 应用的
targetSdkVersion低于24
- 两个应用的
- 不符合上述条件的情况下,原生安卓层本身就无法跨应用读取SharedPreferences,Flutter侧也无法实现对应能力。
具体实现步骤
1. 安卓端注册MethodChannel处理逻辑
在安卓工程的MainActivity中注册自定义方法通道,处理Flutter侧的读取请求,示例代码如下:
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "com.custom.shared_preferences_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "getSharedPreferencesFromOtherApp") { // 获取Flutter侧传入的参数 val targetPackageName = call.argument<String>("packageName") ?: return@setMethodCallHandler result.error("INVALID_PARAM", "包名不能为空", null) val spFileName = call.argument<String>("spFileName") ?: "packagename" val key = call.argument<String>("key") ?: return@setMethodCallHandler result.error("INVALID_PARAM", "key不能为空", null) val defaultValue = call.argument<String>("defaultValue") ?: null try { // 创建目标应用的上下文 val targetContext = createPackageContext(targetPackageName, CONTEXT_IGNORE_SECURITY) // 读取目标应用的SharedPreferences val targetSp = targetContext.getSharedPreferences(spFileName, MODE_PRIVATE) val value = targetSp.getString(key, defaultValue) result.success(value) } catch (e: Exception) { result.error("READ_FAILED", e.localizedMessage, null) } } else { result.notImplemented() } } } }
2. Flutter侧调用通道读取数据
Flutter侧调用已注册的MethodChannel,传入对应参数即可获取目标应用的SharedPreferences数据,示例代码如下:
import 'package:flutter/services.dart'; Future<String?> getOtherAppSharedPreferences({ required String targetPackageName, required String key, String spFileName = "packagename", String? defaultValue, }) async { const MethodChannel channel = MethodChannel("com.custom.shared_preferences_channel"); try { final String? result = await channel.invokeMethod<String>( "getSharedPreferencesFromOtherApp", { "packageName": targetPackageName, "spFileName": spFileName, "key": key, "defaultValue": defaultValue, }, ); return result; } on PlatformException catch (_) { return defaultValue; } }
其他说明
如果需要同时支持iOS端跨应用共享存储数据,可以通过相同的MethodChannel方案调用iOS原生层的App Groups能力实现,逻辑和安卓端一致。
内容的提问来源于stack exchange,提问作者Tim Developer
相关产品推荐
相关产品推荐

