You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Flutter应用获取Android 11设备真实序列号(支持额外配置)

解决Flutter获取Infinix HOT 12 Play NFC设备真实序列号返回unknown的问题

问题说明

我的Flutter应用需要获取设备真实序列号用于身份识别,Android ID在设备恢复出厂设置后会变更,无法满足需求。使用设备为Infinix HOT 12 Play NFC,已在AndroidManifest.xml中添加READ_PRIVILEGED_PHONE_STATE与READ_PHONE_STATE权限,通过device_info_plus包调用接口仍返回“unknown”,需要分步解决方案,不介意设备进行额外配置。

分步解决方案

1. 明确Android权限限制

从Android 10(API 29)开始,普通第三方应用就算申请了READ_PHONE_STATE权限,也无法获取设备序列号;而READ_PRIVILEGED_PHONE_STATE是系统级权限,仅系统应用或获得系统授权的应用可使用,常规渠道无法获取该权限。

2. 设备Root并授予系统权限(适合允许设备配置的场景)

这是直接解决问题的方式:

  • 先对Infinix HOT 12 Play NFC进行Root操作(步骤需匹配机型,比如先解锁Bootloader,再刷入Magisk等Root包)
  • Root完成后,通过ADB命令给应用授予权限:
    adb shell pm grant com.example.e_ktp_reader android.permission.READ_PRIVILEGED_PHONE_STATE
    
  • 也可以用Magisk等Root权限管理工具,手动给应用分配该权限

3. 验证设备本身是否可读取序列号

先确认设备序列号本身可被读取,执行ADB命令:

adb shell getprop ro.serialno

如果命令返回正确序列号,说明是权限问题;如果也返回unknown,代表厂商隐藏了序列号,只能更换其他标识符。

4. 调整代码完善权限流程

在Dart代码中动态请求READ_PHONE_STATE权限(低版本Android可能有效),同时校验权限状态:

import 'package:device_info_plus/device_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/services.dart';
import 'dart:io';

static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();

static Future<String> getSerialNumber() async {
  if (Platform.isAndroid) {
    // 动态请求电话状态权限
    PermissionStatus status = await Permission.phone.request();
    if (status.isGranted) {
      AndroidDeviceInfo info = await _deviceInfo.androidInfo;
      return info.serialNumber;
    } else {
      throw PlatformException(
        code: "PERMISSION_DENIED",
        message: "电话状态权限被拒绝",
      );
    }
  }
  throw PlatformException(
    code: "UNSUPPORTED",
    message: "不支持当前平台",
  );
}

5. 备选方案:使用其他硬件标识符(若Root不可行)

如果不想Root,可考虑以下替代方案,但同样受权限限制:

  • IMEI:双卡设备存在两个IMEI,Android 10+普通应用无法获取,同样需要系统权限
  • 自定义UUID:首次启动时生成唯一UUID并存储到本地(如SharedPreferences),但恢复出厂设置会丢失,可同步到云端作为备选,但这并非“真实序列号”

当前使用的代码

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.e_ktp_reader">
    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
    />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"
    />

    <application
        android:label="Sam Online"
        android:name="${applicationName}"
        android:icon="@mipmap/launcher_icon">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme"
            />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

原Dart代码

import 'package:device_info_plus/device_info_plus.dart';

 // ... more imports
 static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
 // ... more code
 static Future<String> getSerialNumber() async {
    if (Platform.isAndroid) {
      return (await _deviceInfo.androidInfo).serialNumber;
    }

    throw PlatformException(
      code: "UNSUPPORTED",
      message: "Platform is not supported.",
    );
  }

内容的提问来源于stack exchange,提问作者Dias Utsman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:24:51