Flutter获取设备信息插件flutter_cell_info的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter获取设备信息插件flutter_cell_info的使用

Cell Info Plugin

NetMonster Core

🚧 工作进行中! 🚧

轻量级的Android库,基于https://developer.android.com/reference/android/telephony/package-summary构建。NetMonster核心是从https://play.google.com/store/apps/details?id=cz.mroczis.netmonster应用程序中提取出来的,并将几个电信功能回退到较旧的Android设备。

为什么使用NetMonster Core而不是遗留API?

  • 验证 - 库验证来自RIL的数据并尽可能进行纠正。
  • 更丰富的信息 - 提供额外的功能用于小区标识和信号,使你的代码更易理解。
  • 回退 - 几个不可访问的信号或身份字段现在可以通过简单代码访问。
  • 测试 - 在真实设备上进行了测试,拥有50,000+活跃用户。

新函数

以下是每个语音/数据网络的比较。

GSM
功能 最低SDK Android 最低SDK NetMonster Core
CGI - I (14)
NCC - N (24)
BCC - N (24)
带宽 - N (24)
TA O (26) N (24)
WCDMA
功能 最低SDK Android 最低SDK NetMonster Core
CGI - I (14)
CID (16b) - I (14)
RNC - I (14)
Ec/Io - M (23)
带宽 - N (24)
BER - Q (29)
Ec/No - Q (29)
RSCP - Q (29)
LTE
功能 最低SDK Android 最低SDK NetMonster Core
eCGI - I (14)
CID (8b) - I (14)
eNb - I (14)
RSSI Q (29) I (14)
RSRP O (26) I (14)
CQI O (26) I (14)
SNR O (26) I (14)
TA O (26) I (14)
带宽 - N (24)

使用

基本上你可以通过两种方式使用此库:

  • 作为验证库,它会清理来自AOSP的数据,因为许多制造商修改了源代码且不遵循公共文档。
  • 利用NetMonster Core的附加后处理优势。结果将提供更多数据,但正确性可能不是100%保证。
没有附加后处理

NetMonster Core专注于映射两个AOSP的方法来获取当前小区信息:

注意,其中一些方法已被弃用或从AOSP中移除,请参阅每个方法的文档以获取更多信息。

后处理

在这种情况下,你需要与INetMonster类交互。以下是一些NetMonster Core解决的问题列表。

多个来源数据合并

问题:

  • Android提供了多种获取小区信息的方式。
  • 并非所有设备都支持统一的方式访问所有数据。

解决方案:

  • NetMonster Core从你指定的源抓取数据,验证并合并它们。
LTE-A和HSPA+42检测

问题:

  • AOSP无法检测HSPA+42,只能检测HSPA+。
  • AOSP没有提供区分当前网络是否使用载波聚合的方法。

解决方案:

  • NetMonster Core尝试猜测HSPA+ 42的可用性。
  • 基于小区信息可以猜测LTE-CA的存在,也可以使用隐藏的API检测。

使用getNetworkType(vararg detectors: INetworkDetector)可以指定当检测当前网络类型时使用的INetworkDetector

其他特性
  • 识别处于“仅限紧急呼叫”模式下的服务小区。
  • 在GSM、WCDMA、LTE、TD-SCDMA和NR网络中为非服务小区添加PLMN。

起源于 https://github.com/eslamfaisal/FlutterCellInfo

感谢 - https://github.com/eslamfaisal

完整示例代码

import 'dart:async';
import 'dart:convert';

