All checks were successful
Dev Deploy / Explore-Gitea-Actions (push) Successful in 24s
149 lines
5.2 KiB
TypeScript
149 lines
5.2 KiB
TypeScript
import Constants from 'expo-constants';
|
||
import * as Device from 'expo-device';
|
||
import * as Notifications from 'expo-notifications';
|
||
import { useEffect, useState } from 'react';
|
||
import { Button, Platform, Text, View } from 'react-native';
|
||
|
||
Notifications.setNotificationHandler({
|
||
handleNotification: async () => ({
|
||
shouldPlaySound: false,
|
||
shouldSetBadge: false,
|
||
shouldShowBanner: true,
|
||
shouldShowList: true,
|
||
}),
|
||
});
|
||
|
||
export default function AuthNotifications({ setNotificationsEnabled, notificationsEnabled }: { setNotificationsEnabled: (value: boolean) => void, notificationsEnabled: boolean }) {
|
||
const [expoPushToken, setExpoPushToken] = useState('');
|
||
const [channels, setChannels] = useState<Notifications.NotificationChannel[]>([]);
|
||
const [notification, setNotification] = useState<Notifications.Notification | undefined>(
|
||
undefined
|
||
);
|
||
|
||
useEffect(() => {
|
||
console.log('notificationsEnabled', notificationsEnabled);
|
||
registerForPushNotificationsAsync().then(token => {
|
||
console.log('token', token);
|
||
token && setExpoPushToken(token)
|
||
});
|
||
|
||
if (Platform.OS === 'android') {
|
||
Notifications.getNotificationChannelsAsync().then(value => setChannels(value ?? []));
|
||
}
|
||
const notificationListener = Notifications.addNotificationReceivedListener(notification => {
|
||
setNotification(notification);
|
||
});
|
||
|
||
const responseListener = Notifications.addNotificationResponseReceivedListener(response => {
|
||
console.log(response);
|
||
});
|
||
|
||
return () => {
|
||
notificationListener.remove();
|
||
responseListener.remove();
|
||
};
|
||
}, [notificationsEnabled]);
|
||
|
||
return (
|
||
<View
|
||
style={{
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
justifyContent: 'space-around',
|
||
display: "none"
|
||
}}>
|
||
<Text>Your expo push token: {expoPushToken}</Text>
|
||
<Text>{`Channels: ${JSON.stringify(
|
||
channels.map(c => c.id),
|
||
null,
|
||
2
|
||
)}`}</Text>
|
||
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
|
||
<Text>Title: {notification && notification.request.content.title} </Text>
|
||
<Text>Body: {notification && notification.request.content.body}</Text>
|
||
<Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text>
|
||
</View>
|
||
<Button
|
||
title="Press to schedule a notification"
|
||
onPress={async () => {
|
||
await schedulePushNotification();
|
||
}}
|
||
/>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
async function schedulePushNotification() {
|
||
await Notifications.scheduleNotificationAsync({
|
||
content: {
|
||
title: "You've got mail! 📬",
|
||
body: 'Here is the notification body',
|
||
data: { data: 'goes here', test: { test1: 'more data' } },
|
||
},
|
||
trigger: {
|
||
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
|
||
seconds: 2,
|
||
},
|
||
});
|
||
}
|
||
|
||
async function registerForPushNotificationsAsync() {
|
||
let token;
|
||
|
||
// 1. Android 特定配置
|
||
if (Platform.OS === 'android') {
|
||
await Notifications.setNotificationChannelAsync('myNotificationChannel', {
|
||
name: 'A channel is needed for the permissions prompt to appear',
|
||
importance: Notifications.AndroidImportance.MAX, // 最高优先级
|
||
vibrationPattern: [0, 250, 250, 250], // 振动模式
|
||
lightColor: '#FF231F7C', // 通知灯颜色
|
||
});
|
||
}
|
||
|
||
// 2. 检查是否在真实设备上运行
|
||
if (Device.isDevice) {
|
||
// 3. 检查通知权限状态
|
||
const { status: existingStatus } = await Notifications.getPermissionsAsync();
|
||
let finalStatus = existingStatus;
|
||
|
||
// 4. 如果尚未授予权限,则请求权限
|
||
if (existingStatus !== 'granted') {
|
||
const { status } = await Notifications.requestPermissionsAsync();
|
||
finalStatus = status;
|
||
}
|
||
|
||
// 5. 如果权限被拒绝,显示警告并返回
|
||
if (finalStatus !== 'granted') {
|
||
alert('Failed to get push token for push notification!');
|
||
return;
|
||
}
|
||
|
||
// 6. 获取推送令牌
|
||
try {
|
||
// 获取项目ID(用于Expo推送通知服务)
|
||
const projectId =
|
||
Constants?.expoConfig?.extra?.eas?.projectId ??
|
||
Constants?.easConfig?.projectId;
|
||
|
||
if (!projectId) {
|
||
throw new Error('Project ID not found');
|
||
}
|
||
|
||
// 获取Expo推送令牌
|
||
token = (
|
||
await Notifications.getExpoPushTokenAsync({
|
||
projectId,
|
||
})
|
||
).data;
|
||
console.log(token); // 打印令牌,实际应用中应该发送到你的服务器
|
||
|
||
} catch (e) {
|
||
token = `${e}`; // 错误处理
|
||
}
|
||
} else {
|
||
// 7. 如果是在模拟器上运行,显示警告
|
||
alert('Must use physical device for Push Notifications');
|
||
}
|
||
|
||
return token; // 返回获取到的令牌
|
||
} |