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
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
}