usePushNotifications.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { useEffect, useState, useRef } from 'react';
  2. import * as Notifications from 'expo-notifications';
  3. import * as Device from 'expo-device';
  4. import Constants from 'expo-constants';
  5. import { Platform } from 'react-native';
  6. export interface PushNotificationState {
  7. notification?: Notifications.Notification;
  8. expoPushToken?: Notifications.ExpoPushToken;
  9. }
  10. export const usePushNotifications = (): PushNotificationState => {
  11. const [expoPushToken, setExpoPushToken] = useState<Notifications.ExpoPushToken | undefined>();
  12. const [notification, setNotification] = useState<Notifications.Notification | undefined>();
  13. const notificationListener = useRef<Notifications.Subscription>();
  14. const responseListener = useRef<Notifications.Subscription>();
  15. useEffect(() => {
  16. Notifications.setNotificationHandler({
  17. handleNotification: async () => ({
  18. shouldPlaySound: true,
  19. shouldShowAlert: true,
  20. shouldSetBadge: true,
  21. icon: './assets/images/cc.png',
  22. vibrate: true,
  23. shouldShowWhenInForeground: true
  24. })
  25. });
  26. registerForPushNotificationAsync().then((token) => {
  27. setExpoPushToken(token);
  28. });
  29. notificationListener.current = Notifications.addNotificationReceivedListener((notification) => {
  30. setNotification(notification);
  31. });
  32. responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => {
  33. console.log(response);
  34. });
  35. return () => {
  36. Notifications.removeNotificationSubscription(notificationListener.current!);
  37. Notifications.removeNotificationSubscription(responseListener.current!);
  38. };
  39. }, []);
  40. return {
  41. expoPushToken,
  42. notification
  43. };
  44. };
  45. async function registerForPushNotificationAsync() {
  46. let token;
  47. // Check if the device is a physical device, because this only works for physical devices not simulators
  48. if (Device.isDevice) {
  49. const { status: existingStatus } = await Notifications.getPermissionsAsync();
  50. let finalStatus = existingStatus;
  51. if (existingStatus !== 'granted') {
  52. const { status } = await Notifications.requestPermissionsAsync();
  53. finalStatus = status;
  54. }
  55. if (finalStatus !== 'granted') {
  56. alert('需要通知權限才能接收充電狀態更新。請前往「設定」>「通知」中開啟 CrazyCharge 的通知權限。');
  57. return;
  58. }
  59. //if we have permission, then get the token
  60. token = await Notifications.getExpoPushTokenAsync({
  61. projectId: Constants.expoConfig?.extra?.eas?.projectId
  62. });
  63. if (Platform.OS === 'android') {
  64. Notifications.setNotificationChannelAsync('default', {
  65. name: 'default',
  66. importance: Notifications.AndroidImportance.MAX,
  67. vibrationPattern: [0, 250, 250, 250],
  68. lightColor: '#FF231F7C'
  69. });
  70. }
  71. // console.log('token', token);
  72. return token;
  73. } else {
  74. console.log('Must use physical device for Push Notifications');
  75. }
  76. }