0

I asked a similar question yesterday, but I think it was the wrong one. I have PCL that uses Xamarin to implement Bluetooth LE support on iOS & Android already, but now I must implement Windows BT support. It appears the only way to do so is through UWP, but after creating a UWP class library to do so, and referencing it through my PCL, the DeviceWatcher skips from Created to EnumerationComplete.

My guess is this is due to there not being bluetooth permission granted to the program -- as that has to be specified in the manifest, which isn't used in a class library. Do you guys happen to know if this is true? How can I grant permissions to my PCL and/or UWP class library? Below is some of the code I wrote in the UWP (pasted from my previous question.) Thank you in advance for any help you may offer.

Adapter.cs

private DeviceWatcher deviceWatcher;

public override IList<IDevice> ConnectedDevices => ConnectedDeviceRegistry.Values.ToList();

    /// <summary>
    /// Used to store all connected devices
    /// </summary>
    public Dictionary<string, IDevice> ConnectedDeviceRegistry { get; }


    /// <summary>
    /// Registry used to store device instances for pending operations : connect 
    /// </summary>
    public Dictionary<string, IDevice> DeviceOperationRegistry { get; }

    public Adapter(DeviceWatcher deviceWatcher)
    {
        Platform = PLATFORM.WINDOWS;
        DeviceOperationRegistry = new Dictionary<string, IDevice>();
        ConnectedDeviceRegistry = new Dictionary<string, IDevice>();

        this.deviceWatcher = deviceWatcher;
        /*DeviceInformation.CreateWatcher(
            aqsAllBluetoothLEDevices,
            requestedProperties,
            DeviceInformationKind.AssociationEndpoint);*/

        deviceWatcher.Added += DeviceWatcher_Added;
        deviceWatcher.Updated += DeviceWatcher_Updated;
        deviceWatcher.Removed += DeviceWatcher_Removed;
        deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
        deviceWatcher.Stopped += DeviceWatcher_Stopped;
    }

    protected override Task StartScanningForDevicesNativeAsync(Guid[] serviceUuids, bool allowDuplicatesKey, CancellationToken scanCancellationToken)
    {

        // clear out the list
        DiscoveredDevices.Clear();

        deviceWatcher.Start();

        return Task.FromResult(true);
    }

BleImplementation.cs

string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };

    // BT_Code: Example showing paired and non-paired in a single query.
    string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";

    DeviceWatcher deviceWatcher;

    protected override IAdapter CreateNativeAdapter()
    {
        deviceWatcher = DeviceInformation.CreateWatcher(
                aqsAllBluetoothLEDevices,
                requestedProperties,
                DeviceInformationKind.AssociationEndpoint);
        return new Adapter(deviceWatcher);
    }

Package.appxmanifest

    <?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
  <Prerequisites>
    <OSMinVersion></OSMinVersion>
    <OSMaxVersionTested></OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="" />
  </Resources>
  <Applications>
    <Application Id="" StartPage="">
      <VisualElements DisplayName="" Description=""
           Logo="" SmallLogo=""
           ForegroundText="" BackgroundColor="">
        <SplashScreen Image="" />
      </VisualElements>
    </Application>
  </Applications>

  <Identity Name="MyCompany.MySuite.MyApp"
            Version="1.0.0.0"
            Publisher="CN=MyCompany, O=MyCompany, L=MyCity, S=MyState, C=MyCountry"/>

  <Properties>
    <DisplayName>MyApp</DisplayName>
    <PublisherDisplayName>MyCompany</PublisherDisplayName>
    <Logo>images\icon.png</Logo>
  </Properties>

  <Capabilities>
    <Capability Name="internetClient" />
    <!--BT_Code: Always declare the bluetooth capability when using Bluetooth-->
    <DeviceCapability Name="bluetooth" />
  </Capabilities>
</Package>
slacker
  • 137
  • 9

2 Answers2

1

If the class library is in the UWP app package, it inherits the permissions of the UWP app.

Michael S. Scherotter
  • 10,715
  • 3
  • 34
  • 57
  • The UWP class library is used inside of the PCL library, which is part of the confusion. If I set BT permission for a UWP app that uses the PCL library, will that still be detected/usable by the UWP class library's function calls inside of the PCL library? – slacker Apr 30 '18 at 13:03
1

As you are using PCL be aware of this:

Portable Class Libraries (PCLs) now officially deprecated [16 August 2017]
If you’re sharing code between different .NET implementations today, you’re probably aware of Portable Class Libraries (PCLs). With the release of .NET Standard 2.0, we’re now officially deprecating PCLs and you should move your projects to .NET Standard.

Source: [https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-standard-2-0/]

This will probably not be related to your problem with the deviceWatcher. Also you don’t get exceptions, so you’re your code works as it should
Be aware that the enumeration of deviceWatcher comes from system level. Bluetooth devices have to be added first in Windows Settings , unlike USB-devices that are added automatically.
To find the device, try to filter less strict or omit the second parameter from DeviceInformation.CreateWatcher.

You can also try the FindAllAsync method first to check if your device can be found, but this is just a snapshot so you cannot monitor changes.

GrooverFromHolland
  • 971
  • 1
  • 11
  • 18