首页 > web前端 > js教程 > 正文

在 Expo 应用中添加声音和振动通知

心靈之曲
发布: 2025-08-22 17:46:23
原创
1033人浏览过

在 expo 应用中添加声音和振动通知

本文档旨在指导开发者如何在 Expo 应用中集成声音和振动通知。我们将探讨如何利用 expo-av 播放声音以及使用 react-native 的 Vibration API 实现振动效果,并着重解决在特定时间触发通知的问题。同时,我们也关注权限处理,这是实现通知功能的关键环节。

集成声音通知

首先,确保你已经安装了 expo-av 依赖:

npx expo install expo-av
登录后复制

以下代码展示了如何播放声音:

import { useEffect, useState } from "react";
import { Audio } from 'expo-av';
import * as Notifications from 'expo-notifications';
import { Platform } from 'react-native';

async function schedulePushNotification() {
  await Notifications.scheduleNotificationAsync({
    content: {
      title: "Reminder!",
      body: 'It\'s time!',
      sound: 'default', // Use 'default' for the default notification sound
      data: { data: 'goes here' },
    },
    trigger: { seconds: 5, repeats: false }, // Schedule for 5 seconds from now
  });
}

const useSound = () => {
  const [sound, setSound] = useState(null);

  useEffect(() => {
    async function loadSound() {
      try {
        const { sound: soundObject } = await Audio.Sound.createAsync(
          require('./assets/notification.mp3'), // 替换为你的音频文件路径
          { shouldPlay: false } // 初始时不播放
        );
        setSound(soundObject);
        console.log('Sound loaded successfully');

        // Set audio mode to allow playing sound in silent mode (iOS)
        await Audio.setAudioModeAsync({
          playsInSilentModeIOS: true,
          staysActiveInBackground: true,
          interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
          interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS,
          shouldDuckAndroid: false,
        });
      } catch (error) {
        console.error("Failed to load the sound", error);
      }
    }

    loadSound();

    return () => {
      if (sound) {
        sound.unloadAsync();
      }
    };
  }, []);

  const playSound = async () => {
    if (sound) {
      try {
        await sound.replayAsync(); // Use replayAsync to play from the beginning
        console.log('Playing Sound');
      } catch (error) {
        console.error("Failed to play the sound", error);
      }
    }
  };

  return { playSound };
};

export default function App() {
  const { playSound } = useSound();

  useEffect(() => {
    // Schedule notification
    schedulePushNotification();

    // Configure notifications
    async function configurePushNotifications() {
      const { status } = await Notifications.getPermissionsAsync();
      let finalStatus = status;

      if (finalStatus !== 'granted') {
        const { status } = await Notifications.requestPermissionsAsync();
        finalStatus = status;
      }

      if (finalStatus !== 'granted') {
        alert('Failed to get push token for push notification!');
        return;
      }

      if (Platform.OS === 'android') {
        Notifications.setNotificationChannelAsync('default', {
          name: 'default',
          importance: Notifications.AndroidImportance.MAX,
          vibrationPattern: [0, 250, 250, 250],
          lightColor: '#FF231F7C',
        });
      }
    }

    configurePushNotifications();
  }, []);

  useEffect(() => {
    const subscription = Notifications.addNotificationReceivedListener(notification => {
      console.log('Notification Received', notification);
      playSound();
    });

    const responseListener = Notifications.addNotificationResponseReceivedListener(response => {
      console.log('Notification Response', response);
    });

    return () => {
      subscription.remove();
      responseListener.remove();
    };
  }, [playSound]);

  return (
    // Your UI components here
    null
  );
}
登录后复制

关键点:

网页制作与PHP语言应用
网页制作与PHP语言应用

图书《网页制作与PHP语言应用》,由武汉大学出版社于2006出版,该书为普通高等院校网络传播系列教材之一,主要阐述了网页制作的基础知识与实践,以及PHP语言在网络传播中的应用。该书内容涉及:HTML基础知识、PHP的基本语法、PHP程序中的常用函数、数据库软件MySQL的基本操作、网页加密和身份验证、动态生成图像、MySQL与多媒体素材库的建设等。

网页制作与PHP语言应用 447
查看详情 网页制作与PHP语言应用
  • 使用 Audio.Sound.createAsync 加载音频文件。确保文件路径正确。
  • 使用 sound.playAsync() 播放声音。
  • 在组件卸载时,使用 sound.unloadAsync() 释放资源。
  • Notifications.setNotificationHandler 设置通知处理程序,允许播放声音。

注意: 音频文件需要放置在你的项目中,例如 assets 目录下。你需要替换 require('../assets/sonido.mp3') 为你的实际文件路径。

集成振动通知

要添加振动效果,你需要从 react-native 导入 Vibration API:

import { Vibration } from 'react-native';
登录后复制

然后,你可以使用 Vibration.vibrate() 方法触发振动。你可以传递一个数字(毫秒)来指定振动持续时间,或者传递一个模式数组来定义振动和暂停的序列:

import { Vibration } from 'react-native';

