Android Foreground Service 中,提示音循环播放及停止

更新日期: 2023-08-07 阅读次数: 707 字数: 620 分类: Android

需求背景

Android App 收到蓝牙推送的消息之后,播放提示音,且一直播放,直到收到停止的指令。

TODO

  • [X] fragment 界面上增加两个按钮:开始,停止。方便测试
  • [X] 提取出播放和停止功能,封装成两个函数。便于测试
  • [X] 接收到停止指令后,关闭音频
  • [X] Foreground Service 中定义 LiveData,方便 fragment 点击按钮后操作。实际不需要,直接在 service 中定义成静态方法即可。
  • [X] 下载报警提示音
  • [X] 支持自定义音频文件。这个以后播放引导提示音频也能用到,只不过是只用一次
  • [X] 测试无误后,去掉开始按钮(隐藏),只保留停止按钮。按钮名称,关闭警报提示音

下载报警提示音

https://pixabay.com/sound-effects/search/alert/

在 Android Studio 项目的 res 目录下,新建一个 raw 目录,将下载到的 mp3 音频文件放进去。

例如,命名为 alert.mp3

播放报警提示音

由于是在 Foreground Service 中播放音频,所以为了方便 fragment 中调用,使用了静态变量和方法。

同时 Foreground Service 的静态方法中无法获取 context,所以加上了 Context 参数。

private static MediaPlayer mediaPlayer;

public static void playAlertAudio(Context context) {
	if (mediaPlayer != null && mediaPlayer.isPlaying()) {
		// 防止重复播放
		return;
	}

	mediaPlayer = MediaPlayer.create(context, R.raw.alert);
	mediaPlayer.setLooping(true);
	mediaPlayer.start();
}

停止播放

public static void stopAlertAudio() {
	if (mediaPlayer != null && mediaPlayer.isPlaying()) {
		mediaPlayer.stop();
		mediaPlayer.reset();
	}
}

Foreground Servie 中调用

BLE 监听回调中:

NodeConnectionService.playAlertAudio(getApplicationContext());

Fragment 中调用

按钮点击事件中:

NodeConnectionService.playAlertAudio(getContext());

华为鸿蒙系统上的诡异问题

这个功能在台电的 Android 平板上及小米手机上运行的很正常,但是在华为鸿蒙的平板上,有明显的问题。

就是如果信号源短时间内发送了多个报警,这个音频停不下来,或是同时播放了多个音频。即过滤没有成功。

增加了两项针对性的改进:

  • 使用自己的标识位标识是否在播放中
  • 为了防止 mediaPlayer 初始化慢,将标识位放在初始化前

修改后的代码:

    private static MediaPlayer mediaPlayer;
    private static boolean isPlayingAlert = false;

    public static void playAlertAudio(Context context) {
        if (mediaPlayer != null && isPlayingAlert) {
            // 防止重复播放
            return;
        }

        isPlayingAlert = true;

        mediaPlayer = MediaPlayer.create(context, R.raw.alert);

        mediaPlayer.setLooping(true);
        mediaPlayer.start();

    }

    public static void stopAlertAudio() {
        if (mediaPlayer != null && isPlayingAlert) {
            mediaPlayer.stop();
            mediaPlayer.reset();
            isPlayingAlert = false;
        }
    }

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式