1

正如标题所暗示的,即使在我的 react-native 应用程序被杀死/后台模式之后,我也试图从我连接的 BLE 外围设备监听点击事件。

连接后,我的 BLE 外围设备上有一个通知订阅,每次我按下设备上的按钮时,我的应用都会收到通知。即使用户终止应用程序,我也希望此订阅能够持续。

该应用程序在前台和非活动状态下运行良好,但是当我在 iOS 上终止该应用程序时,它停止响应按钮单击。在 android 上,我找到了一个库react-native-background-actions来帮助解决这个问题。这是当前在android上工作的背景代码。

import BackgroundJob from "react-native-background-actions";


playing = BackgroundJob.isRunning();

const sleep = (time) =>
  new Promise((resolve) => setTimeout(() => resolve(), time));

BackgroundJob.on("expiration", () => {
  console.log("iOS: I am being closed!");
});

const taskRandom = async (taskData) => {
  if (Platform.OS === "ios") {
    console.warn(
      "This task will not keep your app alive in the background by itself, use other library like react-native-track-player that use audio,",
      "geolocalization, etc. to keep your app alive in the background while you excute the JS from this library."
    );
  }
  await new Promise(async (resolve) => {
    // For loop with a delay
    const { delay } = taskData;
    console.log(BackgroundJob.isRunning(), delay);
    for (let i = 0; BackgroundJob.isRunning(); i++) {
      console.log("Ran -> ", i);

    //   await BackgroundJob.updateNotification({
    //     taskDesc: "Emergency -> " + i,
    //   });
      await sleep(delay);
    }
  });
};

const options = {
  taskName: "Example",
  taskTitle: "ExampleTask title",
  taskDesc: "ExampleTask desc",
  taskIcon: {
    name: "ic_launcher",
    type: "mipmap",
  },
  color: "#ff00ff",
  linkingURI: "exampleScheme://chat/jane",
  parameters: {
    delay: 30000,
  },
};


/**
 * Toggles the background task
 */
export const toggleBackground = async () => {
playing = !playing;
  if (playing) {
    try {
      console.log("Trying to start background service");
      await BackgroundJob.start(taskRandom, options);
      console.log("Successful start!");
    } catch (e) {
      console.log("Error", e);
    }
  } else {
    console.log("Stop background service");
    await BackgroundJob.stop();
  }
};

我尝试阅读iOS 应用程序的核心蓝牙后台处理,并在我的启动方法上添加了一个恢复标识符,如下所示:

BleManager.start({
  showAlert: true,
  restoreIdentifierKey: "IDENTIFIER",
  queueIdentifierKey: "IDENTIFIER",
}).then(() => {
  console.log("Module initialized");
});

有没有人对如何在应用程序处于后台时保留订阅有任何建议?react-native-background-actions建议使用音频或地理位置库,但这些与我的应用程序无关。

任何帮助将不胜感激。

4

1 回答 1

1

您正在谈论两种截然不同的状态;背景和被杀。

如果您的应用程序不在屏幕上但仍在内存中,则它被“挂起”。它一直暂停,直到

  1. 它被用户带回前台
  2. 支持的后台事件发生并在再次暂停之​​前短暂执行。
  3. 它从内存中删除,因为 iOS 需要资源
  4. 它被用户“刷掉”从内存中删除

如果一个 iOS 应用程序被挂起并且你已经为你的应用程序添加了蓝牙后台​​模式,那么它就可以工作了;这是场景 2。

如果外围设备超出范围,您需要考虑要做什么;你想尝试重新连接还是想放弃。

如果您想尝试重新连接,那么您只需调用connect以响应断开连接。如果外围设备进入范围,那么 Core Bluetooth 将向您的应用程序提供回调(即使它已暂停)。这适用于方案 1 和 2。

一个应用程序可以处于两种不同的“已终止”状态;由系统终止并由用户终止。这些是场景 3 和 4

如果应用程序被系统终止,场景 3,并且您在初始化 Core Bluetooth 时设置了 Core Bluetooth 状态恢复,则 iOS 将重新启动您的应用程序。重新启动后,您需要再次设置 Core Bluetooth,然后该事件将照常传送到您的应用程序。

如果应用程序因用户向上滑动而终止,场景 4,那么一般来说,您的应用程序在用户重新启动之前已经死机。

你还没有展示你是如何使用核心蓝牙的,所以我不能提供任何具体的建议,但我可以说你展示的方法,试图让你的应用程序在后台运行,这不是正确的方法,绝对不会在 iOS 上工作。在 Android 上甚至可能有更好的方法,但我不熟悉那个平台。通常,将应用程序保留在内存中,执行无用的工作只会浪费内存和电池资源。

于 2022-01-31T19:51:30.303 回答