Search code examples
javaandroidwifi

WiFi Aware - Discovery of Session doesn't work


currently i am writing a WiFi-Aware app. After long research and implementation my source code is not producing any Exceptions, when i am running this app. My Problem is now, when i am publishing on my first google pixel 8 a session, that my second pixel 8 phone doesn't find the service. To avoid that something on the hardware is broken, i installed the test-app from google and here it works.

Here my source code now (it shows only the Publish and Subscriber-part):

public void publish(View view) {


    boolean hasWifiAware = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);

    logger.log(Level.INFO, "This device has WiFi-Aware: " + hasWifiAware);

    WifiAwareManager wifiAwareManager = (WifiAwareManager) getSystemService(Context.WIFI_AWARE_SERVICE);
    Handler handler = new Handler();

    wifiAwareManager.attach(new PublishAttachCallback(), handler);
}

public void subscribe(View view) {


    boolean hasWifiAware = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);


    logger.log(Level.INFO, "This device has WiFi-Aware: " + hasWifiAware);


    WifiAwareManager wifiAwareManager = (WifiAwareManager) getSystemService(Context.WIFI_AWARE_SERVICE);
    Handler handler = new Handler();

    wifiAwareManager.attach(new SubscribeAttachCallback(), handler);
}



class PublishAttachCallback extends AttachCallback {
    private Logger logger = Logger.getLogger("MainActivity");

    @Override
    public void onAttachFailed() {
        logger.log(Level.ERROR, "Publish onAttacheFailed!");
    }

    @Override
    public void onAttached(WifiAwareSession session) {
        Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show();


        MainActivity.this.mAwareSession = session;
        PublishConfig config = new PublishConfig.Builder()
                .setServiceName(AWARE_SERVICE_NAME)
                .build();

        if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    REQUEST_CODE);
        }
        if(ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.NEARBY_WIFI_DEVICES},
                    REQUEST_CODE);
        }
        MainActivity.this.mAwareSession.publish(config, new DiscoverySessionCallback() {
            @Override
            public void onPublishStarted(PublishDiscoverySession session) {
                logger.log(Level.INFO, "Publish started!");
                Toast.makeText(MainActivity.this, "onPublishStarted", Toast.LENGTH_SHORT).show();
                

            }

            @Override
            public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
                logger.log(Level.INFO, "Message received");
                Toast.makeText(MainActivity.this, "onMessageReceived : " + message.toString(), Toast.LENGTH_SHORT).show();
            }


        }, null);
    }
}

class SubscribeAttachCallback extends AttachCallback {
    @Override
    public void onAttachFailed() {
        logger.log(Level.ERROR, "Subscribe onAttacheFailed!");
    }

