我正在将我当前的 Android 应用程序更新为 flutter。是否可以使用flutter上的shared_preferences插件访问android应用程序中使用的sharedPreferences。
因此,当用户更新应用程序时,他们会直接登录。
您可以使用这个包native_shared_preferences, 有一些方法可以帮助您喜欢(containsKey(),getKeys())。
这个包native_shared_preferences存储时不给键添加前缀。与此包shared_preferences不同,它总是为使用它存储的每个变量添加前缀
前缀:“flutter_”
这是我从本机应用程序获取必要的令牌和一个 int 值的方法。
首先,您需要 path_provider 来查找必要的文件,plist_parser 用于 iO,因为 iO 将用户默认值存储为 .plist 文件,以及 xml 来读取 Android 中具有共享首选项的 .xml 文件。
如何查找 iO 原生值:
if (Platform.isIOS) {
// Find the dir of the app.
final appDocumentsDir = await getLibraryDirectory();
// Create a list of contents in this dir, which includes files and dirs.
List contents = appDocumentsDir.listSync();
// Find in the list the dir with user preferences
Directory? prefsDir = contents.firstWhereOrNull((element) => element is Directory && element.path.contains('Preferences'));
if (prefsDir != null) {
// Get contents of the dir named 'Preferences'
List subContents = prefsDir.listSync();
// Find .plist file with package name of your app.
File? prefsFile = subContents.firstWhereOrNull((element) => element is File && element.path.contains('com.your_app.plist'));
if (prefsFile != null) {
// Parse the file
final plist = PlistParser().parseBinaryFileSync(prefsFile.path);
// With loop find necessary items
for (final item in plist.entries) {
if (item.key == 'access_token') {
print('${item.value as String}');
// your code to handle the value
}
if (item.key == 'city_id') {
print('${item.value as int}');
// your code to handle the value
}
// An example to get stored data of Swift struct
if (item.key == 'selectedCity') {
// Create decoder
const asciiDecoder = AsciiDecoder();
// Get ASCII value, which stored like [56, 104, 92 ...]
final asciiValues = item.value;
// Convert it to string.
// It returns json string
final cityJson = asciiDecoder.convert(asciiValues);
// Convert json to the class with its factory.
// You may use https://app.quicktype.io to convert JSON
// to Flutter class and create necessary factories
final city = City.fromRawJson(cityJson);
// your code to handle the object of this class
}
}
}
}
}
如何从 Android 中的共享首选项中获取值。
import 'package:xml/xml.dart' as xml;
// Name it somehow you like for example 'xml' as far as it conflicts with dart.io
// You will need dart.io for Platform
if (Platform.isAndroid) {
// Find the dir of you app by package name
final appDocumentsDir = Directory('/data/data/com.your_app');
// Create a list of contents in this dir, which includes files and dirs.
List contents = appDocumentsDir.listSync();
// Find in the list the dir with shared preferences
Directory? prefsDir = contents.firstWhereOrNull((element) => element is Directory && element.path.contains('shared_prefs'));
if (prefsDir != null) {
// Get contents of the dir named shared_prefs
List subContents = prefsDir.listSync();
// Find .xml file with shared preferences.
// Check the name of this file in native code, or
// find it in Device Explorer of Android Studio.
File? prefsFile = subContents.firstWhereOrNull((element) => element is File && element.path.contains('your_name.xml'));
if (prefsFile != null) {
// Create XML document
final document = xml.XmlDocument.parse(prefsFile.readAsStringSync());
// Loop from root to children
for (final items in document.children) {
// Loop for each child
for (final item in items.childElements) {
// Read item as Sting
final itemString = item.outerXml;
// Check for your name in prefs
if (itemString.contains('access_token')) {
// If prefs store it as String it will look like
// '<string name="access_token">the token value</string>'
// Get the value in this key
final value = item.innerXml;
// your code to handle the value
}
// For int or float you need to do something different.
// Because prefs store it like '<int name="city_id" value="3" />'
if (itemString.contains('city_id')) {
// 'item.attributes' will return a list like
// [name="city_id", value="3"]
// and you need to get second value and parse it to int
final cityId = int.parse(item.attributes[1].value);
// You code to handle the value 'cityId'
}
}
}
}
}
}
}
.firstWhereOrNull 是来自 getX 非常有用的库的函数。 或者您可以使用下面的扩展。
extension IterableX<T> on Iterable<T> {
T? firstWhereOrNull(bool Function(T) test) {
T? firstItem;
for (var item in this) {
if (test(item)) {
firstItem = item;
break;
}
}
return firstItem;
}
}