React Native Expo Фоновая уведомление работает в переднем/заднем плане, но не работает при закрытом приложении (Интеграция CallKeep)

Вопрос или проблема

React Native Expo Фоновая уведомление работает в переднем/заднем плане, но не работает при закрытом приложении (Интеграция CallKeep)

Я работаю над проектом React Native Expo, в котором мне нужно обрабатывать уведомления о входящих звонках с использованием expo-notifications, expo-task-manager и react-native-callkeep. Цель состоит в том, чтобы отображать экран входящего звонка, даже когда приложение завершено (убито/закрыто). Вот что я реализовал до сих пор:

import { Component } from 'react';
import Routes from "./Navigations/Route";
import * as React from 'react';
import { registerRootComponent } from 'expo';
import { Provider } from 'react-redux';
import store from './store/store';
import * as TaskManager from "expo-task-manager";
import * as Notifications from "expo-notifications";
import CallKeep from 'react-native-callkeep';

const BACKGROUND_NOTIFICATION_TASK = "BACKGROUND-NOTIFICATION-TASK";

TaskManager.defineTask(
  BACKGROUND_NOTIFICATION_TASK,
  ({ data, error, executionInfo }) => {
    if (error) {
      console.log("Произошла ошибка:", error);
    }
    if (data) {
      console.log("Полученные данные:", data);
      let res = JSON.parse(data.notification.data.body);
      CallKeep.displayIncomingCall(res.uuid, "9999999999", res.instructorName, 'generic', true);
    }
  }
);

Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);

export default class App extends Component {
  componentDidMount() {
    // Любая другая инициализация
  }

  render() {
    return (
      <Provider store={store}>
        <Routes />
      </Provider>
    );
  }
};

registerRootComponent(App);

Проблема:
Эта реализация работает нормально, когда приложение находится на переднем или фоновом плане. Когда приходит уведомление только с данными, фоновая задача срабатывает, и CallKeep успешно отображает экран входящего звонка.

Однако, когда приложение завершено (убито/закрыто), фоновая задача не срабатывает, и экран входящего звонка не появляется. Я использую expo-notifications, expo-task-manager и react-native-callkeep.

Как мне обрабатывать входящие звонки и вызывать CallKeep, когда приложение завершено (убито/закрыто)?

Есть ли какие-либо предложения или обходные пути, чтобы гарантировать, что expo-task manager или подобный сервис могут обрабатывать фоновые уведомления, когда приложение не работает?

Я тестировал это на Android

Ответ или решение

Для решения проблемы с обработкой входящих звонков при закрытом (убитом) приложении в вашем проекте React Native с использованием Expo, важно понимать ограничения платформы Android и поведение фоновых задач. Давайте подробно рассмотрим способы, как можно достичь необходимой функциональности.

Проблема

Ваша текущая реализация работает, когда приложение находится в переднем или фоновом режиме, но не запускается, когда приложение закрыто. Это связано с тем, что фоновая задача, определённая с помощью expo-task-manager, не может быть активирована, если приложение не запущено на устройстве.

Решение

  1. Использование Расширенных Уведомлений: Вам необходимо использовать уведомления, которые могут инициировать действие (например, открытие экрана входящего звонка), когда приложение не запущено. Для этого вам нужно убедиться, что ваши уведомления корректно настроены на обработку действий.

  2. Использование onNotificationOpenedApp: В разделе инициализации используйте Notifications.setNotificationHandler чтобы настроить обработчики уведомлений, как только пользователь взаимодействует с уведомлением. Например:

    Notifications.setNotificationHandler({
      handleNotification: async () => ({
        shouldShowAlert: true,
        shouldPlaySound: true,
        shouldSetBadge: false,
      }),
    });
  3. Проверка инициализации CallKeep: Убедитесь, что react-native-callkeep инициализирован правильно до попытки отображать входящий звонок. Добавьте вызов инициализации CallKeep в componentDidMount вашего основного компонента:

    CallKeep.setup({
      ios: {
        appName: "YourAppName",
      },
      android: {
        alertTitle: 'Permissions required',
        alertDescription: 'This app needs to access your phone to perform calling operations',
        cancelButton: 'Cancel',
        okButton: 'OK',
      }
    });
  4. Отправка Уведомлений с Действиями: Когда вы отправляете уведомление, укажите в нём действия и добавьте data, которые будут использоваться для отображения экрана входящего звонка. Например:

    await Notifications.scheduleNotificationAsync({
      content: {
        title: 'Входящий звонок',
        body: JSON.stringify({ uuid: 'some-unique-uuid', instructorName: 'Instructor Name' }),
        data: { someData: 'data' },
        // Добавляем действия для уведомления
        actions: ['Accept', 'Decline']
      },
      trigger: null, // Сразу отправляем
    });
  5. Обработка Действий из Уведомлений: Также вам нужно будет добавить обработку событий открытия уведомлений, используя Notifications.addNotificationResponseReceivedListener.

    Notifications.addNotificationResponseReceivedListener(response => {
      const { uuid, instructorName } = JSON.parse(response.notification.request.content.data);
      CallKeep.displayIncomingCall(uuid, "9999999999", instructorName, 'generic', true);
    });

Заключение

Ни одно из предложенных решений не гарантирует абсолютной надежности в условиях, когда приложение убито, поскольку Android имеет свои ограничения на фоновую активность. Однако с правильной настройкой уведомлений и учетом специфических особенностей вашего случая можно приблизиться к желаемой функциональности. Если ваши проблемы сохраняются, возможно, стоит рассмотреть использование нативного кода для более полного контроля над фоновыми процессами или сторонних библиотек, которые могут обеспечить дополнительную функциональность для работы с телефонами.

Таким образом, вы сможете обрабатывать входящие вызовы даже в состоянии, когда приложение закрыто. Помните, что требуется протестировать каждое изменение на различных устройствах и версиях Android для обеспечения максимальной совместимости.

Оцените материал
Добавить комментарий

Капча загружается...