xamarin / Essentials

Xamarin.Essentials is no longer supported. Migrate your apps to .NET MAUI, which includes Maui.Essentials.
https://aka.ms/xamarin-upgrade
Other
1.52k stars 505 forks source link

[Bug] Android 12 Crash - Blutooth Scan fails is not set - Android Android 12 (API level 31) #1943

Open pasha-o opened 2 years ago

pasha-o commented 2 years ago

Description

Currently when you switch to android 12 - and you are scanning for BT, the app crashes Need android.permission.BLUETOOTH_SCAN permission for android.content.AttributionSource@f9e3658f: GattService registerScanner

currently Essentials doesn't support checking for adding BT SCAN and Connect required for Androind 12 https://developer.android.com/guide/topics/connectivity/bluetooth/permissions

Steps to Reproduce

Expected Behavior

Actual Behavior

Basic Information

Screenshots

Reproduction Link

AndreaGobs commented 2 years ago

An easy solution is to extend Xamarin.Essentials Permission doc and later ask Bluetooth Scan permission on Android 12 devices.

Add this class on Android project:

internal class BluetoothConnectPermission : BasePlatformPermission
  {
      public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
      {
          (Android.Manifest.Permission.BluetoothScan, true),
          (Android.Manifest.Permission.BluetoothConnect, true)
      }.ToArray();
  }

Always on Android project check and request Bluetooth permission by means of

await Permissions.CheckStatusAsync<BluetoothConnectPermission>();
await Permissions.RequestAsync<BluetoothConnectPermission>();
pasha-o commented 2 years ago

thanks @AndreaGobs - will do

rogihee commented 2 years ago

What I did is create a DependencyService in my shared project with only Android having implementation like @AndreaGobs has. I added a check for the SDK version - 31 needs the new permissions, to scan in older devices you still need the location permissions.

[assembly: Dependency(typeof(PermissionsService))]
namespace MyProjectAndroid
{
    public class PermissionsService : IPermissionsService
    {
        public async Task<bool> RequestBlePermissions()
        {
                PermissionStatus status;
                // New SDK 31 API for bluetooth permissions
                if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.S)
                {
                    status = await Permissions.CheckStatusAsync<BluetoothPermission>();
                    bool showAlert = Permissions.ShouldShowRationale<BluetoothPermission>();
                    if (showAlert || status == PermissionStatus.Unknown || status == PermissionStatus.Denied)
                    {
                         // show an alert explaining why we need the permissions
                    }
                    status = await Permissions.RequestAsync<BluetoothPermission>();
                }
                else
                {
                    // < 31 API, use location permission to search and connect to devices
                    status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
                    bool showAlert = Permissions.ShouldShowRationale<BluetoothPermission>();
                    if (showAlert || status == PermissionStatus.Unknown || status == PermissionStatus.Denied)
                    {
                         // show an alert explaining why we need the permissions
                    }
                    status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>(); });
                }
                return true;
            }
        }
}

The iOS version does nothing:

[assembly: Dependency(typeof(PermissionsService))]
namespace MyProjectiOS
{
    public class PermissionsService : IPermissionsService
    {
        public Task<bool> RequestBlePermissions()
        {
            return Task.FromResult(true);
        }
    }
}

And shared:

public interface IPermissionsService
    {
        Task<bool> RequestBlePermissions();
    }
syedjamal commented 2 years ago

Hi @AndreaGobs @rogihee

I have tried to add the above code in my Xamarin Forms Android project but I get below error

Manifest.Permission doesn't contain a definition for BluetoothScan 
Manifest.Permission doesn't contain a definition for BluetoothConnect 

BuildVersionCodes doesn't contain a definition for 'S'

I have set Android project Target version as <uses-sdk android:minSdkVersion="26" android:targetSdkVersion="31" />

Could you please help to resolve the error

rogihee commented 2 years ago

