目前我正在编写一个 WiFi 感知应用程序。经过长时间的研究和实现,当我运行这个应用程序时,我的源代码没有产生任何异常。我现在的问题是,当我在我的第一个 Google Pixel 8 上发布会话时,我的第二个 Pixel 8 手机找不到该服务。为了避免硬件上的某些东西被破坏,我安装了来自谷歌的测试应用程序,它在这里工作了。
这是我的源代码(它仅显示发布和订阅者部分):
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);
}
...
我在这里做错了什么?
感谢您提前的帮助
您多次调用attach(),将其视为硬件初始化,只需要调用一次“您的应用程序应该仅调用attach()一次。如果您的应用程序多次调用attach(),则应用程序会收到不同的会话每个调用都有自己的命名空间。这在复杂的场景中可能很有用,但通常应该避免。” - 这是来自谷歌文档。
你可以做这样的事情
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");
}
此代码来自我正在测试的应用程序,可能有一些错误 还要确保尊重设备的硬件限制,例如建立连接时可以创建的最大接口
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
}