NotificationListenerService alternative in Xamarin - c#

Is there any way to listen to notificstions(read their text) shown in notificstion bar in Xamarin?
I know that in AndroidStudio, we can use NotificationListenerService, but I can not find any Xamarin alternative.
Real example:
I recieve a Whatsapp message and get notified, I want my app to check if the message was sent by Emily- if so, do something...
Thanks for help and replies

Xamarin.Android has a framework wrapper for Android.Service.Notification.NotificationListenerService.
[Register ("android/service/notification/NotificationListenerService", DoNotGenerateAcw = true, ApiSince = 18)]
public abstract class NotificationListenerService : Service
{
~~~
}
Just as in Java, it is an abstract class that you need to implement.
public class MyNotificationListenerService : NotificationListenerService
{
public override void OnCreate()
{
base.OnCreate();
}
public override void OnNotificationPosted(StatusBarNotification sbn)
{
~~~~
}
public override void OnNotificationRemoved(StatusBarNotification sbn)
{
~~~~
}
}

Related

Using OnBackPressedCallback in Xamarin

I'm trying to implement something similar to OnBackPressed() in a fragment in Xamarin, but the only solutions I found so far are for Java.
Here is one example in Java that does what I want:
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
Toast.makeText(mContext, "back pressed", Toast.LENGTH_SHORT).show();
// And when you want to go back based on your condition
if (yourCondition) {
this.setEnabled(false);
requireActivity().onBackPressed();
}
}
};
How could I go about converting that piece of code into C#?
UPDATE
Create an interface for handling your event:
public interface IOnBackPressedHandler
{
bool OnBackPressed();
}
In your activity(below is just an example) setup your interface callback as follows
public class FragActivity : AppCompatActivity
{
public override void OnBackPressed()
{
Fragment fragment = SupportFragmentManager.FindFragmentById(Resource.Id.yourFragmentId);
if (!(fragment is IOnBackPressedHandler) || !((IOnBackPressedHandler)fragment).OnBackPressed()) {
base.OnBackPressed();
}
}
}
Finally, your fragment would look something like that :
public class SomeFragment : Fragment, IOnBackPressedHandler
{
public bool OnBackPressed()
{
//Callbacks will be received here.
return true;
}
}
Hope this makes it easier to understand. You can also make this method a part of your base Fragment mark it as virtual and then have all classes inherit this to keep overriding it...
OG answer:
Well you cannot have anonymous classes in C#, So just create a Class that inherits this Abstract class and you're good:
public class HandleOnBackPressedCallback : OnBackPressedCallback
{
public HandleOnBackPressedCallback(bool enabled) : base(enabled)
{
}
public override void HandleOnBackPressed()
{
Toast.MakeText(context, "back pressed", ToastLength.Long).Show();
// And when you want to go back based on your condition
if (yourCondition)
{
this.setEnabled(false);
requireActivity().onBackPressed();
}
}
}
Good luck!!

Refactoring C# event based with SQL Server operations

I am not sure how to decide about how to refactor some production code. This code works as select records top 1 from db and decided to column containing value under the below.
switch(column_value):
case send_email:
send_email.DoIt();
case enable_somexx:
enable_somexx.DoIt();
case response_email:
response_email.DoIt();
Showing the below examples, there are created classes for every events (records) including a DoIt() method(SendMail, DecideMail, ResponseMail, MailXXX, enable_somexx). The classes include 3 subfolders actions named action, decision, response (actually these classes irrelevant which other because code select top 1 record)
I'm thinking of refactoring this code logic like this:
Create base class named Behaviour
other 3 main classes will inherit from this base class
Code:
public abstract Behaviour
{
public virtual void DoIt(string type) {
}
}
--Also another classes Decision, Response will inherit from Behaviour.
public class Action : Behaviour
{
override void DoIt(string type) {
}
}
public class Email : Action
{
override void DoIt(string type)
{
if(type == SEND)
call_sendmethod
else if(xxx_operation_about_mail)
call_xxx_operation_about_mail
}
}
But I cannot handle (actually I don't like my solution because I don't want to create same class every operations like EmailAction, EmailResponse, EmailDecision or another operations)
If you make this code block refactoring, how would you do it?
Thank you.
Using your idea of refactoring ... this is how I would code it:
Here is an outline:
Create an abstract class for Behavior
Create an action class which inherits Behavior
Then you can code like this to trigger desire "action".
Notice how I override the "Send" behavior to customize it to "special sent".
Here is the fiddle: https://dotnetfiddle.net/m3tjWl
Blockquote
public class Program : Action
{
public static void Main()
{
Console.WriteLine("Hello World");
var command = Console.ReadLine();
//trigger send from Action class
Action x = new Action();
x.DoIt(command);
//trigger send from behavior class
//the lines below are added to show how you can still access the parent behavior, remove or use where appropriate
Behaviour y = x;
y.Send();
}
}
public abstract class Behaviour
{
public virtual void Send()
{
Console.WriteLine("sent");
}
public virtual void EnableX()
{
Console.WriteLine("enabled");
}
public virtual void Reply()
{
Console.WriteLine("replied");
}
public abstract void DoIt(string type);
}
public class Action : Behaviour
{
public override void DoIt(string type)
{
if(type.ToUpper() == "SEND")
this.Send();
else if (type.ToUpper() == "ENABLEX")
this.EnableX();
else if (type.ToUpper() == "REPLY")
this.Reply();
else
Console.WriteLine("Unknown Command");
}
new public void Send()
{
Console.WriteLine("Special Sent");
}
}

