I have problem with broadcast receiver in xamarin.android. Can't get it to work.
I have notification in my app working and I want to change some things in my app after I get notification (e.g. Toast message or change icon of a button) But it doesn't work. I don't know what am I doing wrong and I can't find solution because all the topics are Java related. I need something, event or broadcastreceiver to fire when user gets notification and then I want to do some stuff in my MainActivity.
So, this is the code.
BroadcastReceiver class:
[BroadcastReceiver(Enabled = true, Exported = false)]
public class MyMessageReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
bool messageReceived = intent.GetBooleanExtra("messageReceived", false);
}
}
OnMessageReceived method:
{
base.OnMessageReceived(message);
SendNotification(message.GetNotification().Body);
LocalBroadcastManager broadcaster = LocalBroadcastManager.GetInstance(this);
Intent intent = new Intent("message");
intent.PutExtra("messageReceived", true);
broadcaster.SendBroadcast(intent);
}
And OnResume and OnPause methods:
protected override void OnResume()
{
base.OnResume();
LocalBroadcastManager.GetInstance(this).RegisterReceiver(myReceiver, new IntentFilter("message"));
RegisterReceiver(myReceiver, new IntentFilter("message"));
}
protected override void OnPause()
{
base.OnPause();
LocalBroadcastManager.GetInstance(this).UnregisterReceiver(myReceiver);
}
I don't know how to receive that info for example in my OnCreate method in MainActivity? I tried with
messageReceived = Intent.GetBooleanExtra("messageReceived", false);
if (messageReceived)
{
Toast.MakeText(this, "new notification", ToastLength.Long).Show();
}
But that doesn't work, messageReceived is null.
I know it is a bit too late but better late than never :
After analysing the firebase messaging I have done a suitable workaround for this purpose :
When your application is in the background the handle intent method is called by default on receiving push notification :
public override void HandleIntent(Intent p0)
{
base.HandleIntent(intent);
//Your code to know that you received a notification (backgrounnd)
// Use shared preference for this
}
Don't know how to use shared preferences check this.
For more information on how handle intent works check my answer out here.
When the application is in the foreground you can simply use on message received method as such :
public override void OnMessageReceived(Context context, Intent intent)
{
//Your code to know that you received a notification (backgrounnd)
// Use shared preference for this
}
Then, wherever you need to use this you can get a flag or count or whatever using shared preferences.
In case of any queries revert!
Related
I've been searching for a way to send a local message within my app and found a tutorial from the Xamarin website on Broadcast Receivers here, more specifically at the bottom of the web page concerning LocalBroadcastManager. I followed the tutorial and read the page a few times but my BroadcastReceiver class still isn't receiving anything when I send a message. I've hit a lot of the questions concerning LocalBroadcastManager for java, but can't seem to figure out what's missing for C#.
This is the code that's triggering a sent message:
Intent intent = new Intent("dirty");
intent.PutExtra("dirtyAppCount", dirtyAppCount);
LocalBroadcastManager.GetInstance(Context).SendBroadcast(intent);
Here's where I'm registering my receiver in OnResume():
_dirtyMessageReceiver = new DirtyBroadcastReceiver();
RegisterReceiver(_dirtyMessageReceiver, new IntentFilter("dirty"));
Unregistering receiver in OnPause():
UnregisterReceiver(_dirtyMessageReceiver);
And here's my receiver class:
[BroadcastReceiver(Enabled = true, Exported = false)]
public class DirtyBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
int dirtyAppCount = intent.GetIntExtra("dirtyAppCount", 0);
OnMessageReceived?.Invoke(this, new MessageArgs(dirtyAppCount));
}
}
There are two issues with this code. First, you should use be registering the Receiver with the LocalBroadcastManager:
_dirtyMessageReceiver = new DirtyBroadcastReceiver();
RegisterReceiver(_dirtyMessageReceiver, new IntentFilter("dirty"));
Should be
_dirtyMessageReceiver = new DirtyBroadcastReceiver();
LocalBroadcastManager.GetInstance(this).RegisterReceiver(_dirtyMessageReceiver, new IntentFilter("dirty"));
Secondly, the Unregistering of the Receiver should be one against the LocalBroadcastManager as well:
UnregisterReceiver(_dirtyMessageReceiver);
becomes
LocalBroadcastManager.GetInstance(this).UnregisterReceiver(_dirtyMessageReceiver);
You need to add a broadcast receiver for these.For example, Set Android.Content.Intent to ActionTimeTick so that android os will broadcast message(an android intent) whenever time is changed.
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionTimeTick })]
public class GridStartBroadcastReceiver : BroadcastReceiver
{
public static readonly string GRID_STARTED = "GRID_STARTED";
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
//your logic
}
}
}
you need to register the broadcast receiver first. Add these code to oncreate method to register broadcast receiver.
IntentFilter filter = new IntentFilter(GridStartBroadcastReceiver.GRID_STARTED);
filter.AddCategory(Intent.CategoryDefault);
_receiver = new GridStartBroadcastReceiver();
RegisterReceiver(_receiver, filter);
Next send the broadcast to the broadcast receiver.
//calling
Intent BroadcastIntent = new Intent(this, typeof(MainActivity.GridStartBroadcastReceiver));
BroadcastIntent.SetAction(MainActivity.GridStartBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
I writing android app on Xamarin(C#)
I need to Show alert with "Yes" and "No" variantes when I tap back button on Activity.
How can I realize this?
I know how to show alert. How I can make it when i press back button
try this , add to your activity
#Override
public void onBackPressed() {
AlertDialog.Builder builder =
new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setTitle(getResources().getString(R.string.app_name));
builder.setMessage("" + Message);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//write your code
}
});
builder.setNegativeButton("No", null);
builder.setCancelable(false);
builder.show();
}
Xamarin provides wrappers to the native Android Activity classes. So you probably have a MainActivity and maybe other Activity classes in your Xamarin Android project.
In these classes you can override the OnBackPressed method inherited from FormsApplicationActivity and then create and show your Alert from there.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
public override void OnBackPressed()
{
// show Alert or pass call on to base.OnBackPressed()
}
}
Since Xamarin Forms 1.3.0 pre3, there is a new method:
protected bool OnBackButtonPressed();
You need to override this on your page.
protected override bool OnBackButtonPressed()
{
// If you want to stop the back button and show alert
return true;
// If you want to continue going back
base.OnBackButtonPressed();
return false;
}
Thanks to Xamarin Forums. Refer this link for more info.
I have WIndows Service app and want to stop service when main code is executed. I am trying to execute ServiceBase.Stop() in OnStart event, everything works fine, the service is stopped but I get annoying error message in event viewer
"Service cannot be started. The handle is invalid"
Any ideas how to stop windows service without errors?
public partial class VirtualServerInitService : ServiceBase
{
public ILogger EventLogger = new EventLogger();
public VirtualServerInitService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
EventLogger.Write("Starting service!");
new VirtualServerInit(EventLogger).Run();
EventLogger.Write("VirtualServerInit code was executed");
Stop();//This code works and also gives error in event viewer
}
protected override void OnStop()
{
EventLogger.Write("Stopping service!");
}
}
Use a thread to make sure the OnStart method finishes. The threadpool will put your workitem on the queue and once a thread it is available it will execute your Run method and then calls Stop on the service. By then the windows service manager already handled the succesful start of your service and hence no error will be sent to the Eventlog when Stop is called.
protected override void OnStart(string[] args)
{
EventLogger.Write("Starting service!");
ThreadPool.QueueUserWorkItem( _ => {
new VirtualServerInit(EventLogger).Run();
EventLogger.Write("VirtualServerInit code was executed");
this.Stop();
});
}
You might consider leaving the service running and use a CustomCommand to control if actual work needs to be done. For that you can override OnCustomCommand and send a pre determined integer to ask the service to perform a particular task for example by calling sc virtualsvc control 128 from the commandline.
protected virtual void OnCustomCommand(int command)
{
switch(command)
{
case 128:
new VirtualServerInit(EventLogger).Run();
EventLogger.Write("VirtualServerInit code was executed");
// maybe keep state if this only can be run once
break;
default:
EventLogger.Write(String.Format("Unknown control code:{0}", command));
break;
}
}
I followed this tutorial
The main problem is :
What is WAKELOCK_KEY in their code ? What I must put here ?
What is classType in their code ? What I must put here ?
For the WAKELOCK_KEY I just put "NOTIF", and for classType is use typeof(MyIntentService).
I receive notification but can't receive notification when I kill the application. So how to manage this in Xamarin (no PushSharp or similar lib) ?
(My code is the same as in the tutorial, except for WAKELOCK_KEY and classType).
If you follow the tutorial, you just have to do that (seems my solution for the wakelock_key and the classType was good)
:-)
[BroadcastReceiver]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
MyIntentService.RunIntentInService(context, intent);
}
}
How does the SignalR handle client disconnection? Am I right if I state the following?
SignalR will detect browser page close/refresh via Javascript event handling and will send appropriate packet to server (through the persisting connection);
SignalR will NOT detect browser close/network failure (probably only by timeout).
I aim the long-polling transport.
I'm aware of this question but would like to make it a bit clear for me.
If a user refreshes the page, that is treated as a new connection. You are correct that the disconnect is based on a timeout.
You can handle the Connect/Reconnect and Disconnect events in a Hub by implementing SignalR.Hubs.IConnected and SignalR.Hubs.IDisconnect.
The above referred to SignalR 0.5.x.
From the official documentation (currently for v1.1.3):
public class ContosoChatHub : Hub
{
public override Task OnConnected()
{
// Add your own code here.
// For example: in a chat application, record the association between
// the current connection ID and user name, and mark the user as online.
// After the code in this method completes, the client is informed that
// the connection is established; for example, in a JavaScript client,
// the start().done callback is executed.
return base.OnConnected();
}
public override Task OnDisconnected()
{
// Add your own code here.
// For example: in a chat application, mark the user as offline,
// delete the association between the current connection id and user name.
return base.OnDisconnected();
}
public override Task OnReconnected()
{
// Add your own code here.
// For example: in a chat application, you might have marked the
// user as offline after a period of inactivity; in that case
// mark the user as online again.
return base.OnReconnected();
}
}
In SignalR 1.0, the SignalR.Hubs.IConnected and SignalR.Hubs.IDisconnect are no longer implemented, and now it's just an override on the hub itself:
public class Chat : Hub
{
public override Task OnConnected()
{
return base.OnConnected();
}
public override Task OnDisconnected()
{
return base.OnDisconnected();
}
public override Task OnReconnected()
{
return base.OnReconnected();
}
}