前台服务在开发版本中工作正常,但在预览版本中则不然

问题描述 投票:0回答:1

我已经在使用 React Native + Expo 编码的 Android 应用程序中拥有一个运行良好的前台服务 (49)。我使用 Notifee 创建服务并显示通知来执行此操作。

在我的开发版本中,一切正常,工作完成得很好。但是,当我创建独立运行的预览版本时,前台服务看起来好像已经启动(通知显示),而所有其他事情似乎都没有启动。

前台服务只是尝试连接蓝牙设备,如果连接成功,获取RSSI并计算到设备的大概距离并断开连接。接下来,通过 REST API 通知我的服务器。所有这一切每 35 秒重复一次。

我将其添加到 AndroidManifest 中。

<service android:name="app.notifee.core.ForegroundService" android:foregroundServiceType="location|dataSync" android:directBootAware="true" />

以及此权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />  
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />  

但是服务看起来没有启动,因为我的后端服务器没有被 API 调用:\

此主题中的开发版本和预/产品版本之间有什么区别?我是否失去了一些事实?

提前感谢您的回答。

android expo foreground-service
1个回答
0
投票

您面临的问题似乎与 Android 13+(SDK 34 或更高版本)的权限和服务声明有关。在 Android 13 中,位置和 dataSync 等新的前台服务类型需要特定的前台服务权限,并且需要显式声明和处理这些权限。

您的开发版本可以工作,因为它可能在较低的 SDK 版本上运行,或者因为开发版本中的权限处理更宽松。然而,在生产版本中,更严格的权限要求可能会导致服务无法正常运行。

解决问题的要点: 自定义前台服务权限:Android 13+ 要求您为特定前台服务类型(例如位置或数据同步)定义和请求自定义权限。不幸的是,这些权限(如 android.permission.FOREGROUND_SERVICE_LOCATION 和 android.permission.FOREGROUND_SERVICE_DATA_SYNC)并未在 React Native 或 Expo 中预先定义。

解决方案:创建自定义权限模块:您需要创建自定义本机模块以通过编程方式请求这些权限。以下是在 Kotlin 中实现它的方法:

创建

MyPermissionsModule.kt
: 科特林

package com.yourapp

import android.app.Activity
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import com.facebook.react.bridge.*

class MyPermissionsModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

override fun getName(): String {
    return "MyPermissionsModule"
}

@ReactMethod
fun requestForegroundServicePermissions(promise: Promise) {
    val activity = currentActivity ?: run {
        promise.reject("ERROR", "Activity is null")
        return
    }

    if (android.os.Build.VERSION.SDK_INT >= 34) {
        val permissions = arrayOf(
            "android.permission.FOREGROUND_SERVICE_LOCATION",
            "android.permission.FOREGROUND_SERVICE_DATA_SYNC"
        )

        ActivityCompat.requestPermissions(activity, permissions, 1)
        promise.resolve(true)
        } else {
            promise.resolve(false)
        }
    }
}

添加到主应用程序: 在 MainApplication 的 getPackages 方法中注册您的模块:

科特林

packages.add(MyPermissionsModule(reactContext))

JavaScript端:使用React Native中的模块在启动前台服务之前请求权限:

javascript

import { NativeModules, Platform } from 'react-native';

const { MyPermissionsModule } = NativeModules;

const requestPermissions = async () => {
  if (Platform.OS === 'android' && Platform.Version >= 34) {
    try {
      await MyPermissionsModule.requestForegroundServicePermissions();
    } catch (error) {
  console.error('Error requesting permissions:', error);
    }
  }
};

其他 AndroidManifest 条目:确保您已正确定义所需的权限和服务类型:

xml

<service
    android:name="app.notifee.core.ForegroundService"
    android:foregroundServiceType="location|dataSync"
    android:directBootAware="true" />

在启动前台服务之前调用权限请求:在启动前台服务之前,调用 requestPermissions() 以确保授予必要的权限。

生产与开发构建:在开发中,权限的处理通常更宽松,或者可能默认为“授予”。在生产中,尤其是较新的 SDK 版本,需要显式请求和处理权限。

为什么这很重要: 如果没有明确请求前台服务类型的这些新权限,您的服务可能会显示通知但无法执行其预期任务。

此方法应该可以解决您的问题,并确保您的前台服务在开发和生产构建中一致工作。如果您需要进一步帮助,请告诉我!

© www.soinside.com 2019 - 2024. All rights reserved.