You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity安卓应用JNI报错:Unknown signature for type 'AlarmReceiver'求助

解决Unity安卓开发中JNI: Unknown signature for type 'AlarmReceiver'错误

错误原因

你在创建Intent时传入了C#的AlarmReceiver类型(typeof(AlarmReceiver)),但Android系统的Intent需要的是Java层BroadcastReceiver的完整类路径,而非C#侧的AndroidJavaProxy代理类类型。JNI无法识别C#类型的签名,因此抛出该错误。

解决方案

Android系统无法直接调度C#层的AndroidJavaProxy实现的广播接收器,必须通过Java原生BroadcastReceiver中转,再触发C#逻辑。以下是完整修复步骤:

1. 创建Android原生BroadcastReceiver

在Unity项目的Plugins/Android/com/yourpackage目录下(需自行创建对应包名路径),新建AlarmReceiver.java文件:

package com.yourpackage;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.unity3d.player.UnityPlayer;

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if ("Server_Managment_Background_Processes".equals(action)) {
            // 调用Unity中指定GameObject的C#方法
            UnityPlayer.UnitySendMessage("AlarmManagerHelperObject", "OnAlarmTriggered", "");
        }
    }
}

2. 注册BroadcastReceiver到AndroidManifest

在Plugins/Android目录下创建AndroidManifest.xml(若已有则修改),添加接收器注册:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yourpackage">
    <application>
        <receiver android:name=".AlarmReceiver">
            <intent-filter>
                <action android:name="Server_Managment_Background_Processes" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

3. 修正C#代码

更新AlarmManagerHelper,移除原C#侧的AlarmReceiver类,改为接收原生广播的回调:

using UnityEngine;
using System;

public class AlarmManagerHelper : MonoBehaviour
{
    public static AlarmManagerHelper Instance;
    private Action pendingAlarmAction;

    private void Start()
    {
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    public void ScheduleAlarm(float delayInSeconds, Action action)
    {
        pendingAlarmAction = action;
        long triggerTime = DateTime.Now.AddSeconds(delayInSeconds).Ticks / 10000;

        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        AndroidJavaObject alarmManager = currentActivity.Call<AndroidJavaObject>("getSystemService", "alarm");

        // 创建指向原生广播的Intent
        AndroidJavaObject alarmIntent = new AndroidJavaObject("android.content.Intent", "Server_Managment_Background_Processes");

        int requestCode = UnityEngine.Random.Range(0, int.MaxValue);
        AndroidJavaClass pendingIntentClass = new AndroidJavaClass("android.app.PendingIntent");
        // Android 12+需指定FLAG_IMMUTABLE,避免兼容性问题
        AndroidJavaObject pendingIntent = pendingIntentClass.CallStatic<AndroidJavaObject>("getBroadcast", currentActivity, requestCode, alarmIntent, 1 << 25);

        // 使用setExact保证触发时间准确性(API 19+)
        alarmManager.Call("setExact", 0, triggerTime, pendingIntent);
    }

    // 供Android原生调用的回调方法,需与UnitySendMessage参数匹配
    public void OnAlarmTriggered(string unused)
    {
        pendingAlarmAction?.Invoke();
        pendingAlarmAction = null;
    }
}

关键注意事项

  • 确保挂载AlarmManagerHelper的GameObject名称为AlarmManagerHelperObject(与UnitySendMessage的第一个参数一致),且该对象不会被场景销毁。
  • Android 12及以上版本创建PendingIntent必须指定FLAG_IMMUTABLE(值为1 << 25)或FLAG_MUTABLE,否则会抛出安全异常。
  • 若需要调度多个不同的闹钟任务,可通过Intent传递额外参数(如任务ID),在C#侧区分执行不同Action。

内容的提问来源于stack exchange,提问作者Adam Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:06:04