Вопрос или проблема
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
, не может быть активирована, если приложение не запущено на устройстве.
Решение
-
Использование Расширенных Уведомлений: Вам необходимо использовать уведомления, которые могут инициировать действие (например, открытие экрана входящего звонка), когда приложение не запущено. Для этого вам нужно убедиться, что ваши уведомления корректно настроены на обработку действий.
-
Использование
onNotificationOpenedApp
: В разделе инициализации используйтеNotifications.setNotificationHandler
чтобы настроить обработчики уведомлений, как только пользователь взаимодействует с уведомлением. Например:Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: false, }), });
-
Проверка инициализации 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', } });
-
Отправка Уведомлений с Действиями: Когда вы отправляете уведомление, укажите в нём действия и добавьте
data
, которые будут использоваться для отображения экрана входящего звонка. Например:await Notifications.scheduleNotificationAsync({ content: { title: 'Входящий звонок', body: JSON.stringify({ uuid: 'some-unique-uuid', instructorName: 'Instructor Name' }), data: { someData: 'data' }, // Добавляем действия для уведомления actions: ['Accept', 'Decline'] }, trigger: null, // Сразу отправляем });
-
Обработка Действий из Уведомлений: Также вам нужно будет добавить обработку событий открытия уведомлений, используя
Notifications.addNotificationResponseReceivedListener
.Notifications.addNotificationResponseReceivedListener(response => { const { uuid, instructorName } = JSON.parse(response.notification.request.content.data); CallKeep.displayIncomingCall(uuid, "9999999999", instructorName, 'generic', true); });
Заключение
Ни одно из предложенных решений не гарантирует абсолютной надежности в условиях, когда приложение убито, поскольку Android имеет свои ограничения на фоновую активность. Однако с правильной настройкой уведомлений и учетом специфических особенностей вашего случая можно приблизиться к желаемой функциональности. Если ваши проблемы сохраняются, возможно, стоит рассмотреть использование нативного кода для более полного контроля над фоновыми процессами или сторонних библиотек, которые могут обеспечить дополнительную функциональность для работы с телефонами.
Таким образом, вы сможете обрабатывать входящие вызовы даже в состоянии, когда приложение закрыто. Помните, что требуется протестировать каждое изменение на различных устройствах и версиях Android для обеспечения максимальной совместимости.