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

React Native非Expo版本前台服务正常但通知不显示问题

React Native 前台服务通知不显示问题排查与修复

1. 确保Android 13+通知权限已授予

Android 13(API 33)及以上版本仅在Manifest中声明POST_NOTIFICATIONS权限不够,必须在运行时主动请求。修改App.jsx添加权限请求逻辑:

import { NativeModules, PermissionsAndroid, Platform } from 'react-native';
const Clip = NativeModules.ClipboardService;

export const App = () => {
  const [whatsNextYCoord, setWhatsNextYCoord] = useState(0);
  const scrollViewRef = useRef(null);

  useEffect(() => {
    const requestNotificationPermission = async () => {
      if (Platform.OS === 'android' && Platform.Version >= 33) {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
          {
            title: '通知权限请求',
            message: '需要通知权限显示前台服务运行状态',
            buttonPositive: '允许',
            buttonNegative: '拒绝',
          },
        );
        return granted === PermissionsAndroid.RESULTS.GRANTED;
      }
      return true;
    };

    const startService = async () => {
      const hasPermission = await requestNotificationPermission();
      if (hasPermission && Clip) {
        console.log({ asd: Clip });
        Clip.startService();
      } else {
        console.log('权限未授予或模块不可用');
      }
    };

    startService();
  }, []);

  // 原有组件渲染逻辑
};

2. 检查通知图标有效性

Android通知图标要求为白色透明背景的矢量图/PNG图,若R.drawable.abacus不符合规范,通知会被系统隐藏。建议替换为项目中已有的合规图标,比如启动图标:

private void startForegroundService() {
    Log.d("ClipboardService", "Starting Foreground Service");
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Clipboard Service")
            .setContentText("Listening to clipboard changes")
            .setSmallIcon(R.mipmap.ic_launcher) // 替换为现有有效图标
            .setPriority(NotificationCompat.PRIORITY_HIGH);

    startForeground(1, builder.build());
}

3. 确认通知渠道字符串资源存在

确保res/values/strings.xml中定义了渠道名称与描述,否则通知渠道创建失败:

<resources>
    <!-- 其他现有字符串 -->
    <string name="channel_name">剪贴板服务通知</string>
    <string name="channel_description">显示剪贴板监听服务的运行状态</string>
</resources>

4. 修正前台服务启动时序(符合Android规范)

Android要求调用startForegroundService后5秒内必须调用startForeground,建议将初始化逻辑移至onStartCommand方法:

public class ClipboardListenerService extends Service {
    private ClipboardManager clipboardManager;
    private static final String CHANNEL_ID = "clipboard_service_channel";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("ClipboardService", "Service Created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("ClipboardService", "Service Started");
        createNotificationChannel();
        startForegroundService();
        clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        clipboardManager.addPrimaryClipChangedListener(this::onPrimaryClipChanged);
        return START_STICKY;
    }

    // 原有startForegroundService、createNotificationChannel方法不变
}

同时调整原生模块启动服务的代码:

@ReactMethod
public void startService() {
    Log.d("ClipboardService", "Starting Clipboard Listener Service");
    Intent serviceIntent = new Intent(getReactApplicationContext(), ClipboardListenerService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        getReactApplicationContext().startForegroundService(serviceIntent);
    } else {
        getReactApplicationContext().startService(serviceIntent);
    }
}

5. 验证通知渠道创建状态

在createNotificationChannel方法中添加日志,确认渠道是否创建成功:

private void createNotificationChannel() {
    Log.d("ClipboardService", "createNotificationChannel");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
            Log.d("ClipboardService", "Notification channel created: " + CHANNEL_ID);
        } else {
            Log.e("ClipboardService", "Failed to get NotificationManager");
        }
    }
}

查看Logcat日志,确认是否有Notification channel created的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:55:20