WiFiP2PManager,OnPeersAvailable,DeviceList.Count 零 - 总是

WiFiP2PManager, OnPeersAvailable, DeviceList.Count zero - always

我已经为 2 Samsung S8 phones 运行 Xamarin 测试应用程序苦苦挣扎了好几天,用最少的 WiFiP2PManager 代码来发现对等点。我浏览了社区论坛和文档 - 不可能这么难,一定有我遗漏的东西。

我检查了常见的错误:

仍然调用 OnPeersAvailable 并为 DeviceList 设置一个空集合。

调试中的调用顺序 window 结果是:

  1. WifiP2pManager.Initialize
  2. MainActivity.RegisterReceiver
  3. WifiP2pManager.DiscoverPeers
  4. WifiP2pManager.RequestPeers
  5. 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 回调中得到了同行!