Comments (8)
Can you share your android manifest
from shiny.
This one is going to require some fiddling. Android 14 (13 a bit) changes the way the alarm permission works.
from shiny.
It's still an issue because I haven't fixed it. I'll get to this when I can, but it isn't a 30 second fix.
Fixes at this point are set for 4.0 which will be .NET8+ only
from shiny.
Previous versions of local notifications used shiny jobs which caused delays. V3 uses the alarm which needs a permission request. Try the extension off INotificationManager called RequestRequiredAccess(Notification notification)
from shiny.
I tried calling RequestRequiredAccess with a notification that had ScheduleDate set and I got NullReferenceException. I copied the extension method so I could run it locally.
var request = AccessRequestFlags.Notification;
if (notification.RepeatInterval != null)
request |= AccessRequestFlags.TimeSensitivity;
if (notification.ScheduleDate != null)
{
var channelId = notification.Channel ?? Channel.Default.Identifier;
var channel = notificationManager.GetChannel(channelId)!;
if (channel!.Importance == ChannelImportance.High)
request |= AccessRequestFlags.TimeSensitivity;
}
if (notification.Geofence != null)
request |= AccessRequestFlags.LocationAware;
return await this.notificationManager
.RequestAccess(request)
.ConfigureAwait(false);
The call to RequestAccess sees the following callback to MainActivity.OnRequestPermissionsResult
- requestCode = 4
- permissions = ["android.permission.POST_NOTIFICATIONS" "android.permission.SCHEDULE_EXACT_ALARM"]
- grantResults = [0 -1]
In one of my debug scenarios the channel had not been created. That throws a NullReferenceException when trying to read channel!.Importance
. I do however agree I should not be calling this without checking the channel has been created. I am just pointing out that the method should probably check too.
Once the code runs on a device with the Channel I get an AccessState of Restricted.If I remove the Channel then the AccessRequestFlags.TimeSensitivity flag is not set and I get AccessState of Available.
from shiny.
Hi, @munkii, @aritchie
I spend some time on investigation on Shiny 3.3.3 / dev branch of source code and MAUI but behavior should be really similar also for Xamarin and my conclusions are that there is couple things:
- in manifest probably should be max api 33 for SCHEDULE_EXACT_ALARM (now with Shiny.Templates is set to 32)
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="33" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
- for api 34 we should check permissions on different way like android documentation suggest + request user to open special access settings in case when permission was not granted yet (on api 34 default is not granted, unfortunately I don't have good idea how to implement it in library)
if (!this.Alarms.CanScheduleExactAlarms())
{
var intent = new Android.Content.Intent(Android.Provider.Settings.ActionRequestScheduleExactAlarm);
Application.Current.Context.StartActivity(intent);
}
- implementation of
Send(Notification notification)
inPlatforms/Android/NotificationManager.cs
code.
After scheduling notification I checked pending notifications and was always 0 on android:
var list = await notificationManager.GetPendingNotifications();
var pendingNotificationsCount = list.Count(); // result is 0, but I scheduled notifications in future :(
so I checked implementation of GetPendingNotifications()
which is:
public Task<IList<Notification>> GetPendingNotifications()
=> Task.FromResult((IList<Notification>)this.repository.GetList<AndroidNotification>().OfType<Notification>().ToList());
then if pending notifications are coming from repository
I checked place where potentially AndroidNotification should be stored in repository which is Send(Notification notification)
:
public async Task Send(Notification notification)
{
notification.AssertValid();
var android = notification.TryToNative<AndroidNotification>();
(...)
if (notification.ScheduleDate == null && notification.Geofence == null)
{
var native = builder.Build();
this.manager.NativeManager.Notify(notification.Id, native);
}
else
{
// ensure a channel is set
notification.Channel = channel!.Identifier;
this.repository.Set(notification);
if (notification.ScheduleDate != null)
this.manager.SetAlarm(notification);
}
}
then we can see that into repository we store generic Notification type instead of AndroidNotification so I stored it as well. I added after this.repository.Set(notification);
:
//re-asign android variable because we did manipulation from the moment when it was defined
android = notification.TryToNative<AndroidNotification>();
this.repository.Set(android);
and magic just happened - Scheduled Notifications started to works!
I'm not sure how it should be, maybe this.repository.Set(notification)
should be removed or maybe not or maybe something else should be changed in other files (I dont know how the implementation of notifications looks like in other files and if generic type need to be stored or no or maybe AndroidNotificationProcessor is looking for wrong stuff in repository).
However I hope it can help you to understand better problem and solve it in plugin :)
from shiny.
@anchorit3 while I appreciate the effort. Most of the work is done in the 4.0 branch. The issue isn't really with the "making it happen", but with how much of a mess the permissions have gotten now due to this additional permission. I'm working on that part, but the plugin will do all of the permissions properly in the future.
from shiny.
This is still an issue for us even when using 3.3.3.
I can ask the Android AlarmService if i can schedule exact alarms via the canScheduleExactAlarmsMethod
and that returns true.
AlarmManager alarmManager = (AlarmManager)GetSystemService(AlarmService);
Method canScheduleExactAlarmsMethod = alarmManager.Class.GetMethod("canScheduleExactAlarms");
bool canScheduleExactAlarms = (bool)canScheduleExactAlarmsMethod.Invoke(alarmManager);
However when it comes time to send the notification and I call Shiny I get AccessState.Restricted
var result = await this.remindersService.CheckNotificationsPermission(AccessRequestFlags.Notification | AccessRequestFlags.TimeSensitivity);
if (result != Shiny.AccessState.Available)
{
this.notificationPermissionRequestedAndDenied = true;
}
public async Task<Shiny.AccessState> CheckNotificationsPermission(AccessRequestFlags accessRequestFlags = AccessRequestFlags.Notification)
{
return await this.notificationManager.RequestAccess(accessRequestFlags);
}
I looked at the implmentation of NotifcationManager RequestAccess and had a look at starting the Android.Provider.Settings.ActionRequestScheduleExactAlarm
activity myself. Whilst it does start it gives me as the user now way to add us to the allowed set of apps.
Are these exact notifications best left alone for now. Should wait for 4.0? Will 4.0 be MAUI only?
from shiny.
Related Issues (20)
- [Feature Request]: Allow specifying user-agent header on NSURLSession Config HOT 1
- [Bug]: actionIdentifier not available in OnEntry delegate for Push Notifications HOT 1
- [Bug]: ServiceCollectionExtensions.AddBluetoothLE() throws "System.InvalidOperationException: This service descriptor is keyed. Your service provider may not support keyed services." HOT 2
- [Bug]: Shiny not working with Azure Notification Hub and FCM V1 HOT 3
- [Bug]: CharacteristicExtensions.GetAllCharacteristics returns only characteristics of the latest found service
- [Bug]: Setting up Shiny services for MAUI with .Net 8.0 support HOT 3
- [Bug]: await IBleManager.RequestAccessAsync() never returns a completed task the first time asking for permissions HOT 6
- [Bug]: Cannot use ScheduleDate and RepeatInterval at the same time HOT 1
- [Bug]: Connecting and disconnecting the connection does not work reliably HOT 3
- [Bug]: WriteCharacteristic is always timeout once "GATT is not connected" is thrown HOT 3
- [Bug]: HOT 1
- [Bug]: Shiny Push Notification - Delegate On Entry HOT 2
- [Bug]: PushManager never returns a value from the RequestAccess task. HOT 4
- [Feature Request]: Support Push notifications for iOS Simulator HOT 1
- [Bug]: BLE CharacteristicInfo Discovery HOT 6
- [Bug]: Notification doesn't appear when the app is running HOT 3
- [Bug]: System.ObjectDisposedException: ObjectDisposed_Generic ObjectDisposed_ObjectName_Name, Android.OS.PowerManager HOT 9
- [Bug]: Notification not clickable HOT 2
- [Bug]: The devices are not disconnected with 2 Bluetooth connections HOT 1
- [Feature Request]:HttpTransferStore not Found in MAUI HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from shiny.