前言
FlutterUtilCode 是一个 Flutter 东西类调集插件,封装了常用的东西类和函数,便利开发者调用。
本篇是 Flutter东西篇之DeviceUtils,系列文章内容主要介绍插件中东西类的功用、用法和代码完成等,感兴趣的同学可以持续重视。
FlutterUtilCode 系列(一)—— Flutter东西篇之LogUtils、SharedPerfsUtils
FlutterUtilCode 系列(二)—— Flutter东西篇之ToastUtils
FlutterUtilCode 系列(三)—— Flutter东西篇之UuidUtils
FlutterUtilCode 系列(四)—— Flutter东西篇之DeviceUtils
Device东西类-DeviceUtils
在 App 开发中,获取安装设备的信息是十分必要的。这些信息不只可以帮忙开发者了解用户集体、优化应用程序并供给更好的用户体验和服务,还可以协助开发者更好地定位和修正应用程序中的漏洞、错误或其他技术问题,然后保证应用程序始终保持高质量和可靠性。
一般来说,咱们需要获取设备的设备ID、设备品牌、设备类型、体系版别号、体系版别称号等,咱们的 DeviceUtils 就围绕这些信息来完成。
这儿咱们用到了 pub 上的 device_info_plus 。device_info_plus 是一个获取当时设备信息的插件,其 LIKES 数达到了 1.6K 也是十分收欢迎,现在已支撑全渠道。
一、代码完成
DeviceUtils 现在暂只支撑 Android /iOS 渠道设备信息获取,后续会加上其他渠道。
咱们经过 getDeviceData()
方法获取当时渠道的设备信息并缓存下来,便利屡次调用。完成代码如下:
/// 获取设备信息
static Future<Map<String, dynamic>> getDeviceData() async {
if (_deviceData != null) {
return _deviceData!;
}
if (kIsWeb) {
_deviceData = _readWebBrowserInfo(await deviceInfoPlugin.webBrowserInfo);
} else {
_deviceData = switch (defaultTargetPlatform) {
TargetPlatform.android => _readAndroidDeviceInfo(await deviceInfoPlugin.androidInfo),
TargetPlatform.iOS => _readIosDeviceInfo(await deviceInfoPlugin.iosInfo),
TargetPlatform.linux => _readLinuxDeviceInfo(await deviceInfoPlugin.linuxInfo),
TargetPlatform.windows => _readWindowsDeviceInfo(await deviceInfoPlugin.windowsInfo),
TargetPlatform.macOS => _readMacOsDeviceInfo(await deviceInfoPlugin.macOsInfo),
TargetPlatform.fuchsia => <String, dynamic>{'Error:': 'Fuchsia platform isn\'t supported'},
};
}
return _deviceData!;
}
关于设备类型,由于 iOS 和 Android 两个渠道的设备类型是同一个字段,所以咱们只需要经过 model
字段获取即可。
/// 获取设备类型
static Future<String> getModel() async {
Map<String, dynamic> deviceData = await getDeviceData();
return deviceData['model'] ?? '';
}
关于设备品牌,iOS 中是经过 brand
字段获取, Android 中则是经过 name
字段获取。
/// 设备品牌
static Future<String> getBrand() async {
Map<String, dynamic> deviceData = await getDeviceData();
if (kIsWeb) {
return '';
} else {
return switch (defaultTargetPlatform) {
TargetPlatform.android => deviceData['brand'],
TargetPlatform.iOS => deviceData['name'],
TargetPlatform.linux => '',
TargetPlatform.windows => '',
TargetPlatform.macOS => '',
TargetPlatform.fuchsia => '',
};
}
}
关于体系版别号,在 iOS 中经过 systemVersion
字段获取,在 Android 中经过 version.sdkInt
获取。注意 version.sdkInt
获取的是 Android体系的 SDK_INT
,而不是咱们往常称号的 AndroidXX。
关于体系称号,在 iOS 中经过 systemName
字段获取,在 Android 中经过 display
获取。在 iOS 中获取的是 iOS,而在 Android 中获取的是厂商的体系称号,例如:CH6J-H6211V-Q-OP-201215V091。
/// 获取设备体系版别号
static Future<String> getSystemVersion() async {
Map<String, dynamic> deviceData = await getDeviceData();
if (kIsWeb) {
return '';
} else {
return switch (defaultTargetPlatform) {
TargetPlatform.android => '${deviceData['version.sdkInt']}',
TargetPlatform.iOS => '${deviceData['systemVersion']}',
TargetPlatform.linux => '',
TargetPlatform.windows => '',
TargetPlatform.macOS => '',
TargetPlatform.fuchsia => '',
};
}
}
/// 获取设备体系称号
static Future<String> getSystemName() async {
Map<String, dynamic> deviceData = await getDeviceData();
if (kIsWeb) {
return deviceData['browserName'];
} else {
return switch (defaultTargetPlatform) {
TargetPlatform.android => deviceData['display'],
TargetPlatform.iOS => deviceData['systemName'],
TargetPlatform.linux => '',
TargetPlatform.windows => '',
TargetPlatform.macOS => '',
TargetPlatform.fuchsia => '',
};
}
}
关于最重要的 设备仅有Id 获取,由于其获取方法不同于上面的情况,这儿咱们需要着重讲解下。
关于 iOS 来说,获取设备仅有Id 十分简略,只需要调用体系API 获取即可。可是,关于 Android 来说,由于其杂乱的体系版别、高版别体系对权限的收紧以及第三方厂商的定制化,导致获取设备仅有Id 的方法愈加杂乱。
针对 Android 体系获取设备的杂乱性,咱们采用现在行业界比较通用的方法:获取AnroidID + UUID + 本地缓存 来获取设备仅有ID。
/// 获取仅有设备 ID
/// 若没有从设备获取到,则生成一个 UUID 作为设备 ID
static Future<String> getDeviceId() async {
// 假如已经获取过设备ID,则直接回来
if (_deviceId != null && _deviceId!.isNotEmpty) {
return _deviceId!;
}
// 从本地获取设备ID
String? deviceId = await SharedPrefsUtil.getString(SPConstants.deviceId);
if (deviceId != null && deviceId.isNotEmpty) {
_deviceId = deviceId;
return _deviceId!;
}
// 获取设备ID
Map<String, dynamic> deviceData = await getDeviceData();
if (kIsWeb) {
_deviceId = '';
} else {
_deviceId = switch (defaultTargetPlatform) {
TargetPlatform.android => await _getAndroidId(),
TargetPlatform.iOS => deviceData['identifierForVendor'],
TargetPlatform.linux => '',
TargetPlatform.windows => '',
TargetPlatform.macOS => '',
TargetPlatform.fuchsia => '',
};
}
// 假如获取不到,则生成一个UUID
_deviceId = _getUniqueDeviceId(_deviceId);
// 保存到本地
SharedPrefsUtil.putString(SPConstants.deviceId, _deviceId!);
return _deviceId!;
}
关于已获取过的设备Id 直接取出缓存回来,若没有获取过设备Id 的则经过 _getAndroidId()
方法获取 AndroidId
。咱们引进 android_id 库,并针对部分体系版别获取的 AndroidId
重复问题进行处理。
/// 获取 AndroidId
static Future<String?> _getAndroidId() async {
String? androidId = await _androidIdPlugin.getId();
if ("9774d56d682e549c" == androidId) return null;
// 根据 AndroidId 生成 UUID
if (androidId != null && androidId.isNotEmpty) {
return UuidUtils.getUuidV5(androidId);
}
return null;
}
若是 AndroidId
没有获取到,则在 _getUniqueDeviceId()
方法中进行判别,并生成 UUID 替代。
/// 获取 设备仅有 ID
static String _getUniqueDeviceId(String? deviceId) {
if (deviceId == null || deviceId.isEmpty) {
return UuidUtils.getUuid();
} else {
return deviceId;
}
}
最后,将获取的设备Id 经过 SharedPrefsUtil 缓存,保证在用户没有卸载应用的情况下,获取到的设备ID 是仅有的。
...
// 假如获取不到,则生成一个UUID
_deviceId = _getUniqueDeviceId(_deviceId);
// 保存到本地
SharedPrefsUtil.putString(SPConstants.deviceId, _deviceId!);
return _deviceId!;
总结一下:
-
iOS :经过
identifierForVendor
字段,可以直接获取到设备仅有ID。 -
Android :先获取
AndroidID
,若获取到则生成设备仅有ID。若获取不到,则生成 UUID 字符串作为仅有标识。 -
设备ID是否仅有 :iOS 获取到的设备ID 一定是仅有的。Android 在没有卸载重装的情况下也是仅有的,若是卸载重装,若获取到设备的
AndroidID
则也是仅有的,只要在没有获取到AndoridID
并且有卸载重装行为的,才会呈现不一致的问题。
二、使用事例
DeviceUtils 使用起来十分简略,只需要一行代码调用即可:
/// 获取设备仅有ID
await DeviceUtils.getDeviceId();
/// 获取设备类型
await DeviceUtils.getModel();
/// 获取设备品牌
await DeviceUtils.getBrand();
/// 获取操作体系版别号
await DeviceUtils.getSystemVersion();
/// 获取体系版别称号
await DeviceUtils.getSystemName();
运行结果:
结语
好了,今日的东西类整理文章就到这儿,现在插件已发布到 Pub 中,欢迎我们体验。
假如觉得这篇文章对你有所协助的话,不要忘掉一键三连哦,我们的点赞是我更新的动力。
Pub: flutter_util_code
项目源码:FlutterUtilCode
使用事例:Example