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

在 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  );}

关键点:

使用 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 ;};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 应用中添加声音和振动通知的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1517127.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
提取嵌套括号内的特定内容:JavaScript 括号解析教程
上一篇 2025年12月20日 10:32:26
Angular ag-Grid 自定义聚合函数无法调用其他函数的问题解决
下一篇 2025年12月20日 10:32:41

相关推荐

发表回复

登录后才能评论
关注微信