const vibrate = () => {
  Vibration.vibrate(); // 默认振动
  //Vibration.vibrate(1000); // 振动 1 秒
  //Vibration.vibrate([0, 500, 200, 500], true); // 自定义模式 (启动, 振动500ms, 暂停200ms, 振动500ms, 循环)
};
登录后复制

关键点:

  • Vibration.vibrate() 触发振动。
  • 可以传递一个数字指定振动时长。
  • 可以传递一个数组定义振动模式。

将振动集成到你的通知处理程序中:

import { useEffect } from "react";
import * as Notifications from "expo-notifications";
import { Alert, Vibration } from "react-native";
import React from "react";
import { useNavigation } from "@react-navigation/native";
import { Audio } from 'expo-av';

Notifications.setNotificationHandler({
  handleNotification: async () => {
    return {
      shouldPlaySound: true,
      shouldSetBadge: false,
      shouldShowAlert: true,
    };
  },
});

const HandleNotifications = () => {
  const navigation = useNavigation();

  useEffect(() => {
    async function configurePushNotifications() {
      const { status } = await Notifications.getPermissionsAsync();
      let finalStatus = status;
      if (finalStatus !== "granted") {
        const { status } = await Notifications.requestPermissionsAsync();
        finalStatus = status;
      }
      if (finalStatus !== "granted") {
        Alert.alert(
          "Permiso requerido",
          "Se requieren notificaciones locales para recibir alertas cuando vencen los recordatorios."
        );
        return;
      }
    }

    configurePushNotifications();
  }, []);

  useEffect(() => {
    const subscription = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        console.log("RESPONSE", response);
        const reminderId = response.notification.request.content.data.reminderId;
        if (reminderId) {
          navigation.navigate("ModifyReminder", { reminderId });
        }
      }
    );

    return () => subscription.remove();
  }, []);

  useEffect(() => {
    let soundObject = null;

    async function playSound() {
      soundObject = new Audio.Sound();
      try {
        await soundObject.loadAsync(require('../assets/sonido.mp3'));
        await soundObject.playAsync();
      } catch (error) {
        console.log(error);
      }
    }

    playSound();

    return () => {
      if (soundObject) {
        soundObject.stopAsync();
        soundObject.unloadAsync();
      }
    };
  }, []);

  useEffect(() => {
    const appFocusSubscription = Notifications.addNotificationResponseReceivedListener(() => {
      Vibration.cancel();
      Audio.setIsEnabledAsync(false);
    });

    const appBlurSubscription = Notifications.addNotificationResponseReceivedListener(() => {
      Audio.setIsEnabledAsync(true);
    });

    return () => {
      appFocusSubscription.remove();
      appBlurSubscription.remove();
    };
  }, []);

  useEffect(() => {
    const subscription = Notifications.addNotificationReceivedListener(() => {
      Vibration.vibrate([0, 500, 200, 500], true);
    });

    return () => {
      subscription.remove();
      Vibration.cancel();
    };
  }, []);


  return <React.Fragment />;
};

export default HandleNotifications;
登录后复制

注意: Vibration.cancel() 可以停止振动。

处理权限

在 Android 和 iOS 上,你需要请求用户授权才能发送通知。 Expo 提供 Notifications.requestPermissionsAsync() 方法来处理权限请求。

import * as Notifications from 'expo-notifications';
import { Alert } from 'react-native';

async function configurePushNotifications() {
  const { status } = await Notifications.getPermissionsAsync();
  let finalStatus = status;

  if (finalStatus !== 'granted') {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }

  if (finalStatus !== 'granted') {
    Alert.alert(
      "Permiso requerido",
      "Se requieren notificaciones locales para recibir alertas cuando vencen los recordatorios."
    );
    return;
  }
}
登录后复制

确保在组件挂载时调用 configurePushNotifications()。

在特定时间触发通知

要实现在特定时间触发通知,你需要使用 Notifications.scheduleNotificationAsync() 方法,并设置 trigger 属性。trigger 属性可以是一个 Date 对象,也可以是一个包含 seconds 属性的对象,表示从现在开始的秒数。

import * as Notifications from 'expo-notifications';

async function schedulePushNotification() {
  await Notifications.scheduleNotificationAsync({
    content: {
      title: "Reminder!",
      body: 'It\'s time!',
      sound: 'default',
      data: { data: 'goes here' },
    },
    trigger: { seconds: 5, repeats: false }, // Schedule for 5 seconds from now
  });
}
登录后复制

关键点:

  • 使用 Notifications.scheduleNotificationAsync() 安排通知。
  • trigger 属性控制通知触发时间。

总结

通过结合 expo-av 和 react-native 的 Vibration API,你可以轻松地在 Expo 应用中添加声音和振动通知。 确保正确处理权限,并使用 Notifications.scheduleNotificationAsync() 方法在特定时间触发通知。 记住,用户体验至关重要,合理使用通知可以提升应用的用户满意度。

以上就是在 Expo 应用中添加声音和振动通知的详细内容,更多请关注php中文网其它相关文章!

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号