Flutter在特定设备上无法获取设备令牌
我正在开发一个Flutter应用,在应用启动时获取设备令牌。这在几乎所有设备上都正常工作,只有少数设备例外。当我们联系用户时,发现这个问题仅发生在Redmi设备上。这感觉很奇怪。下面是用于获取设备令牌并通过重复该过程来确保其被正确获取的代码。
import 'dart:async';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
class FcmTokenManager {
static final FirebaseMessaging _messaging = FirebaseMessaging.instance;
static String? _cachedToken;
/// Initialize FCM token handling
static Future<void> init(Function(String token) onTokenReceived) async {
// Request notification permissions (important for Xiaomi/MIUI)
await _messaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
// Try to fetch token immediately
await _fetchToken(onTokenReceived);
// Listen for token refresh events
_messaging.onTokenRefresh.listen((newToken) {
debugPrint("FCM Token refreshed -> $newToken");
_cachedToken = newToken;
onTokenReceived(newToken);
});
}
/// Fetch token with retries
static Future<void> _fetchToken(Function(String token) onTokenReceived) async {
try {
String? token = await _messaging.getToken();
if (token == null) {
debugPrint("FCM Token is null, retrying...");
token = await _retryGetToken();
}
if (token != null) {
debugPrint("FCM Token -> $token");
_cachedToken = token;
onTokenReceived(token);
} else {
debugPrint("FCM Token could not be retrieved.");
}
} catch (e) {
debugPrint("FCM Token Error -> $e");
}
}
/// Retry mechanism: try multiple times with delay
static Future<String?> _retryGetToken({int retries = 3}) async {
String? token;
for (int i = 0; i < retries; i++) {
await Future.delayed(Duration(seconds: 2));
token = await _messaging.getToken();
if (token != null) break;
}
return token;
}
/// Get cached token if available
static String? get cachedToken => _cachedToken;
}
这在上一版本中一直工作正常(在所有设备上)。新版本的变动是compileSdkVersion从 34升级到36,targetSdkVersion从 34升级到35,Kotlin版本也发生了变化。
注:应用正在请求通知权限,用户已允许。
为什么会出现这个问题?有人能帮我解决吗?
解决方案
我们在Redmi设备上也遇到了同样的FCM问题,下面的解决方案解决了它。将以下代码片段添加到你的 AndroidManifest.xml 文件中。
在 <manifest> 标签内:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
在 <application> 标签内:
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。