WiFiP2PManager,OnPeersAvailable,DeviceList.Count 零 - 总是
WiFiP2PManager, OnPeersAvailable, DeviceList.Count zero - always
我已经为 2 Samsung S8 phones 运行 Xamarin 测试应用程序苦苦挣扎了好几天,用最少的 WiFiP2PManager 代码来发现对等点。我浏览了社区论坛和文档 - 不可能这么难,一定有我遗漏的东西。
我检查了常见的错误:
- 应用权限集(
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_WIFI_STATE, CHANGE_WIFI_STATE, CHANGE_NETWORK_STATE, INTERNET
)
- WiFi直连是否开启
- phone 是否都处于发现模式(或不是,结果相同)
仍然调用 OnPeersAvailable 并为 DeviceList 设置一个空集合。
调试中的调用顺序 window 结果是:
WifiP2pManager.Initialize
MainActivity.RegisterReceiver
WifiP2pManager.DiscoverPeers
WifiP2pManager.RequestPeers
OnPeersAvailable
(DeviceList.Count == 0
)
这是我的代码,也许你能看到一些东西?
using System;
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Net.Wifi.P2p;
using Android.Content;
using static Android.Net.Wifi.P2p.WifiP2pManager;
namespace WiFiDirectTest
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity, IChannelListener, IPeerListListener
{
private WifiP2pManager manager;
Channel channel;
MyBroadcastReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
System.Diagnostics.Debug.WriteLine($"Wifi - initialize");
manager = (WifiP2pManager)GetSystemService(WifiP2pService);
channel = manager.Initialize(this, MainLooper, null);
}
protected override void OnResume()
{
base.OnResume();
System.Diagnostics.Debug.WriteLine($"Wifi - register receiver");
receiver = new MyBroadcastReceiver(manager, channel, this);
receiver.Register(this);
System.Diagnostics.Debug.WriteLine($"Wifi - discover peers");
manager.DiscoverPeers(channel, new MyActionListner());
}
protected override void OnPause()
{
base.OnPause();
System.Diagnostics.Debug.WriteLine($"Wifi - unregister receiver");
receiver.Unregister(this);
receiver = null;
}
public void OnPeersAvailable(WifiP2pDeviceList peers)
{
var count = peers.DeviceList.Count;
System.Diagnostics.Debug.WriteLine($"Wifi - peers available: {count}");
}
public void OnChannelDisconnected()
{
System.Diagnostics.Debug.WriteLine("OnChannelDisconnected");
}
private class MyActionListner : Java.Lang.Object, WifiP2pManager.IActionListener
{
public MyActionListner()
{
}
public void OnFailure(WifiP2pFailureReason reason)
{
// breakpoint placed here, never reached.
}
public void OnSuccess()
{
}
}
}
public class MyBroadcastReceiver : BroadcastReceiver
{
WifiP2pManager manager;
WifiP2pManager.Channel channel;
MainActivity activity;
public MyBroadcastReceiver(WifiP2pManager manager, Channel channel, MainActivity activity)
{
this.manager = manager;
this.channel = channel;
this.activity = activity;
}
public void Register(MainActivity context)
{
var intentFilter = new IntentFilter();
intentFilter.AddAction(WifiP2pManager.WifiP2pStateChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pPeersChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pConnectionChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pThisDeviceChangedAction);
context.RegisterReceiver(this, intentFilter);
}
public void Unregister(MainActivity context)
{
context.UnregisterReceiver(this);
}
public override void OnReceive(Context context, Intent intent)
{
var action = intent.Action;
if (WifiP2pManager.WifiP2pStateChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pStateChangedAction");
}
else if (WifiP2pManager.WifiP2pPeersChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine($"Wifi - request peers");
manager.RequestPeers(channel, activity);
}
else if (WifiP2pManager.WifiP2pConnectionChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pConnectionChangedAction");
}
else if (WifiP2pManager.WifiP2pThisDeviceChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pThisDeviceChangedAction");
}
}
}
}
有什么想法吗?
-约翰
已解决!
原来我使用的 WiFiDirectSample 是用旧的 API 构建的,先于 v6.0 中的新运行时权限功能 (API 23)。当我在为 v9 (API 28) 构建的新应用程序中模仿 WiFiP2PManager 编排时。
因此我需要在运行时明确请求权限,尽管它们已列在 Android 清单中。 None 我阅读(一遍又一遍)的文档提到请求权限。
string[] permissions = {
Manifest.Permission.AccessFineLocation,
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessWifiState,
Manifest.Permission.ChangeWifiState,
Manifest.Permission.Internet
};
RequestPermissions(permissions, 0);
所以我刚刚将这段代码添加到我的 OnCreate()
中,现在我在我的 OnPeersAvailable 回调中得到了同行!
我已经为 2 Samsung S8 phones 运行 Xamarin 测试应用程序苦苦挣扎了好几天,用最少的 WiFiP2PManager 代码来发现对等点。我浏览了社区论坛和文档 - 不可能这么难,一定有我遗漏的东西。
我检查了常见的错误:
- 应用权限集(
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_WIFI_STATE, CHANGE_WIFI_STATE, CHANGE_NETWORK_STATE, INTERNET
) - WiFi直连是否开启
- phone 是否都处于发现模式(或不是,结果相同)
仍然调用 OnPeersAvailable 并为 DeviceList 设置一个空集合。
调试中的调用顺序 window 结果是:
WifiP2pManager.Initialize
MainActivity.RegisterReceiver
WifiP2pManager.DiscoverPeers
WifiP2pManager.RequestPeers
OnPeersAvailable
(DeviceList.Count == 0
)
这是我的代码,也许你能看到一些东西?
using System;
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Net.Wifi.P2p;
using Android.Content;
using static Android.Net.Wifi.P2p.WifiP2pManager;
namespace WiFiDirectTest
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity, IChannelListener, IPeerListListener
{
private WifiP2pManager manager;
Channel channel;
MyBroadcastReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
System.Diagnostics.Debug.WriteLine($"Wifi - initialize");
manager = (WifiP2pManager)GetSystemService(WifiP2pService);
channel = manager.Initialize(this, MainLooper, null);
}
protected override void OnResume()
{
base.OnResume();
System.Diagnostics.Debug.WriteLine($"Wifi - register receiver");
receiver = new MyBroadcastReceiver(manager, channel, this);
receiver.Register(this);
System.Diagnostics.Debug.WriteLine($"Wifi - discover peers");
manager.DiscoverPeers(channel, new MyActionListner());
}
protected override void OnPause()
{
base.OnPause();
System.Diagnostics.Debug.WriteLine($"Wifi - unregister receiver");
receiver.Unregister(this);
receiver = null;
}
public void OnPeersAvailable(WifiP2pDeviceList peers)
{
var count = peers.DeviceList.Count;
System.Diagnostics.Debug.WriteLine($"Wifi - peers available: {count}");
}
public void OnChannelDisconnected()
{
System.Diagnostics.Debug.WriteLine("OnChannelDisconnected");
}
private class MyActionListner : Java.Lang.Object, WifiP2pManager.IActionListener
{
public MyActionListner()
{
}
public void OnFailure(WifiP2pFailureReason reason)
{
// breakpoint placed here, never reached.
}
public void OnSuccess()
{
}
}
}
public class MyBroadcastReceiver : BroadcastReceiver
{
WifiP2pManager manager;
WifiP2pManager.Channel channel;
MainActivity activity;
public MyBroadcastReceiver(WifiP2pManager manager, Channel channel, MainActivity activity)
{
this.manager = manager;
this.channel = channel;
this.activity = activity;
}
public void Register(MainActivity context)
{
var intentFilter = new IntentFilter();
intentFilter.AddAction(WifiP2pManager.WifiP2pStateChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pPeersChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pConnectionChangedAction);
intentFilter.AddAction(WifiP2pManager.WifiP2pThisDeviceChangedAction);
context.RegisterReceiver(this, intentFilter);
}
public void Unregister(MainActivity context)
{
context.UnregisterReceiver(this);
}
public override void OnReceive(Context context, Intent intent)
{
var action = intent.Action;
if (WifiP2pManager.WifiP2pStateChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pStateChangedAction");
}
else if (WifiP2pManager.WifiP2pPeersChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine($"Wifi - request peers");
manager.RequestPeers(channel, activity);
}
else if (WifiP2pManager.WifiP2pConnectionChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pConnectionChangedAction");
}
else if (WifiP2pManager.WifiP2pThisDeviceChangedAction.Equals(action))
{
System.Diagnostics.Debug.WriteLine("WifiP2pThisDeviceChangedAction");
}
}
}
}
有什么想法吗?
-约翰
已解决!
原来我使用的 WiFiDirectSample 是用旧的 API 构建的,先于 v6.0 中的新运行时权限功能 (API 23)。当我在为 v9 (API 28) 构建的新应用程序中模仿 WiFiP2PManager 编排时。
因此我需要在运行时明确请求权限,尽管它们已列在 Android 清单中。 None 我阅读(一遍又一遍)的文档提到请求权限。
string[] permissions = {
Manifest.Permission.AccessFineLocation,
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessWifiState,
Manifest.Permission.ChangeWifiState,
Manifest.Permission.Internet
};
RequestPermissions(permissions, 0);
所以我刚刚将这段代码添加到我的 OnCreate()
中,现在我在我的 OnPeersAvailable 回调中得到了同行!