@syedjamal these are the BLE permissions I have in my manifest:


    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- < 31 permissions for BLE -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
    <!-- new 31 permissions for BLE -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />```
syedjamal commented 2 years ago

@rogihee

I have added permission in theAndroid Manifest file as you mentioned. But I still get the errors. It is not resolved. I don't see any update for Xamarin Android in my visual studio for MAC 2019

Xamarin.Android
Version: 12.0.0.3 (Visual Studio Enterprise)
Commit: xamarin-android/d16-11/f0e3c2d
Android SDK: /Users/jamibr/Library/Android/sdk
    Supported Android versions:
        7.1 (API level 25)
        8.0 (API level 26)

SDK Tools Version: 26.1.1
SDK Platform Tools Version: 32.0.0
SDK Build Tools Version: 31.0.0

Is there anything I need to upgrde for support Android 12

penghouho commented 2 years ago

@syedjamal After I set the Droid project to have Target Framework with Android 12.0 (S), everything is okay now, before this I changed also the AndroidManifest.xml but it is not enough.

Right Click Droid Project -> Options -> Build -> General -> Target Framework -> Android 12.0 (S)

image
janusw commented 2 years ago

We also need the runtime handling of Android 12 Bluetooth permissions for xamarin-bluetooth-le, see xabre/xamarin-bluetooth-le#568.

andreasbrostencab commented 1 year ago

Why are this Bluetooth permissions not yet included in the Xamarin.Essentials project?

janusw commented 1 year ago

Why are this Bluetooth permissions not yet included in the Xamarin.Essentials project?

Probably because the development of Xamarin.Essentials has slowed down significantly since the advent of Maui (which btw also does not have this feature yet, but I have just opened an issue there).

andreasbrostencab commented 1 year ago

Why are this Bluetooth permissions not yet included in the Xamarin.Essentials project?

Probably because the development of Xamarin.Essentials has slowed down significantly since the advent of Maui (which btw also does not have this feature yet, but I have just opened an issue there).

True, but as long as Maui isn't mature enought to move larger apps into, I see a huge need from Microsoft to keep Xamarin.Essentials up to date with changes like this.

janusw commented 1 year ago

True, but as long as Maui isn't mature enought to move larger apps into, I see a huge need from Microsoft to keep Xamarin.Essentials up to date with changes like this.

I fully agree, but still I wouldn't bet on any new permissions coming to Xamarin at this point (unless you contribute it yourself). Also, with .NET 7, it seems like Maui is finally getting a bit closer to the point where it's stable enough for larger apps (but that surely depends on the use case).

janseris commented 1 year ago

Why are this Bluetooth permissions not yet included in the Xamarin.Essentials project?

Probably because the development of Xamarin.Essentials has slowed down significantly since the advent of Maui (which btw also does not have this feature yet, but I have just opened an issue there).

True, but as long as Maui isn't mature enought to move larger apps into, I see a huge need from Microsoft to keep Xamarin.Essentials up to date with changes like this.

The Xamarin dev team basically moved to MAUI

enantiomer2000 commented 1 year ago

I have a bunch of hardware which is still not compatible with Maui so stuck with Xamarin Forms atm...

pasha-o commented 1 year ago

I thought they were going to support the Xamarin platform and essentials until Maui is fully ready for enterprise projects. regardless, I reported this issue in 2021 and it should have been incorporated into the essentials by now. very strange @janseris

BConnectSoftware commented 1 year ago

Been dealing for days on trying to just scan for beacons with android. Have yet to be successful and I ran into this issue. I spend more time trying to configure maui and trying to get it to work than actually coding....

janusw commented 1 year ago

I thought they were going to support the Xamarin platform and essentials until Maui is fully ready for enterprise projects.

Xamarin will be officially supported until May 2024, but it's basically in "maintenance mode", so I guess you can expect bugfixes and minor updates, but no major new features.

janusw commented 1 year ago

Been dealing for days on trying to just scan for beacons with android. Have yet to be successful and I ran into this issue. I spend more time trying to configure maui and trying to get it to work than actually coding....

Check out dotnet-bluetooth-le. It has sample clients for Xamarin and MAUI and both can handle Android 12 permissions well (via some custom extensions). With .NET8, MAUI will support the Android 12 Bluetooth permissions out of the box, but I'm pretty sure this will not be coming to Xamarin any more. If you still have a Xamarin app that requires this, follow the technique used in the sample app above.

janseris commented 1 year ago

Been dealing for days on trying to just scan for beacons with android. Have yet to be successful and I ran into this issue. I spend more time trying to configure maui and trying to get it to work than actually coding....

Check out dotnet-bluetooth-le. It has sample clients for Xamarin and MAUI and both can handle Android 12 permissions well (via some custom extensions). With .NET8, MAUI will support the Android 12 Bluetooth permissions out of the box, but I'm pretty sure this will not be coming to Xamarin any more. If you still have a Xamarin app that requires this, follow the technique used in the sample app above.

Yeah this works perfectly and I've created successfully a proof of concept bluetooth beacon app thanks to your repository.

BConnectSoftware commented 1 year ago

We made the go/no-go decision to drop maui and go native. Sure its two code bases, but the feature set in maui is just not there for what we needed for BLE. And the promise for .NET8, with maui's track record, I would not hold my breath that it works 100%. Its unfortunate but honestly we are back up to speed and CODING and not configuring...

janusw commented 1 year ago

We made the go/no-go decision to drop maui and go native. Sure its two code bases, but the feature set in maui is just not there for what we needed for BLE.

Hm, I can see various good reasons for dropping MAUI, but honestly lack of BLE support is not one of them, since this is covered quite well by community projects like dotnet-bluetooth-le.

BConnectSoftware commented 1 year ago

Hm, I can see various good reasons for dropping MAUI, but honestly lack of BLE support is not one of them, since this is covered quite well by community projects like dotnet-bluetooth-le.

You realize that sometimes for legal and security reasons, open source is not an option for certain projects? We did look at dotnet-bluetooth-le, but could not get it to successfully monitor/range beacons with android.