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

三星Galaxy S8(Android8.0.0)FCM Instance Id无法生成求助

三星Galaxy S8(Android 8.0)FCM Instance ID生成失败问题解决

我帮你分析下这个问题:核心是在三星Galaxy S8(Android 8.0)设备上,FCM的Instance ID(也就是Token)无法生成,导致MainActivity里的Log.d抛出了NullPointerException,而其他设备运行正常。结合你提供的代码和报错日志,问题主要出在旧版FCM API的兼容性和同步获取Token的异步逻辑冲突上,再加上三星Android 8.0定制ROM的后台限制,才出现了这个特定设备的问题。下面是具体的诊断和修复步骤:

一、先解决直接触发崩溃的空指针问题

你在MainActivity的onCreate里直接调用FirebaseInstanceId.getInstance().getToken(),但FCM Token的生成是异步操作,在App启动初期可能还没完成,返回了null,而Log.d的第二个参数不能为null,所以触发了println needs a message的异常。

修复这个问题很简单,改用异步方式获取Token:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "fcmToken";
    Button invokeServer;
    String url="http://10.0.3.2/fcm/fcmInsert.php";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 异步获取Token,避免空指针
        FirebaseMessaging.getInstance().getToken()
                .addOnCompleteListener(task -> {
                    if (!task.isSuccessful()) {
                        Log.w(TAG, "获取FCM Token失败", task.getException());
                        return;
                    }
                    // 获取到有效Token
                    String token = task.getResult();
                    Log.d(TAG, "FCM Token: " + token);
                    // 这里可以把Token上传到你的服务器
                    // sendTokenToServer(token);
                });
    }
}

二、替换废弃的FCM API(关键修复)

你用的FirebaseInstanceIdService已经被Google废弃了,在Android 8.0及以上的后台服务限制下,尤其是三星的定制ROM,这个服务可能无法被正确触发,导致Token根本不会生成。

1. 更新FCM依赖(确保用最新版本)

在Module级别的build.gradle里更新FCM依赖:

implementation 'com.google.firebase:firebase-messaging:23.0.0' // 或更高版本

2. 重构Token获取逻辑

删除旧的FCMInstance类,把Token获取逻辑合并到FcmMessageReceiver里(它继承的FirebaseMessagingService是官方推荐的最新实现):

public class FcmMessageReceiver extends FirebaseMessagingService {
    private static final String TAG = "fcmToken";

    // 当Token刷新时会调用这个方法
    @Override
    public void onNewToken(String token) {
        super.onNewToken(token);
        Log.d(TAG, "刷新后的Token: " + token);
        // 把Token上传到你的服务器
        sendTokenToServer(token);
    }

    // 保留你原有的消息接收逻辑
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d("fcm","收到消息");
        String title= remoteMessage.getNotification().getTitle();
        String body= remoteMessage.getNotification().getBody();
        Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder mNotifyBuilder;
        NotificationManager mNotificationManager;
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        int notifyID = 9001;
        mNotifyBuilder = new NotificationCompat.Builder(getApplicationContext())
                .setContentTitle(title)
                .setContentText(body)
                .setSmallIcon(R.mipmap.ic_launcher);
        mNotifyBuilder.setContentIntent(resultPendingIntent);
        int defaults = 0;
        defaults = defaults | Notification.DEFAULT_SOUND;
        mNotifyBuilder.setDefaults(defaults);
        mNotifyBuilder.setAutoCancel(true);
        mNotificationManager.notify(notifyID, mNotifyBuilder.build());
    }

    // 实现Token上传到服务器的逻辑
    private void sendTokenToServer(String token) {
        // 这里可以用OkHttp、Volley等网络库实现上传
    }
}

3. 更新Manifest配置

删除原有的FCMInstance服务声明,确保FcmMessageReceiver的配置正确:

<service android:name=".FcmMessageReceiver">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

三、针对三星Android 8.0设备的额外排查

如果上面的修复后还是有问题,可能是三星ROM的后台限制导致的:

  • 关闭电池优化:进入设置 > 电池 > 电池优化 > 找到你的应用 > 设置为「不优化」
  • 解除后台限制:进入设置 > 应用程序 > 你的应用 > 电池 > 关闭「后台限制」
  • 更新Google Play服务:确保设备上的Google Play服务是最新版本,旧版本可能和FCM不兼容
  • 清除应用缓存数据:尝试清除应用的缓存和数据,然后重启应用再测试

你提供的原代码与报错日志参考

清单文件(Manifest File):

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ideabinbd.fcmimplementation"> 
    <uses-permission android:name="android.permission.INTERNET"/> 
    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> 
        <activity android:name=".MainActivity"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <service android:name=".FCMInstance"> 
            <intent-filter> 
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> 
            </intent-filter> 
        </service> 
        <service android:name=".FcmMessageReceiver"> 
            <intent-filter> 
                <action android:name="com.google.firebase.MESSAGING_EVENT"/> 
            </intent-filter> 
        </service> 
    </application> 
</manifest>

Instance Id类(已废弃):

public class FCMInstance extends FirebaseInstanceIdService { 
    private final String TAG="fcmToken"; 
    public String currentToken; 
    @Override 
    public void onTokenRefresh() { 
        currentToken= FirebaseInstanceId.getInstance().getToken(); 
        Log.d(TAG, currentToken); 
    } 
}

消息接收服务:

public class FcmMessageReceiver extends FirebaseMessagingService { 
    @Override 
    public void onMessageReceived(RemoteMessage remoteMessage) { 
        Log.d("fcm","messageRecieved"); 
        String title= remoteMessage.getNotification().getTitle(); 
        String body= remoteMessage.getNotification().getBody(); 
        Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); 
        PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
        NotificationCompat.Builder mNotifyBuilder; 
        NotificationManager mNotificationManager; 
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
        int notifyID = 9001; 
        mNotifyBuilder = new NotificationCompat.Builder(getApplicationContext()) 
                .setContentTitle(title) 
                .setContentText(body) 
                .setSmallIcon(R.mipmap.ic_launcher); 
        mNotifyBuilder.setContentIntent(resultPendingIntent); 
        int defaults = 0; 
        defaults = defaults | Notification.DEFAULT_SOUND; 
        mNotifyBuilder.setDefaults(defaults); 
        mNotifyBuilder.setAutoCancel(true); 
        mNotificationManager.notify(notifyID, mNotifyBuilder.build()); 
    } 
}

MainActivity代码:

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = "fcmToken"; 
    Button invokeServer; 
    String url="http://10.0.3.2/fcm/fcmInsert.php"; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        Log.d(TAG, FirebaseInstanceId.getInstance().getToken()); 
    } 
}

报错日志:

Process: com.ideabinbd.fcmimplementation, PID: 809 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ideabinbd.fcmimplementation/com.ideabinbd.fcmimplementation.MainActivity}: java.lang.NullPointerException: println needs a message 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2955) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6938) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 
Caused by: java.lang.NullPointerException: println needs a message 
at android.util.Log.println_native(Native Method) 
at android.util.Log.d(Log.java:161) 
at com.ideabinbd.fcmimplementation.MainActivity.onCreate(MainActivity.java:34) 
at android.app.Activity.performCreate(Activity.java:7174) 
at android.app.Instrumentation.callActivityOnCreate(I

内容的提问来源于stack exchange,提问作者Mohaimanul Chowdhury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:45:35