0

I would like to play sound when some location - region entered. I am sending a store dispatch when I enter the region and I can see the expo-notification but the sound is not played. (I have to open up the app every time if I need to hear the sound)

My Code is the following;

App.js, I am registering the task

import React, {useEffect, useRef, useState} from 'react'
import MainRouter from "./router/MainRouter";
import {Provider} from "react-redux";
import {RootSiblingParent} from 'react-native-root-siblings';
import * as TaskManager from "expo-task-manager";
import {persistor, store} from "./redux/Store";
import {PersistGate} from "redux-persist/integration/react";
import {GeofencingEventType} from "expo-location";
import {removeExpoToken, saveExpoToken, trackingEntered} from "./redux/reducers/LocationActions";
import * as Notifications from "expo-notifications";
import * as Device from 'expo-device';
import {Platform} from "react-native";
Notifications.setNotificationHandler({
    handleNotification: async () => ({
        shouldShowAlert: true,
        shouldPlaySound: true,
        shouldSetBadge: false,
    }),
});
async function sendPushNotification(expoPushToken, title,body) {
    const message = {
        to: expoPushToken,
        sound: 'default',
        title: title,
        body: body
    };

    await fetch('https://exp.host/--/api/v2/push/send', {
        method: 'POST',
        headers: {
            Accept: 'application/json',
            'Accept-encoding': 'gzip, deflate',
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(message),
    });
}
async function registerForPushNotificationsAsync() {
    let token;
    if (Device.isDevice) {
        const { status: existingStatus } = await Notifications.getPermissionsAsync();
        let finalStatus = existingStatus;
        if (existingStatus !== 'granted') {
            const { status } = await Notifications.requestPermissionsAsync();
            finalStatus = status;
        }
        if (finalStatus !== 'granted') {
            alert('Failed to get push token for push notification!');
            return;
        }
        token = (await Notifications.getExpoPushTokenAsync()).data;
        console.log(token);
    } else {
        alert('Must use physical device for Push Notifications');
    }

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

    return token;
}


TaskManager.defineTask(LOCATION_TRACKING, async ({data: { eventType, region }, error}) => {
    if (error) {
        console.log('LOCATION_TRACKING task ERROR:', error);
        return;
    }
    if (eventType === GeofencingEventType.Enter) {
        console.log("You've entered region:", JSON.stringify(region));
        alert("You've entered region: "+ JSON.stringify(region.identifier))
        await sendPushNotification(store.getState().location.expoToken,APP_NAME,"You've entered region: "+ JSON.stringify(region.identifier))
        store.dispatch(trackingEntered(region.identifier))
    } else if (eventType === GeofencingEventType.Exit) {
        console.log("You've left region:", JSON.stringify(region));
    }
})


export default function App() {
    const notificationListener = useRef();
    const responseListener = useRef();

    useEffect(() => {
        registerForPushNotificationsAsync().then(token => {
            store.dispatch(saveExpoToken(token))
        });

        notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
            console.log(notification)
        });

        responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
            console.log(response);
        });

        return () => {
            Notifications.removeNotificationSubscription(notificationListener.current);
            Notifications.removeNotificationSubscription(responseListener.current);
            store.dispatch(removeExpoToken())
        };
    }, []);
    return (
        <RootSiblingParent>
            <Provider store={store}>
                <PersistGate persistor={persistor} loading={null}>
                    <MainRouter/>
                </PersistGate>
            </Provider>
        </RootSiblingParent>
    );
}

And AudioScreen.js I am retrieving the region and play the sound of it

const AudioScreen = (props) =>{  const song = useSelector((state) => state.location.identifier)  useEffect(() => {
        if(song){
            (async () =>{
                if(song.music){
                    const { sound } = await Audio.Sound.createAsync(song.music);
                    sound.getStatusAsync().then(async status => {
                        if (!status.isPlaying) {
                            await sound.playAsync();
                        }
                    })
                    sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
                }
            })();
        }
    },[song])   useEffect(() => {
        (async () => {


       await Location.startLocationUpdatesAsync(LOCATION_TRACKING, {
            accuracy: Location.Accuracy.Highest,
            timeInterval: 5000,
            distanceInterval: 0,
            deferredUpdatesInterval: 1000,
            showsBackgroundLocationIndicator: true
        });


            await Audio.setAudioModeAsync({
                allowsRecordingIOS: false,
                staysActiveInBackground: true,
                interruptionModeIOS: InterruptionModeIOS.DoNotMix,
                playsInSilentModeIOS: true,
                shouldDuckAndroid: true,
                interruptionModeAndroid: InterruptionModeAndroid.DoNotMix,
                playThroughEarpieceAndroid: false
            });
        })();

    }, []); }
Falzao
  • 23
  • 4

0 Answers0