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

Android 8广播意图变更:WiFiP2P应用后台监听系统广播问题咨询

Fixing WiFi P2P Broadcast Listening Issues on Android 8.0+

Hey there, let's break down why your WiFi P2P broadcast receivers stopped working on Android Oreo and above, and how to fix it properly.

First, the core issue: Android 8.0 (API 26) introduced strict restrictions on manifest-declared broadcast receivers. Most system broadcasts—including the android.net.wifi.p2p.DISCOVERY_STATE_CHANGE and android.net.wifi.p2p.CONNECTION_STATE_CHANGE ones you're targeting—aren't on the system's whitelist. That means statically registering them in your AndroidManifest.xml won't work anymore once the app is swiped away from the recent apps list.

Here's the most reliable solution to keep listening to these broadcasts even when your app isn't in the foreground:


Solution 1: Foreground Service + Dynamic Broadcast Registration

A foreground service stays active even after the app is removed from recent apps (as long as the user doesn't force-stop it), and dynamically registered receivers aren't affected by the Oreo broadcast restrictions.

Step-by-Step Implementation:

  1. Create a Foreground Service Class
    This service will handle registering/unregistering the broadcast receiver and keep running in the background with a required notification (Oreo+ mandate):

    public class WiFiP2PBackgroundService extends Service {
        private WiFiP2PReceiver p2pReceiver;
    
        @Override
        public void onCreate() {
            super.onCreate();
            // Initialize and register the receiver
            p2pReceiver = new WiFiP2PReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
            filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
            // Add any other WiFi P2P actions you need to listen for
            registerReceiver(p2pReceiver, filter);
    
            // Start foreground service with a notification
            Notification foregroundNotification = buildForegroundNotification();
            startForeground(1, foregroundNotification);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            // Clean up: unregister the receiver
            if (p2pReceiver != null) {
                unregisterReceiver(p2pReceiver);
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        private Notification buildForegroundNotification() {
            // Create a notification channel for Oreo+
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = new NotificationChannel(
                    "wifi_p2p_channel",
                    "WiFi P2P Background Service",
                    NotificationManager.IMPORTANCE_LOW
                );
                NotificationManager manager = getSystemService(NotificationManager.class);
                manager.createNotificationChannel(channel);
            }
    
            // Build the notification (low priority to avoid annoying users)
            return new NotificationCompat.Builder(this, "wifi_p2p_channel")
                .setContentTitle("WiFi P2P Active")
                .setContentText("Listening for peer connections")
                .setSmallIcon(R.drawable.ic_wifi_icon)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();
        }
    }
    
  2. Implement the Broadcast Receiver
    This class will handle the actual WiFi P2P state changes:

    public class WiFiP2PReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) {
                // Handle discovery state changes
                int discoveryState = intent.getIntExtra(
                    WifiP2pManager.EXTRA_DISCOVERY_STATE,
                    WifiP2pManager.DISCOVERY_STOPPED
                );
                if (discoveryState == WifiP2pManager.DISCOVERY_STARTED) {
                    // Peer discovery started
                } else {
                    // Peer discovery stopped
                }
            } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
                // Handle connection state changes
                NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
                if (networkInfo != null && networkInfo.isConnected()) {
                    // Connected to a peer device
                } else {
                    // Disconnected from peer
                }
            }
        }
    }
    
  3. Update the Manifest
    Declare the service and required permissions:

    <!-- Required permissions for WiFi P2P -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Critical for WiFi P2P -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Android 9+ -->
    
    <application ...>
        <service
            android:name=".WiFiP2PBackgroundService"
            android:foregroundServiceType="connectedDevice" /> <!-- Optional but recommended -->
    </application>
    
  4. Start the Service When Your App Launches
    Trigger the foreground service from your main Activity's onCreate():

    Intent serviceIntent = new Intent(this, WiFiP2PBackgroundService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(serviceIntent);
    } else {
        startService(serviceIntent);
    }
    

Solution 2: JobScheduler (Less Ideal)

If you don't want a foreground notification, you could use JobScheduler to periodically check WiFi P2P state. However, this only works for non-real-time use cases—you won't get instant updates when broadcast events happen. It's not recommended if you need immediate responses to connection or discovery changes.


Important Notes

  • Location Permission: WiFi P2P requires ACCESS_FINE_LOCATION (not just coarse), and you'll need to request it dynamically on Android 6.0+. Without this, your receiver won't pick up any WiFi P2P events.
  • Battery Optimization: Some OEMs (like Samsung, Xiaomi) have aggressive battery optimization that can kill background services. Advise users to add your app to their battery optimization whitelist for reliable operation.
  • Notification Priority: Setting the foreground notification to IMPORTANCE_LOW keeps it unobtrusive—no sound or pop-up, just a small icon in the notification shade.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:50:55