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

Unity Android端MQTT后台运行及开机自启问题咨询

问题解答

1. 能否通过Android Manifest实现后台持续运行?

只靠Manifest配置不行,得结合Android的前台服务机制——从Android 8.0(API 26)开始,系统对后台进程限制极严,普通后台进程很容易被系统杀死。你需要把MQTT收发逻辑放到前台服务里,同时在Manifest中声明必要权限和服务组件。

具体步骤:

  • 添加权限:在Manifest的<manifest>标签下新增:
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 防止设备休眠中断MQTT连接 -->
    
  • 声明前台服务:在<application>标签内添加服务声明:
    <service
        android:name=".MqttForegroundService"
        android:foregroundServiceType="connectedDevice" <!-- 适配IoT/设备连接类服务的系统优先级 -->
        android:exported="false" />
    
  • Unity端启动前台服务:通过C#调用Android原生代码触发服务启动,示例代码:
    using UnityEngine;
    
    public class MqttBackgroundHandler : MonoBehaviour
    {
        private AndroidJavaObject _serviceIntent;
    
        void Start()
        {
            AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
            AndroidJavaClass serviceClass = new AndroidJavaClass("com.company.productname.MqttForegroundService");
            _serviceIntent = new AndroidJavaObject("android.content.Intent", currentActivity, serviceClass);
    
            if (GetCurrentAndroidSDKVersion() >= 26)
            {
                currentActivity.Call("startForegroundService", _serviceIntent);
            }
            else
            {
                currentActivity.Call("startService", _serviceIntent);
            }
        }
    
        private int GetCurrentAndroidSDKVersion()
        {
            return AndroidJNI.CallStaticIntMethod(
                AndroidJNI.FindClass("android/os/Build"),
                AndroidJNI.GetStaticMethodID(AndroidJNI.FindClass("android/os/Build"), "VERSION.SDK_INT", "()I"),
                new jvalue[0]
            );
        }
    }
    
  • 编写Android原生服务类:创建MqttForegroundService.java,在onCreate方法中调用startForeground显示通知(必须步骤,否则系统会判定为后台服务并杀死),并在服务内部处理MQTT的连接、订阅和消息收发逻辑。

2. 能否实现设备重启后自动启动?

可以,但受Android版本限制(Android 10+限制更严格),需要结合广播接收器和前台服务实现。

具体步骤:

  • 添加权限:在Manifest中新增:
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
  • 声明广播接收器:在<application>标签内添加:
    <receiver
        android:name=".BootCompletedReceiver"
        android:exported="true"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <!-- 适配部分厂商的快速开机逻辑 -->
        </intent-filter>
    </receiver>
    
  • 实现广播接收器:创建BootCompletedReceiver.java,在onReceive中启动前台服务:
    package com.company.productname;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    public class BootCompletedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                Intent serviceIntent = new Intent(context, MqttForegroundService.class);
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                    context.startForegroundService(serviceIntent);
                } else {
                    context.startService(serviceIntent);
                }
            }
        }
    }
    
  • 注意事项:Android 10+需要用户手动授予“自动启动”权限(不同手机厂商的开启路径不同,需引导用户操作),否则广播接收器不会触发;另外,应用必须至少被用户手动启动过一次,才能在设备重启后被唤醒。

修改后的完整Manifest代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
          android:versionCode="1" 
          android:versionName="1.0" 
          package="com.company.productname">

  <supports-screens android:anyDensity="true" 
                    android:largeScreens="true" 
                    android:normalScreens="true" 
                    android:smallScreens="true" 
                    android:xlargeScreens="true" />

  <!-- 新增必要权限 -->
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

  <application android:icon="@drawable/app_icon" 
               android:label="@string/app_name" 
               android:theme="@style/UnityTransparentStatusBarTheme">

    <activity android:label="@string/app_name" 
              android:name="com.unity3d.nostatusbar.UnityPlayerActivityStatusBar" 
              android:fitsSystemWindows="true" >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>

    <!-- 声明前台服务 -->
    <service
        android:name=".MqttForegroundService"
        android:foregroundServiceType="connectedDevice"
        android:exported="false" />

    <!-- 声明开机启动广播接收器 -->
    <receiver
        android:name=".BootCompletedReceiver"
        android:exported="true"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

  </application>

  <uses-sdk android:minSdkVersion="26" android:targetSdkVersion="33" /> <!-- 建议升级目标SDK版本以适配最新系统限制 -->
</manifest>

内容的提问来源于stack exchange,提问作者Jim Mede

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:03:15