feat: 获取sn
This commit is contained in:
@@ -21,6 +21,8 @@ import com.ttstd.controlled.R;
|
|||||||
import com.ttstd.controlled.base.BaseMvvmActivity;
|
import com.ttstd.controlled.base.BaseMvvmActivity;
|
||||||
import com.ttstd.controlled.databinding.ActivityMainBinding;
|
import com.ttstd.controlled.databinding.ActivityMainBinding;
|
||||||
import com.ttstd.controlled.service.ScreenCaptureService;
|
import com.ttstd.controlled.service.ScreenCaptureService;
|
||||||
|
import com.ttstd.controlled.utils.DeviceUtils;
|
||||||
|
import com.ttstd.controlled.utils.SignatureUtils;
|
||||||
import com.ttstd.controlled.webrtc.WebRtcClient;
|
import com.ttstd.controlled.webrtc.WebRtcClient;
|
||||||
|
|
||||||
import org.webrtc.RendererCommon;
|
import org.webrtc.RendererCommon;
|
||||||
@@ -65,7 +67,7 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
|
|||||||
// 默认服务器地址
|
// 默认服务器地址
|
||||||
binding.etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
binding.etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
||||||
// 生成设备ID
|
// 生成设备ID
|
||||||
// binding.etDeviceId.setText("controlled_" + UUID.randomUUID().toString().substring(0, 8));
|
binding.etDeviceId.setText(DeviceUtils.getSystemSerialNumber());
|
||||||
|
|
||||||
binding.btnStart.setOnClickListener(v -> startScreenSharing());
|
binding.btnStart.setOnClickListener(v -> startScreenSharing());
|
||||||
binding.btnStop.setOnClickListener(v -> stopScreenSharing());
|
binding.btnStop.setOnClickListener(v -> stopScreenSharing());
|
||||||
@@ -76,6 +78,12 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
|
|||||||
@Override
|
@Override
|
||||||
protected void initData() {
|
protected void initData() {
|
||||||
// Initialization logic if any
|
// Initialization logic if any
|
||||||
|
Log.e(TAG, "initData: isSystemApp = " + SignatureUtils.isSystemApp(this));
|
||||||
|
Log.e(TAG, "initData: isSystemSignature = " + SignatureUtils.isSystemSignature(this));
|
||||||
|
Log.e(TAG, "initData: isSharedSystemUid = " + SignatureUtils.isSharedSystemUid(this));
|
||||||
|
Log.e(TAG, "initData: isSystemUid = " + SignatureUtils.isSystemUid());
|
||||||
|
Log.e(TAG, "initData: isDeviceRooted = " + SignatureUtils.isDeviceRooted());
|
||||||
|
Log.e(TAG, "initData: isAppHasRootPermission = " + SignatureUtils.isAppHasRootPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startScreenSharing() {
|
private void startScreenSharing() {
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.ttstd.controlled.utils;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备信息工具类
|
||||||
|
*/
|
||||||
|
public class DeviceUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备序列号(适用于系统签名应用)
|
||||||
|
* <p>
|
||||||
|
* 需要权限: android.permission.READ_PRIVILEGED_PHONE_STATE
|
||||||
|
* 注意:普通应用即使有 READ_PHONE_STATE 权限,在 Android 10+ 也无法获取序列号。
|
||||||
|
*
|
||||||
|
* @return 设备序列号,获取失败可能返回 "unknown"
|
||||||
|
*/
|
||||||
|
@SuppressLint({"MissingPermission", "HardwareIds"})
|
||||||
|
public static String getSystemSerialNumber() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
try {
|
||||||
|
// 对于系统应用,Build.getSerial() 应该能成功返回真实的硬件序列号
|
||||||
|
return Build.getSerial();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Build.SERIAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Build.SERIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备标识(适用于普通应用)
|
||||||
|
* <p>
|
||||||
|
* 做了 Android 版本兼容。如果无法获取硬件序列号(如 Android 10+),
|
||||||
|
* 则尝试使用 Android ID。如果 Android ID 也获取不到,则通过硬件信息生成 UUID。
|
||||||
|
*
|
||||||
|
* @param context 上下文
|
||||||
|
* @return 设备唯一标识
|
||||||
|
*/
|
||||||
|
@SuppressLint({"MissingPermission", "HardwareIds"})
|
||||||
|
public static String getSerialNumber(Context context) {
|
||||||
|
String serial = null;
|
||||||
|
try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// 尝试通过 getSerial 获取,Android 10+ 普通应用通常会抛异常或返回 unknown
|
||||||
|
serial = Build.getSerial();
|
||||||
|
} else {
|
||||||
|
serial = Build.SERIAL;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验序列号是否有效
|
||||||
|
if (!TextUtils.isEmpty(serial) && !Build.UNKNOWN.equalsIgnoreCase(serial)) {
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试获取 Android ID
|
||||||
|
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||||
|
// 排除某些设备上已知的错误 Android ID ("9774d56d682e549c")
|
||||||
|
if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
|
||||||
|
return androidId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果上述方式都失败,则根据硬件机型信息生成 UUID
|
||||||
|
return getDeviceUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用硬件机型信息生成 UUID
|
||||||
|
* 这种方案在设备重启或刷机后通常能保持稳定,但在系统升级导致某些 Build 字段变化时可能会变。
|
||||||
|
*/
|
||||||
|
private static String getDeviceUuid() {
|
||||||
|
String devInfo = "35" + // 模拟 IMEI 的前缀
|
||||||
|
Build.BOARD.length() % 10 +
|
||||||
|
Build.BRAND.length() % 10 +
|
||||||
|
Build.SUPPORTED_ABIS[0].length() % 10 +
|
||||||
|
Build.DEVICE.length() % 10 +
|
||||||
|
Build.DISPLAY.length() % 10 +
|
||||||
|
Build.HOST.length() % 10 +
|
||||||
|
Build.ID.length() % 10 +
|
||||||
|
Build.MANUFACTURER.length() % 10 +
|
||||||
|
Build.MODEL.length() % 10 +
|
||||||
|
Build.PRODUCT.length() % 10 +
|
||||||
|
Build.TAGS.length() % 10 +
|
||||||
|
Build.TYPE.length() % 10 +
|
||||||
|
Build.USER.length() % 10;
|
||||||
|
|
||||||
|
// 使用 Build.SERIAL 参与 hash,增加独特性(即使它是 "unknown" 也是一种标识)
|
||||||
|
return new UUID(devInfo.hashCode(), Build.SERIAL.hashCode()).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,15 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
|
<!-- Android 8.0+ 需要 -->
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.READ_PHONE_STATE"
|
||||||
|
android:maxSdkVersion="28" /> <!-- 29+ 加了也没用,可限制住 -->
|
||||||
|
|
||||||
|
<!-- 如果你只跑在定制系统/有特权,用这个 -->
|
||||||
|
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.ttstd.control.ControlMessage;
|
|||||||
import com.ttstd.controller.signaling.SignalMessage;
|
import com.ttstd.controller.signaling.SignalMessage;
|
||||||
import com.ttstd.controller.signaling.WebSocketClient;
|
import com.ttstd.controller.signaling.WebSocketClient;
|
||||||
import com.ttstd.controller.view.RemoteTouchView;
|
import com.ttstd.controller.view.RemoteTouchView;
|
||||||
|
import com.ttstd.controller.utils.DeviceUtils;
|
||||||
import com.ttstd.controller.webrtc.WebRtcClient;
|
import com.ttstd.controller.webrtc.WebRtcClient;
|
||||||
|
|
||||||
import org.webrtc.EglBase;
|
import org.webrtc.EglBase;
|
||||||
@@ -29,7 +30,6 @@ import org.webrtc.RendererCommon;
|
|||||||
import org.webrtc.SurfaceViewRenderer;
|
import org.webrtc.SurfaceViewRenderer;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@@ -92,8 +92,8 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
// 默认服务器地址
|
// 默认服务器地址
|
||||||
etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
||||||
// 生成设备ID
|
// 生成设备ID(非系统签名,使用兜底方案获取设备标识)
|
||||||
myDeviceId = "controller_" + UUID.randomUUID().toString().substring(0, 8);
|
myDeviceId = DeviceUtils.getSerialNumber(this);
|
||||||
etDeviceId.setText(myDeviceId);
|
etDeviceId.setText(myDeviceId);
|
||||||
|
|
||||||
btnConnect.setOnClickListener(v -> connectToControlled());
|
btnConnect.setOnClickListener(v -> connectToControlled());
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.ttstd.controller.utils;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备信息工具类(控制端,非系统签名应用)
|
||||||
|
* <p>
|
||||||
|
* 与 WebRTCControlled 的 DeviceUtils 对应,但控制端没有系统签名,
|
||||||
|
* 因此无法稳定获取真实的硬件序列号,这里采用「不要求准确」的兜底方案:
|
||||||
|
* 1. 先尝试 Build.getSerial() / Build.SERIAL(Android 10+ 普通应用通常失败);
|
||||||
|
* 2. 失败则使用官方提供的 Android ID;
|
||||||
|
* 3. 再失败则基于硬件机型信息生成 UUID。
|
||||||
|
*/
|
||||||
|
public class DeviceUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备标识(适用于普通应用)
|
||||||
|
* <p>
|
||||||
|
* 做了 Android 版本兼容。如果无法获取硬件序列号(如 Android 10+),
|
||||||
|
* 则尝试使用 Android ID。如果 Android ID 也获取不到,则通过硬件信息生成 UUID。
|
||||||
|
*
|
||||||
|
* @param context 上下文
|
||||||
|
* @return 设备唯一标识
|
||||||
|
*/
|
||||||
|
@SuppressLint({"MissingPermission", "HardwareIds"})
|
||||||
|
public static String getSerialNumber(Context context) {
|
||||||
|
String serial = null;
|
||||||
|
try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// 尝试通过 getSerial 获取,Android 10+ 普通应用通常会抛异常或返回 unknown
|
||||||
|
serial = Build.getSerial();
|
||||||
|
} else {
|
||||||
|
serial = Build.SERIAL;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验序列号是否有效
|
||||||
|
if (!TextUtils.isEmpty(serial) && !Build.UNKNOWN.equalsIgnoreCase(serial)) {
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试获取 Android ID(官方提供的设备标识,无需特殊权限)
|
||||||
|
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||||
|
// 排除某些设备上已知的错误 Android ID ("9774d56d682e549c")
|
||||||
|
if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
|
||||||
|
return androidId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果上述方式都失败,则根据硬件机型信息生成 UUID
|
||||||
|
return getDeviceUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用硬件机型信息生成 UUID
|
||||||
|
* 这种方案在设备重启或刷机后通常能保持稳定,但在系统升级导致某些 Build 字段变化时可能会变。
|
||||||
|
*/
|
||||||
|
private static String getDeviceUuid() {
|
||||||
|
String devInfo = "35" + // 模拟 IMEI 的前缀
|
||||||
|
Build.BOARD.length() % 10 +
|
||||||
|
Build.BRAND.length() % 10 +
|
||||||
|
Build.SUPPORTED_ABIS[0].length() % 10 +
|
||||||
|
Build.DEVICE.length() % 10 +
|
||||||
|
Build.DISPLAY.length() % 10 +
|
||||||
|
Build.HOST.length() % 10 +
|
||||||
|
Build.ID.length() % 10 +
|
||||||
|
Build.MANUFACTURER.length() % 10 +
|
||||||
|
Build.MODEL.length() % 10 +
|
||||||
|
Build.PRODUCT.length() % 10 +
|
||||||
|
Build.TAGS.length() % 10 +
|
||||||
|
Build.TYPE.length() % 10 +
|
||||||
|
Build.USER.length() % 10;
|
||||||
|
|
||||||
|
// 使用 Build.SERIAL 参与 hash,增加独特性(即使它是 "unknown" 也是一种标识)
|
||||||
|
return new UUID(devInfo.hashCode(), Build.SERIAL.hashCode()).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
import 'config/ice_servers.dart';
|
import 'config/ice_servers.dart';
|
||||||
import 'controller/remote_controller.dart';
|
import 'controller/remote_controller.dart';
|
||||||
import 'utils/control_commands.dart';
|
import 'utils/control_commands.dart';
|
||||||
|
import 'utils/device_utils.dart';
|
||||||
import 'widgets/remote_touch_view.dart';
|
import 'widgets/remote_touch_view.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -54,7 +54,15 @@ class _ControllerHomeState extends State<ControllerHome> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_deviceIdController.text = 'controller_${const Uuid().v4().substring(0, 8)}';
|
_initDeviceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 异步获取设备标识并填入设备ID输入框(非系统签名,使用兜底方案)。
|
||||||
|
Future<void> _initDeviceId() async {
|
||||||
|
final id = await DeviceUtils.getSerialNumber();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() => _deviceIdController.text = id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
42
webrtc_controller_flutter/lib/utils/device_utils.dart
Normal file
42
webrtc_controller_flutter/lib/utils/device_utils.dart
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
/// 设备信息工具类(控制端,非系统签名应用)
|
||||||
|
///
|
||||||
|
/// 与 WebRTCControlled 的 DeviceUtils 对应,但控制端没有系统签名,
|
||||||
|
/// 因此无法稳定获取真实的硬件序列号,这里采用「不要求准确」的兜底方案:
|
||||||
|
/// 1. 优先使用官方插件([DeviceInfoPlugin])提供的 serialNumber;
|
||||||
|
/// 2. 失败则使用 iOS 的 identifierForVendor;
|
||||||
|
/// 3. 再失败则生成随机 UUID。
|
||||||
|
class DeviceUtils {
|
||||||
|
DeviceUtils._();
|
||||||
|
|
||||||
|
/// 获取设备标识(适用于普通应用)。
|
||||||
|
///
|
||||||
|
/// 兼容各平台:Android 使用官方序列号,iOS 使用 identifierForVendor,
|
||||||
|
/// 均不可用时回退到随机 UUID。
|
||||||
|
static Future<String> getSerialNumber() async {
|
||||||
|
const uuid = Uuid();
|
||||||
|
try {
|
||||||
|
final deviceInfo = DeviceInfoPlugin();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
final androidInfo = await deviceInfo.androidInfo;
|
||||||
|
final serial = androidInfo.serialNumber;
|
||||||
|
if (serial.isNotEmpty && serial.toLowerCase() != 'unknown') {
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
} else if (Platform.isIOS) {
|
||||||
|
final iosInfo = await deviceInfo.iosInfo;
|
||||||
|
final id = iosInfo.identifierForVendor;
|
||||||
|
if (id != null && id.isNotEmpty) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// 获取失败,走兜底逻辑
|
||||||
|
}
|
||||||
|
return uuid.v4();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,10 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import device_info_plus
|
||||||
import flutter_webrtc
|
import flutter_webrtc
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,22 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.1"
|
||||||
|
device_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: device_info_plus
|
||||||
|
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "11.5.0"
|
||||||
|
device_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_platform_interface
|
||||||
|
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.3"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -97,6 +113,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -123,6 +147,11 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_webrtc:
|
flutter_webrtc:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -472,6 +501,22 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.15.0"
|
||||||
|
win32_registry:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32_registry
|
||||||
|
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ dependencies:
|
|||||||
|
|
||||||
# 设备 ID 生成
|
# 设备 ID 生成
|
||||||
uuid: ^4.4.0
|
uuid: ^4.4.0
|
||||||
|
|
||||||
|
# 官方提供的设备信息插件,用于获取 Android ID / 设备标识
|
||||||
|
device_info_plus: ^11.0.0
|
||||||
protobuf: ^6.0.0
|
protobuf: ^6.0.0
|
||||||
fixnum: ^1.1.1
|
fixnum: ^1.1.1
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user