Xamarin ObjC binding callback not called

I have a Xamarin-Objective C binding project (see here: https://github.com/bbhsu2/XamarinAdMarvelBinding). Fundamentally, it works and I can load clickable ads.
So I implement the AdMarvelDelegate interface on my ViewController class, but important implemented methods are not getting called:
public class CategoryViewController : UITableViewController, IAdMarvelDelegate
{
/*Initializing stuff*/
public void GetAdSucceeded() //not called
{
Console.WriteLine("succeeded!");
}
public void GetAdFailed() //not called
{
Console.WriteLine("failed!");
AppDelegate.Shared.AddAdBanner();
}
}
Does anyone have any suggestions on why GetAdSucceeded and GetAdFailed are not called? In the binding project I have:
[Export("getAdSucceeded")]
void GetAdSucceeded();
[Export("getAdFailed")]
void GetAdFailed();
which I believe are correct
If the corresponding members in AdMarvelDelegate are optional (i.e. they don't have the [Abstract] attribute in the binding), you'll need the [Export] attribute on those methods:
public class CategoryViewController : UITableViewController, IAdMarvelDelegate
{
[Export ("getAdSucceeded")]
public void GetAdSucceeded()
{
Console.WriteLine("succeeded!");
}
[Export("getAdFailed")]
public void GetAdFailed()
{
Console.WriteLine("failed!");
AppDelegate.Shared.AddAdBanner();
}
}

Xamarin.Forms implement AndHud and BTProgressHud

Can anyone point me to a Xamarin.forms sample that utilises AndHud for Android and BTProgressHud for iOS (or anything similar)?
I know there is the ACR-Xamarin-Forms example here https://github.com/aritchie/acr-xamarin-forms, but it is way too complicated and completely over my head.
Surely there is a more simple easy to understand implementation, but if not some sort of guidance on how to get started on implementing it (for a C# and Xamarin newbie)
Thanks in advance
This is how I've done it for iOS. All you should need to do for Android is create an implementation of IHud that using AndHud instead of BTProgressHud.
First, create an interface in the shared project
public interface IHud
{
void Show();
void Show(string message);
void Dismiss();
}
Next, in the iOS project, create an implementation of IHud using BTProgressHud component:
[assembly: Dependency(typeof(Hud))]
namespace project.iOS
{
public class Hud : IHud
{
public Hud ()
{
}
public void Show() {
BTProgressHUD.Show ();
}
public void Show(string message) {
BTProgressHUD.Show (message);
}
public void Dismiss() {
BTProgressHUD.Dismiss ();
}
}
}
Finally, to utilize this from Forms code, just do
var hud = DependencyService.Get<IHud> ();
hud.Show ("Loading Vehicles");
// tasks...
hud.Dismiss ();
My answer, which is quite similar to #jason's can be found here:
Loading Icon for layout screen Xamarin android

Caliburn.Micro EventAggregator

Apologise if this a really stupid question but I'm just getting started with caliburn.micro and I'm struggling with getting the eventAggregator, nothing seems to be subscribing...
I'm not sure whether the problem is with the view model or the bootstrapper. Here is the viewmodel:
class MainWindowViewModel : Screen
{
private readonly IEventAggregator _eventAggregator;
public MainWindowViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}
public void SayHello()
{
_eventAggregator.Publish("Hello World!");
}
public void Handle(string message)
{
MessageBox.Show(message);
}
}
Bootstrapper:
class AppBootstrapper : Bootstrapper<MainWindowViewModel>
{
public static readonly Container ContainerInstance = new Container();
protected override void Configure()
{
ContainerInstance.Register<IWindowManager, WindowManager>();
ContainerInstance.RegisterSingle<IEventAggregator,EventAggregator>();
ContainerInstance.Register<MainWindowViewModel, MainWindowViewModel>();
ContainerInstance.Verify();
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return ContainerInstance.GetAllInstances(service);
}
protected override object GetInstance(System.Type service, string key)
{
return ContainerInstance.GetInstance(service);
}
protected override void BuildUp(object instance)
{
ContainerInstance.InjectProperties(instance);
}
}
Any ideas what I'm missing, I feel I must not be linking somewhere...
I am using SimpleInjector as the IOC Container
EDIT:
It seems like a very simple case of I didn't know what I was doing. RTFM.
Implementing IHandle does work. It seems to get called twice the first time the type is handled though. I'll do some investigating as to why.
It sounds like you've already arrived at a solution of sorts.
I believe it should work provided you implement an IHandle<T> interface using a type compatible with the even you're publishing. E.g:
class MainWindowViewModel : Screen, IHandle<string>
{
//... Your Code
public void Handle(string myEventstring)
{
// Do Something.
}
}
If at all helpful, when I use the EventAggregator, I tend to create a static EventAggregator instance (from a small helper class) which I use in any ViewModels that require it - it may help in cases where you've actually initialised the EventAggregator multiple times by accident (might be the cause of your double event).
I also sometimes create small helper classes to wrap up event information. E.g:
public sealed class DownloadFinishedEvent
{
public readonly string EventText = "Download Completed";
// Additional Download Info Here.
public override string ToString()
{
return this.EventText;
}
}
The caliburn micro doc example shows, that the subscriber has to implement the IHandle interface. I think that's the problem.

Categories