Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions src/Essentials/src/Permissions/Permissions.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ public static bool IsDeclaredInManifest(string permission)
return requestedPermissions?.Any(r => r.Equals(permission, StringComparison.OrdinalIgnoreCase)) ?? false;
}

private static bool HasFlagInManifest(string permission, RequestedPermission flag)
{
var context = Application.Context;
#pragma warning disable CS0618, CA1416, CA1422 // Deprecated in API 33: https://developer.android.com/reference/android/content/pm/PackageManager#getPackageInfo(java.lang.String,%20int)
var packageInfo = context.PackageManager.GetPackageInfo(context.PackageName, PackageInfoFlags.Permissions);
#pragma warning restore CS0618, CA1416, CA1422
var requestedPermissions = packageInfo?.RequestedPermissions;
var requestedPermissionsFlags = packageInfo?.RequestedPermissionsFlags;

for (int i=0; i<requestedPermissions.Count; i++)
{
if (requestedPermissions[i].Equals(permission, StringComparison.OrdinalIgnoreCase))
return (requestedPermissionsFlags[i] & (int)flag) != 0;
}

return false;
}

internal static void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
=> BasePlatformPermission.OnRequestPermissionsResult(requestCode, permissions, grantResults);

Expand Down Expand Up @@ -204,8 +222,7 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions
var permissions = new List<(string, bool)>();

// When targeting Android 11 or lower, AccessFineLocation is required for Bluetooth.
// For Android 12 and above, it is optional.
if (Application.Context.ApplicationInfo.TargetSdkVersion <= BuildVersionCodes.R || IsDeclaredInManifest(Manifest.Permission.AccessFineLocation))
if (Application.Context.ApplicationInfo.TargetSdkVersion <= BuildVersionCodes.R)
permissions.Add((Manifest.Permission.AccessFineLocation, true));

#if __ANDROID_31__
Expand All @@ -218,6 +235,9 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions
permissions.Add((Manifest.Permission.BluetoothConnect, true));
if (IsDeclaredInManifest(Manifest.Permission.BluetoothAdvertise))
permissions.Add((Manifest.Permission.BluetoothAdvertise, true));
// for Android 12 and above, AccessFineLocation is optional
if (IsDeclaredInManifest(Manifest.Permission.AccessFineLocation) && !HasFlagInManifest(Manifest.Permission.BluetoothScan, RequestedPermission.NeverForLocation))
permissions.Add((Manifest.Permission.AccessFineLocation, true));
}
#endif

Expand Down Expand Up @@ -365,8 +385,7 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions
{
var permissions = new List<(string, bool)>();
// When targeting Android 12 or lower, AccessFineLocation is required for several WiFi APIs.
// For Android 13 and above, it is optional.
if (Application.Context.ApplicationInfo.TargetSdkVersion < BuildVersionCodes.Tiramisu || IsDeclaredInManifest(Manifest.Permission.AccessFineLocation))
if (Application.Context.ApplicationInfo.TargetSdkVersion < BuildVersionCodes.Tiramisu)
permissions.Add((Manifest.Permission.AccessFineLocation, true));

#if __ANDROID_33__
Expand All @@ -375,6 +394,9 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions
// new runtime permission on Android 13
if (IsDeclaredInManifest(Manifest.Permission.NearbyWifiDevices))
permissions.Add((Manifest.Permission.NearbyWifiDevices, true));
// for Android 13 and above, AccessFineLocation is optional
if (IsDeclaredInManifest(Manifest.Permission.AccessFineLocation) && !HasFlagInManifest(Manifest.Permission.NearbyWifiDevices, RequestedPermission.NeverForLocation))
permissions.Add((Manifest.Permission.AccessFineLocation, true));
}
#endif

Expand Down