import 'package:flutter_cell_info/CellResponse.dart';
import 'package:flutter_cell_info/SIMInfoResponse.dart';
import 'package:flutter_cell_info/flutter_cell_info.dart';
import 'package:flutter_cell_info/models/common/cell_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  CellsResponse? _cellsResponse;

  [@override](/user/override)
  void initState() {
    super.initState();
    startTimer();
  }

  String? currentDBM;

  // 平台消息是异步的,因此我们初始化在一个异步方法中。
  Future<void> initPlatformState() async {
    CellsResponse? cellsResponse;
    // 平台消息可能会失败,所以我们使用一个try/catch PlatformException。
    try {
      String? platformVersion = await CellInfo.getCellInfo;
      final body = json.decode(platformVersion!);

      cellsResponse = CellsResponse.fromJson(body);

      CellType currentCellInFirstChip = cellsResponse.primaryCellList![0];
      if (currentCellInFirstChip.type == "LTE") {
        currentDBM =
            "LTE dbm = ${currentCellInFirstChip.lte?.signalLTE?.dbm}";
      } else if (currentCellInFirstChip.type == "NR") {
        currentDBM =
            "NR dbm = ${currentCellInFirstChip.nr?.signalNR?.dbm}";
      } else if (currentCellInFirstChip.type == "WCDMA") {
        currentDBM = "WCDMA dbm = ${currentCellInFirstChip.wcdma?.signalWCDMA?.dbm}";

        print('currentDBM = ' + currentDBM!);
      }

      String? simInfo = await CellInfo.getSIMInfo;
      final simJson = json.decode(simInfo!);
      print(
          "display name ${SIMInfoResponse.fromJson(simJson).simInfoList![0].displayName}");
    } on PlatformException {
      _cellsResponse = null;
    }

    // 如果小部件在异步平台消息还在飞行时被从树中移除,我们想丢弃回复而不是调用setState更新我们的不存在的外观。
    if (!mounted) return;

    setState(() {
      _cellsResponse = cellsResponse;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: _cellsResponse != null
            ? Center(
                child: Text(
                  'mahmoud = ${currentDBM}\n primary = ${_cellsResponse?.primaryCellList?.length.toString()} \n neighbor = ${_cellsResponse?.neighboringCellList?.length}',
                ),
              )
            : null,
      ),
    );
  }

  Timer? timer;

  void startTimer() {
    const oneSec = const Duration(seconds: 3);
    timer = new Timer.periodic(
      oneSec,
      (Timer timer) {
        initPlatformState();
      },
    );
  }
}

更多关于Flutter获取设备信息插件flutter_cell_info的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter获取设备信息插件flutter_cell_info的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用flutter_cell_info插件来获取设备信息的示例代码。这个插件允许你获取关于设备蜂窝网络的信息,如运营商名称、SIM卡信息等。

首先,你需要在你的Flutter项目中添加flutter_cell_info插件。你可以通过修改pubspec.yaml文件来完成这一步:

dependencies:
  flutter:
    sdk: flutter
  flutter_cell_info: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在你的Dart代码中导入并使用这个插件。以下是一个简单的示例,展示如何获取并显示设备蜂窝网络信息:

import 'package:flutter/material.dart';
import 'package:flutter_cell_info/flutter_cell_info.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CellInfoScreen(),
    );
  }
}

class CellInfoScreen extends StatefulWidget {
  @override
  _CellInfoScreenState createState() => _CellInfoScreenState();
}

class _CellInfoScreenState extends State<CellInfoScreen> {
  String? cellInfo;

  @override
  void initState() {
    super.initState();
    _getCellInfo();
  }

  Future<void> _getCellInfo() async {
    try {
      CellInfo cellInfoResult = await FlutterCellInfo.getCellInfo();
      
      // 你可以根据需要访问cellInfoResult中的不同属性
      // 这里我们简单地将所有信息转换为一个字符串
      String info = "Cell Info:\n"
          "Network Type: ${cellInfoResult.networkType}\n"
          "Is Available: ${cellInfoResult.isAvailable}\n"
          "Is Connected: ${cellInfoResult.isConnected}\n"
          "Operator Name: ${cellInfoResult.operatorName}\n"
          "Operator Code: ${cellInfoResult.operatorCode}\n"
          "Country Code: ${cellInfoResult.countryCode}\n"
          "MCC: ${cellInfoResult.mcc}\n"
          "MNC: ${cellInfoResult.mnc}\n"
          "Roaming: ${cellInfoResult.isRoaming}\n"
          "Technology: ${cellInfoResult.technology}\n";
      
      setState(() {
        cellInfo = info;
      });
    } catch (e) {
      print("Error getting cell info: $e");
      setState(() {
        cellInfo = "Error getting cell info.";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Device Cell Info'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: cellInfo != null
            ? Text(cellInfo!)
            : Center(child: CircularProgressIndicator()),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,该应用在启动时调用_getCellInfo方法来获取设备的蜂窝网络信息。获取到的信息会被存储在一个字符串中,并通过Text组件显示在屏幕上。如果获取信息时发生错误,则显示一个错误消息。

请注意,FlutterCellInfo.getCellInfo()方法返回的是一个CellInfo对象,该对象包含多个属性,如networkTypeisAvailableoperatorName等,你可以根据需要访问这些属性来获取特定的信息。

另外,由于这个插件可能涉及到设备的敏感信息,因此在实际应用中,请确保你已经正确处理了权限请求和隐私保护的问题。

回到顶部