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

如何检测手机来电?Flutter音乐播放器来电时如何暂停音频?

我来一步步帮你解决这两个Flutter开发里的常见场景问题~

问题1:如何检测手机是否处于来电状态?

Flutter本身没有直接提供系统电话状态的API,得依赖原生平台能力或现成的Flutter插件来实现,下面分两种方式说明:

原生平台层面的实现思路

Android

Android可通过TelephonyManager监听电话状态,核心关注三个状态:

  • CALL_STATE_RINGING:来电响铃中
  • CALL_STATE_OFFHOOK:电话已接通
  • CALL_STATE_IDLE:无通话的空闲状态

需要在AndroidManifest.xml中申请READ_PHONE_STATE权限(Android 10及以上可能还需READ_CALL_LOG权限,要注意权限适配)。

iOS

iOS 10之前用CTCallCenter,但现在已被弃用,推荐使用CallKit框架监听来电状态。同时要在Info.plist中添加对应隐私权限描述(比如NSPhoneUsageDescription),否则会被系统拦截。

更便捷的Flutter插件方案

直接用封装好的Flutter插件能省去原生代码开发的麻烦,比如telephony或flutter_phone_state插件,这里以telephony为例:

  1. 先在pubspec.yaml添加依赖:
dependencies:
  telephony: ^0.2.0
  1. 初始化并监听来电状态:
import 'package:telephony/telephony.dart';

final Telephony telephony = Telephony.instance;

void initState() {
  super.initState();
  // 监听来电状态变化
  telephony.listenIncomingCall(
    onNewCall: (PhoneCall call) {
      print("当前来电状态:${call.state.name}");
      // 根据call.state判断是响铃、接通还是空闲
      if (call.state == CallState.RINGING) {
        // 处理来电响铃逻辑
      }
    },
  );
}

记得提前请求电话权限,否则监听会失效。


问题2:Flutter音乐播放器来电时自动暂停音频

结合上面的来电状态检测,配合常用的音乐播放器插件(比如just_audio、audioplayers),就能实现自动暂停的功能。下面用just_audio+telephony给出完整示例:

步骤1:添加依赖

在pubspec.yaml中引入需要的包:

dependencies:
  just_audio: ^0.9.34
  telephony: ^0.2.0
  permission_handler: ^10.2.0 # 用于申请权限

步骤2:核心逻辑实现

import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:telephony/telephony.dart';
import 'package:permission_handler/permission_handler.dart';

class MusicPlayerPage extends StatefulWidget {
  const MusicPlayerPage({super.key});

  @override
  State<MusicPlayerPage> createState() => _MusicPlayerPageState();
}

class _MusicPlayerPageState extends State<MusicPlayerPage> {
  final AudioPlayer _audioPlayer = AudioPlayer();
  final Telephony _telephony = Telephony.instance;
  bool _wasPlaying = false; // 记录来电前的播放状态,用于后续恢复

  @override
  void initState() {
    super.initState();
    _requestPermissions();
    _initAudioPlayer();
    _initCallListener();
  }

  // 请求必要权限
  Future<void> _requestPermissions() async {
    await Permission.phone.request();
    await Permission.storage.request(); // 播放本地音频时需要
  }

  // 初始化音频播放器(示例用网络音频)
  Future<void> _initAudioPlayer() async {
    await _audioPlayer.setUrl("https://example.com/your-audio-file.mp3");
  }

  // 初始化来电监听,实现自动暂停/恢复
  void _initCallListener() {
    _telephony.listenIncomingCall(
      onNewCall: (PhoneCall call) {
        if (call.state == CallState.RINGING || call.state == CallState.OFFHOOK) {
          // 来电响铃或接通时,暂停播放器
          if (_audioPlayer.playing) {
            _wasPlaying = true;
            _audioPlayer.pause();
          }
        } else if (call.state == CallState.IDLE) {
          // 通话结束后,恢复之前的播放状态
          if (_wasPlaying) {
            _audioPlayer.play();
            _wasPlaying = false;
          }
        }
      },
    );
  }

  @override
  void dispose() {
    _audioPlayer.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("音乐播放器")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () async => await _audioPlayer.play(),
              child: const Text("播放"),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () async => await _audioPlayer.pause(),
              child: const Text("暂停"),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  • 权限适配:Android需在AndroidManifest.xml添加<uses-permission android:name="android.permission.READ_PHONE_STATE"/>;iOS要在Info.plist中添加NSPhoneUsageDescription权限描述。
  • 播放器替换:如果用的是audioplayers,只需把_audioPlayer.play()/pause()替换成对应插件的方法即可。
  • 自定义逻辑:如果不需要通话结束后自动恢复播放,删掉CallState.IDLE分支的代码即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:05:29