    @Override
    public void onAttached(WifiAwareSession session) {
        Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show();


        MainActivity.this.mAwareSession = session;

        SubscribeConfig config = new SubscribeConfig.Builder()
                .setServiceName(AWARE_SERVICE_NAME)
                .build();

        if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    REQUEST_CODE);
        }
        if(ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.NEARBY_WIFI_DEVICES},
                    REQUEST_CODE);
        }

        MainActivity.this.mAwareSession.subscribe(config, new DiscoverySessionCallback() {
            private PeerHandle mPeerHandle = null;

            @Override
            public void onServiceDiscovered(PeerHandle peerHandle,
                                            byte[] serviceSpecificInfo, List<byte[]> matchFilter){
                Toast.makeText(MainActivity.this, "onServiceDiscovered!", Toast.LENGTH_SHORT).show();

                //here always null
                mPeerHandle = peerHandle;
                if(mPeerHandle == null) {
                    logger.log(Level.ERROR, "mPeerHandle is null!");
                }
            }
            @Override
            public void onSubscribeStarted(SubscribeDiscoverySession session1) {
                Toast.makeText(MainActivity.this, "onSubscribeStarted", Toast.LENGTH_SHORT).show();
                if (mPeerHandle != null) {
                    int messageId = 1;
                    session1.sendMessage(mPeerHandle, messageId, "Test Message".getBytes());
                } else {
                    Toast.makeText(MainActivity.this, "mPeerHandle is null in onSubscribeStarted!", Toast.LENGTH_SHORT).show();

                }
            }
            @Override
            public void onMessageSendSucceeded(int messageId) {
                logger.log(Level.INFO, "Message send succeeded!");
                Toast.makeText(MainActivity.this, "onMessageSendSucceeded for " + messageId, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onMessageSendFailed(int messageId) {
                logger.log(Level.ERROR, "Message send failed!");
                Toast.makeText(MainActivity.this, "onMessageSendFailed for " + messageId, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
                logger.log(Level.INFO, "Message received!");
            }

        }, null);


    }

...

What i am doing wrong here?

Thank you for your help in advance


Solution

  • you are calling attach() multiple times, think it as the hardware init, only need to called once "Your app should call attach() only once. If your app calls attach() multiple times, the app receives a different session for each call, each with its own namespace. This could be useful in complex scenarios, but should generally be avoided." - this is from google documents.

    you can do something like this

    WifiAwareManager wifiAwareManager = (WifiAwareManager) context.getSystemService(Context.WIFI_AWARE_SERVICE);
    
        if (wifiAwareManager.isAvailable()) {
    
            wifiAwareManager.attach(new AttachCallback(){
    
                @Override
                public void onAttached(WifiAwareSession session) {
                    super.onAttached(session);
    
                     //Publisher
    
                    PublishConfig publishConfig = new PublishConfig.Builder()
                            .setServiceName("test")
                            .build();
    
                    session.publish(publishConfig, new DiscoverySessionCallback() {
                        private PublishDiscoverySession publisherSession;
    
                        @Override
                        public void onPublishStarted(@NonNull PublishDiscoverySession session) {
                            super.onPublishStarted(session);
                            this.publisherSession = session;
                            Log.d("Publisher", "Publisher started");
                        
    
                            NetworkSpecifier networkSpecifier = new WifiAwareNetworkSpecifier.Builder(session)
                                    .setPskPassphrase("somePassword")
                                    .setPort(port)
                                    .build();
                            NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
                                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
                                    .setNetworkSpecifier(networkSpecifier)
                                    .build();
    
                            ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
                                @Override
                                public void onAvailable(@NonNull Network network) {
                                    super.onAvailable(network);
                                    Log.d("Pub Network", "Network available: " + network.toString());
                                }
    
                                @Override
                                public void onLost(@NonNull Network network) {
                                    super.onLost(network);
                                    Log.d("Pub Network", "Network lost: " + network.toString());
                                }
    
                                @Override
                                public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
                                    super.onCapabilitiesChanged(network, networkCapabilities);
                                    Log.d("Pub Network", "Network capabilities changed for: " + network.toString());
                                    // You can also log specific capabilities if needed
                                    Log.d("Pub Network", "New capabilities: " + networkCapabilities.toString());
                                }
    
                                @Override
                                public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {
                                    super.onLinkPropertiesChanged(network, linkProperties);
                                    Log.d("Pub Network", "Link properties changed for: " + network.toString());
                                    // You can also log specific properties if needed
                                    Log.d("Pub Network", "New properties: " + linkProperties.toString());
                                }
                            };
    
                            connectivityManager.requestNetwork(myNetworkRequest, callback);
                        }
    
    
    
                        @Override
                        public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
                            super.onMessageReceived(peerHandle, message);
                        }
                    }, null);
    
                     // Subscriber
    
                    SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
                            .setServiceName("test")
                            .build();
    
                    session.subscribe(subscribeConfig, new DiscoverySessionCallback() {
                        private SubscribeDiscoverySession subscriberSession;
    
                        @Override
                        public void onSubscribeStarted(@NonNull SubscribeDiscoverySession session) {
                            super.onSubscribeStarted(session);
                            this.subscriberSession = session;
                            Log.d("Subscriber", "Subscriber started");
    
                        
                        }
    
                        @Override
                        public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
                            super.onServiceDiscovered(peerHandle, serviceSpecificInfo, matchFilter);
                            Log.d("Subscriber", "Service Discovered - Peer: " + peerHandle.hashCode());
    
                            NetworkSpecifier networkSpecifier = new WifiAwareNetworkSpecifier.Builder(subscriberSession, peerHandle)
                                    .setPskPassphrase("somePassword")
                                    .build();
                            NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
                                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
                                    .setNetworkSpecifier(networkSpecifier)
                                    .build();
    
                            ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
                                @Override
                                public void onAvailable(@NonNull Network network) {
                                    super.onAvailable(network);
                                    Log.d("Sub Network", "Network available: " + network.toString());
                                }
    
                                @Override
                                public void onLost(@NonNull Network network) {
                                    super.onLost(network);
                                    Log.d("Sub Network", "Network lost: " + network.toString());
                                }
    
                                @Override
                                public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
                                    super.onCapabilitiesChanged(network, networkCapabilities);
                                    Log.d("Sub Network", "Network capabilities changed for: " + network.toString());
                                    // You can also log specific capabilities if needed
                                    Log.d("Sub Network", "New capabilities: " + networkCapabilities.toString());
    
    
                                }
    
                                @Override
                                public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {
                                    super.onLinkPropertiesChanged(network, linkProperties);
                                    Log.d("Sub Network", "Link properties changed for: " + network.toString());
                                    // You can also log specific properties if needed
                                    Log.d("Sub Network", "New properties: " + linkProperties.toString());
                                }
                            };
    
                            connectivityManager.requestNetwork(myNetworkRequest, callback);
    
                        }
    
                        @Override
                        public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
                            super.onMessageReceived(peerHandle, message);
                        }
                    }, null);
    
                }
    
                @Override
                public void onAttachFailed() {
                    super.onAttachFailed();
                }
    
                @Override
                public void onAwareSessionTerminated() {
                    super.onAwareSessionTerminated();
                }
            },null);
    
        } else {
            Log.d(TAG,"WifiAwareManager not available");
        }
    

    This code is from an app i'm testing, can have some error Also make sure you respect the hardware contrains from the device like the max interfaces you can create when establishing a connection

    wifiAwareManager = (WifiAwareManager) context.getSystemService(Context.WIFI_AWARE_SERVICE);
    
        // Check if Wi-Fi Aware is supported on this device
        if (wifiAwareManager.isAvailable()) {
            wifiAwareManagerStatus = true;
    
            Characteristics characteristics = wifiAwareManager.getCharacteristics();
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    
                assert characteristics != null;
                Log.d(TAG,String.format(
                        "isAwarePairingSupported() - %b \n" +
                                "isInstantCommunicationModeSupported() - %b \n" +
                                "isSetChannelOnDataPathSupported() - %b \n" +
                                "getNumberOfSupportedDataInterfaces - %d \n" +
                                "getNumberOfSupportedDataPaths - %d \n",
                        characteristics.isAwarePairingSupported(),
                        characteristics.isInstantCommunicationModeSupported(),
                        wifiAwareManager.isSetChannelOnDataPathSupported(),
                        characteristics.getNumberOfSupportedDataInterfaces(),
                        characteristics.getNumberOfSupportedDataPaths()
                ));
            }
            Log.d(TAG, String.format("getAvailableDataPathsCount() = %d \n" +
                            "getAvailableSubscribeSessionsCount() = %d \n" +
                            "getAvailablePublishSessionsCount() = %d\n",
                    wifiAwareManager.getAvailableAwareResources().getAvailableDataPathsCount(),
                    wifiAwareManager.getAvailableAwareResources().getAvailableSubscribeSessionsCount(),
                    wifiAwareManager.getAvailableAwareResources().getAvailablePublishSessionsCount()));
        } else {
            wifiAwareManagerStatus = false;
            Log.d("wifiAwareManager", "not available");
            // Wi-Fi Aware is not available on this device
        }