Flutter电话功能修复插件telephony_fix的使用

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

Flutter电话功能修复插件telephony_fix的使用

简介

telephony_fix 是一个修复版本的 telephony 插件,由 shounakmulay.dev 开发。该插件主要用于修复原版 telephony 插件在某些情况下的问题,确保其在 Android 平台上正常工作。telephony_fix 提供了多种电话功能,如发送短信、查询短信、监听短信、启动电话等。

注意事项

  • 该插件目前仅支持 Android 平台。
  • 插件会自动检查并请求权限,但建议在调用任何功能之前手动请求权限。
  • 部分功能需要在 AndroidManifest.xml 中添加相应的权限声明。

功能列表

  • 发送短信
  • 查询短信(收件箱、已发送、草稿)
  • 查询对话
  • 监听传入短信
  • 获取网络参数和指标
  • 启动电话

使用步骤

1. 添加依赖

pubspec.yaml 文件中添加 telephony 依赖:

dependencies:
  telephony: ^latest_version
2. 导入插件

在 Dart 文件中导入 telephony 包:

import 'package:telephony/telephony.dart';
3. 获取 Telephony 实例

通过 Telephony.instance 获取单例对象:

final Telephony telephony = Telephony.instance;
4. 请求权限

在调用任何功能之前,建议手动请求必要的权限:

bool permissionsGranted = await telephony.requestPhoneAndSmsPermissions;

你也可以分别请求 SMS 和 Phone 权限:

bool smsPermissionsGranted = await telephony.requestSmsPermissions;
bool phonePermissionsGranted = await telephony.requestPhonePermissions;
5. 发送短信

发送短信可以直接从应用内发送,也可以通过默认的短信应用发送。

直接发送短信
telephony.sendSms(
  to: "1234567890",
  message: "May the force be with you!"
);

如果你想监听短信发送的状态,可以提供 SmsSendStatusListener

final SmsSendStatusListener listener = (SendStatus status) {
  // 处理发送状态
};

telephony.sendSms(
  to: "1234567890",
  message: "May the force be with you!",
  statusListener: listener
);

如果短信内容超过 160 个字符,可以通过设置 isMultipart 标志发送多部分短信:

telephony.sendSms(
  to: "1234567890",
  message: "This is a very long message that exceeds the standard SMS length limit of 160 characters.",
  isMultipart: true
);
通过默认短信应用发送短信
telephony.sendSmsByDefaultApp(to: "1234567890", message: "May the force be with you!");
6. 查询短信

查询短信需要 READ_SMS 权限。可以在 AndroidManifest.xml 中添加以下权限声明:

<uses-permission android:name="android.permission.READ_SMS"/>

查询收件箱、已发送或草稿中的短信:

List<SmsMessage> messages = await telephony.getInboxSms(
  columns: [SmsColumn.ADDRESS, SmsColumn.BODY],
  filter: SmsFilter.where(SmsColumn.ADDRESS)
      .equals("1234567890")
      .and(SmsColumn.BODY)
      .like("starwars"),
  sortOrder: [OrderBy(SmsColumn.ADDRESS, sort: Sort.ASC), OrderBy(SmsColumn.BODY)]
);
7. 查询对话

查询对话与查询短信类似,但使用 ConversationFilter 进行过滤:

List<SmsConversation> conversations = await telephony.getConversations(
  filter: ConversationFilter.where(ConversationColumn.MSG_COUNT)
      .equals("4")
      .and(ConversationColumn.THREAD_ID)
      .greaterThan("12"),
  sortOrder: [OrderBy(ConversationColumn.THREAD_ID, sort: Sort.ASC)]
);
8. 监听传入短信

监听传入短信需要 RECEIVE_SMS 权限。在 AndroidManifest.xml 中添加以下权限声明:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<application>
  ...
  <receiver android:name="com.shounakmulay.telephony.sms.IncomingSmsReceiver"
      android:permission="android.permission.BROADCAST_SMS" android:exported="true">
    <intent-filter>
      <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
  </receiver>
</application>

创建一个静态函数来处理后台消息:

@pragma('vm:entry-point')
void backgroundMessageHandler(SmsMessage message) async {
  // 处理后台消息
}

注册监听器:

telephony.listenIncomingSms(
  onNewMessage: (SmsMessage message) {
    // 处理新消息
  },
  onBackgroundMessage: backgroundMessageHandler
);

如果你不希望在后台接收短信,可以不传递 onBackgroundMessage 参数,或者将 listenInBackground 设置为 false

telephony.listenIncomingSms(
  onNewMessage: (SmsMessage message) {
    // 处理新消息
  },
  listenInBackground: false
);
9. 获取网络参数和指标

获取设备是否支持发送短信、SIM 卡状态等信息:

bool canSendSms = await telephony.isSmsCapable;
SimState simState = await telephony.simState;

更多网络参数和指标的详细信息可以参考官方文档。

10. 后台执行

如果你需要在后台执行 telephony 方法,可以使用 Telephony.backgroundInstance

