React Native中Native服务调用的Headless JS任务未运行问题
问题描述
我尝试通过CallScreeningService触发Headless任务,将来电号码传递给Headless.js处理数据,同时为React Native(RN)应用启动前台服务。CallScreeningService.kt与CallHeadlessService.kt的日志已在logcat中输出,说明这两个服务正常运行,前台服务也处于活跃状态,但Headless.js始终未执行。
仅在启动前台服务时出现该问题,当RN应用处于打开状态时,Headless任务可正常运行。我已排除前台服务启动与Headless任务调用的延迟问题。
期望实现:当应用未运行时,由CallScreening触发前台服务并启动Headless任务。
CallScreeningService.kt
@RequiresApi(Build.VERSION_CODES.N) class CallScreeningService: CallScreeningService() { @SuppressLint("VisibleForTests") @RequiresApi(Build.VERSION_CODES.Q) override fun onScreenCall(callDetails: Call.Details) { Log.d("Call_Receiver", "[SERVICE] Fetching caller number") val incomingNum = callDetails.handle.schemeSpecificPart Log.d("Call_Receiver", "[SERVICE] Incoming call from: $incomingNum") val intentForeground = Intent(this, CallForegroundService::class.java) startService(intentForeground) Log.d("Call_Receiver", "[FOREGROUND] Service called") val intent = Intent(this, CallHeadlessService::class.java) intent.putExtra("incomingNumber", incomingNum) this.startService(intent) HeadlessJsTaskService.acquireWakeLockNow(this) Log.d("Call_Receiver", "[MODULE] Headless task waking up") val response = CallResponse.Builder() .setDisallowCall(false) .setSilenceCall(false) .build() respondToCall(callDetails, response) } }
CallHeadlessService.kt
package com.dev.justcall import android.content.Intent import android.util.Log import com.facebook.react.HeadlessJsTaskService import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.WritableMap import com.facebook.react.jstasks.HeadlessJsTaskConfig class CallHeadlessService : HeadlessJsTaskService() { override fun getTaskConfig(intent: Intent?): HeadlessJsTaskConfig { Log.d("Call_Receiver", "[HEADLESS] Task called") val incomingNumber = intent?.getStringExtra("incomingNumber") ?: "" Log.d("Call_Receiver", "[HEADLESS] Incoming Number: $incomingNumber") val taskData: WritableMap = Arguments.createMap() taskData.putString("incomingNumber", incomingNumber) Log.d("Call_Receiver", "[HEADLESS] Task Data: $taskData") return HeadlessJsTaskConfig( "IncomingCallTask", taskData, 0, true ) } }
Headless.js
import { AppRegistry, NativeModules } from "react-native"; //Import Javascript components import CallerID from "./CallerID"; import CleanPhoneNumber from "./CleanPhoneNumber"; import StartPage from "../../app"; import { name as appName } from '../../app.json'; const { CallNativeModule } = NativeModules; const handleIncomingCallTask = async (taskData) => { const { incomingNumber } = taskData; console.log('[HEADLESS] Task received incoming number:', incomingNumber); //Get wallet connection status and provider const { walletSigner } = global.appData; if (walletSigner) { console.log('[HEADLESS] User logged in'); try { const cleanedPhoneNumber = await CleanPhoneNumber(incomingNumber); const profile = await CallerID(cleanedPhoneNumber, walletSigner); const name = profile[0]; CallNativeModule.receiveCallerID(name, cleanedPhoneNumber); console.log('[HEADLESS] Caller ID sent to Native Module'); } catch (error) { if (error.message.includes('[HEADLESS] Invalid phone number length.')) { console.log('[HEADLESS] Invalid phone number length.'); } else if (error.message.includes('[HEADLESS] Phone number is not registered')) { console.log('[HEADLESS] Phone number is not registered.'); } else { console.log('[HEADLESS] Error:', error); }; }; } else { console.log('[HEADLESS] User not logged in'); }; }; console.log('[HEADLESS] App starting...'); AppRegistry.registerComponent(appName, () => StartPage); AppRegistry.registerHeadlessTask('IncomingCallTask', () => handleIncomingCallTask);
CallForegroundService.kt
package com.dev.justcall import android.app.NotificationChannel import android.app.NotificationManager import android.app.Service import android.content.Intent import android.os.Build import android.os.IBinder import android.util.Log import androidx.core.app.NotificationCompat class CallForegroundService : Service() { private val channelID = "CallServiceChannel" override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.d("Call_Receiver", "[FOREGROUND] Setting up") createNotificationChannel() val notification = NotificationCompat.Builder(this, channelID) .setContentTitle("Call Service") .setContentText("JustCall is active") .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_HIGH) .build() startForeground(1, notification) Log.d("Call_Receiver", "[FOREGROUND] Service started") return START_STICKY } override fun onBind(intent: Intent?): IBinder? { return null } private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val serviceChannel = NotificationChannel( channelID, "Caller ID Active", NotificationManager.IMPORTANCE_HIGH ) val manager = getSystemService(NotificationManager::class.java) manager.createNotificationChannel(serviceChannel) Log.d("Call_Receiver", "[FOREGROUND] Notification channel created") } } }
内容的提问来源于stack exchange,提问作者NgKs
相关产品推荐
相关产品推荐

