I'm trying to launch the TickEvent
when BroadcastReceiver
gets a custom message.
When intent.Action == Intent.ActionTimeTick
, for example (instead of GRID_STARTED
), it works fine.
I commented out the working code, so you can experiment easily.
Seems like I'm missing an important thing about actions. Could you help me out, please?
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace TestApp
{
[Activity(Label = "BroadcastUpdateFormExample", MainLauncher = true)]
public class MainActivity : Activity
{
int count = 1;
TextView txtNote;
BroadcastMessageCatcher catcher;
static readonly string TAG = "MainActivity";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
txtNote = FindViewById<TextView>(Resource.Id.textView1);
Button button = FindViewById<Button>(Resource.Id.button1);
button.Click += delegate
{
button.Text = string.Format("{0} clicks!", count++);
BroadcastStarted();
};
catcher = new BroadcastMessageCatcher();
catcher.TickEvent += delegate
{
Log.Debug(TAG, "before listener");
txtNote.Text = "Tick";
Log.Debug(TAG, "after listener");
};
}
protected override void OnResume()
{
base.OnResume();
// RegisterReceiver (catcher, new IntentFilter (Intent.ActionTimeTick));
IntentFilter filter = new IntentFilter(BroadcastMessageCatcher.GRID_STARTED);
RegisterReceiver(catcher, filter);
}
protected override void OnPause()
{
base.OnPause();
UnregisterReceiver(catcher);
}
private void BroadcastStarted()
{
// Broadcast message to the view
// Source: https://forums.xamarin.com/discussion/1147/updating-activity-using-a-background-service
Intent BroadcastIntent = new Intent(this, typeof(BroadcastMessageCatcher));
BroadcastIntent.SetAction(BroadcastMessageCatcher.GRID_STARTED);
//BroadcastIntent.AddCategory(Intent.CategoryDefault);
Log.Debug(TAG, "Broadcast started");
SendBroadcast(BroadcastIntent);
}
}
[BroadcastReceiver]
public class BroadcastMessageCatcher : BroadcastReceiver
{
static readonly string TAG = "MainActivity";
public static readonly string GRID_STARTED = "GRID_STARTED";
public override void OnReceive(Context context, Intent intent)
{
// if (intent.Action == Intent.ActionTimeTick)
if (intent.Action == GRID_STARTED)
{
Log.Debug(TAG, "before event");
// Here I get the error:
TickEvent();
Log.Debug(TAG, "after event");
}
}
public delegate void TickEventHandler();
public event TickEventHandler TickEvent;
}
}
I'm getting the 'System.NullReferenceException: 'Object reference not set to an instance of an object.'' error on TickEvent();
inside the BroadcastMessageCatcher
(marked in comments).
I understood actions wrong. Mostly because I didn't know that intent which initiates activities and intent which initiates actions are two completely different things.
So if it helps anybody, I post the working code.
Mainifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.companyname.testapp">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="com.companyname.testapp.MY_CUSTOM_ACTION"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
Activity:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Util;
using Android.Widget;
namespace TestApp
{
[Activity(Label = "BroadcastUpdateFormExample", MainLauncher = true)]
public class MainActivity : Activity
{
int count = 1;
TextView txtNote;
BroadcastMessageCatcher catcher;
static readonly string TAG = "FCMActivity";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
txtNote = FindViewById<TextView>(Resource.Id.textView1);
Button button = FindViewById<Button>(Resource.Id.button1);
button.Click += delegate
{
button.Text = string.Format("{0} clicks!", count++);
BroadcastStarted();
};
catcher = new BroadcastMessageCatcher();
catcher.TickEvent += delegate
{
Log.Debug(TAG, "before listener");
txtNote.Text = "Tick";
Log.Debug(TAG, "after listener");
};
}
protected override void OnResume()
{
base.OnResume();
IntentFilter filter = new IntentFilter("com.companyname.testapp.MY_CUSTOM_ACTION");
RegisterReceiver(catcher, filter);
}
protected override void OnPause()
{
base.OnPause();
UnregisterReceiver(catcher);
}
private void BroadcastStarted()
{
// Broadcast message to the view
Intent BroadcastIntent = new Intent();
BroadcastIntent.SetAction("com.companyname.testapp.MY_CUSTOM_ACTION");
//BroadcastIntent.AddCategory(Intent.CategoryDefault);
Log.Debug(TAG, "Broadcast started");
SendBroadcast(BroadcastIntent);
}
}
[BroadcastReceiver]
public class BroadcastMessageCatcher : BroadcastReceiver
{
private readonly string TAG = "MainActivity";
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == "com.companyname.testapp.MY_CUSTOM_ACTION")
{
Log.Debug(TAG, "before event");
TickEvent();
Log.Debug(TAG, "after event");
}
}
public delegate void TickEventHandler();
public event TickEventHandler TickEvent;
}
}