@pragma('vm:entry-point')
void backgroundMessageHandler(SmsMessage message) async {
  // 处理后台消息
  Telephony.backgroundInstance.sendSms(to: "123456789", message: "Message from background");
}

完整示例 Demo

以下是一个完整的示例应用程序,展示了如何使用 telephony_fix 插件发送短信、监听传入短信以及启动拨号器。

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:telephony/telephony.dart';

// 后台消息处理函数
void onBackgroundMessage(SmsMessage message) {
  debugPrint("onBackgroundMessage called");
}

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

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

class _MyAppState extends State<MyApp> {
  String _message = "";
  final Telephony telephony = Telephony.instance;

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

  // 处理新消息
  void onMessage(SmsMessage message) async {
    setState(() {
      _message = message.body ?? "Error reading message body.";
    });
  }

  // 处理发送状态
  void onSendStatus(SendStatus status) {
    setState(() {
      _message = status == SendStatus.SENT ? "sent" : "delivered";
    });
  }

  // 初始化平台状态
  Future<void> initPlatformState() async {
    try {
      final bool? result = await telephony.requestPhoneAndSmsPermissions;

      if (result != null && result) {
        telephony.listenIncomingSms(
            onNewMessage: onMessage, onBackgroundMessage: onBackgroundMessage);
      }
    } catch (e) {
      print("Failed to initialize platform state: $e");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Center(child: Text("Latest received SMS: $_message")),
            TextButton(
              onPressed: () async {
                await telephony.openDialer("123413453");
              },
              child: Text('Open Dialer'),
            ),
            TextButton(
              onPressed: () async {
                await telephony.sendSms(
                  to: "1234567890",
                  message: "Hello from Flutter!",
                  statusListener: onSendStatus,
                );
              },
              child: Text('Send SMS'),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter电话功能修复插件telephony_fix的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter电话功能修复插件telephony_fix的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用telephony_fix插件来修复电话功能的示例代码。telephony_fix插件主要用于解决Android平台上调用拨打电话功能时可能遇到的问题。

首先,确保你已经在pubspec.yaml文件中添加了telephony_fix依赖:

dependencies:
  flutter:
    sdk: flutter
  telephony_fix: ^最新版本号  # 请替换为当前最新版本号

然后,运行flutter pub get命令来获取依赖。

接下来,在你的Flutter项目中,你需要按照以下步骤使用telephony_fix插件:

  1. 导入插件

在你的Dart文件中导入telephony_fix插件:

import 'package:telephony_fix/telephony_fix.dart';
  1. 请求电话权限

在Android上拨打电话需要请求CALL_PHONE权限。你可以在运行时请求这个权限。

import 'package:permission_handler/permission_handler.dart';

Future<void> requestCallPhonePermission() async {
  var status = await Permission.phoneCall.status;
  if (!status.isGranted) {
    var result = await Permission.phoneCall.request();
    if (!result.isGranted) {
      // 处理权限被拒绝的情况
      throw Exception('Phone call permission is denied');
    }
  }
}

注意:permission_handler插件用于请求权限,你需要在pubspec.yaml中添加这个依赖并获取。

  1. 使用TelephonyFix进行电话拨打

在请求到电话权限后,你可以使用TelephonyFix来拨打电话。

void makePhoneCall(String phoneNumber) async {
  try {
    // 请求电话权限
    await requestCallPhonePermission();

    // 使用TelephonyFix拨打电话
    bool result = await TelephonyFix.dial(phoneNumber);
    if (result) {
      print("Call dialed successfully");
    } else {
      print("Failed to dial call");
    }
  } catch (e) {
    print("Error dialing call: $e");
  }
}
  1. 调用拨打电话函数

你可以在你的UI组件中调用这个函数来拨打电话,例如在一个按钮的点击事件中:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Telephony Fix Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              makePhoneCall('1234567890');  // 替换为实际电话号码
            },
            child: Text('Make Call'),
          ),
        ),
      ),
    );
  }
}

完整的代码示例如下:

import 'package:flutter/material.dart';
import 'package:telephony_fix/telephony_fix.dart';
import 'package:permission_handler/permission_handler.dart';

Future<void> requestCallPhonePermission() async {
  var status = await Permission.phoneCall.status;
  if (!status.isGranted) {
    var result = await Permission.phoneCall.request();
    if (!result.isGranted) {
      throw Exception('Phone call permission is denied');
    }
  }
}

void makePhoneCall(String phoneNumber) async {
  try {
    await requestCallPhonePermission();
    bool result = await TelephonyFix.dial(phoneNumber);
    if (result) {
      print("Call dialed successfully");
    } else {
      print("Failed to dial call");
    }
  } catch (e) {
    print("Error dialing call: $e");
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Telephony Fix Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              makePhoneCall('1234567890');  // 替换为实际电话号码
            },
            child: Text('Make Call'),
          ),
        ),
      ),
    );
  }
}

确保你已经正确配置了AndroidManifest.xml中的电话权限:

<uses-permission android:name="android.permission.CALL_PHONE"/>

这样,你就可以在Flutter应用中通过telephony_fix插件来修复并拨打电话了。

回到顶部