I have a service that I intend to use from an activity. However when i run my program the my variable isBound
, which I use to invoke RunOnUIThread()
to update my UI does not change from false
to true
. The program had implemented the necessary methods for the binding process but seems that some are not invoked.
Here is the code for my activity:
namespace Oasis
public class DemoActivity : Activity
{
bool isBound = false;
bool isConfigurationChange = false;
DemoServiceBinder binder;
DemoServiceConnection demoServiceConnection;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.DemoServiceUI);
var start = FindViewById<Button>(Resource.Id.startService);
start.Click += delegate
{
StartService (new Intent (this, typeof(DemoService)));
};
var stop = FindViewById<Button>(Resource.Id.stopService);
stop.Click += delegate
{
StopService (new Intent (this, typeof(DemoService)));
};
var callService = FindViewById<Button>(Resource.Id.callService);
callService.Click += delegate
{
if (isBound)
{
RunOnUiThread(() =>
{
string text = binder.GetDemoService().GetText();
if (text == "Foo")
{
UpdateUI();
}
}
);
}
};
var btnnext = FindViewById<Button>(Resource.Id.nextlayout);
btnnext.Click += btnnext_Click;
demoServiceConnection = LastNonConfigurationInstance as DemoServiceConnection;
if (demoServiceConnection != null)
binder = demoServiceConnection.Binder;
}
void btnnext_Click(object sender, EventArgs e)
{
var intent = new Intent(this, typeof(DatabaseFormActivity));
StartActivity(intent);
}
protected override void OnStart()
{
base.OnStart();
var demoServiceIntent = new Intent("DemoService");
demoServiceConnection = new DemoServiceConnection(this);
BindService(demoServiceIntent, demoServiceConnection, Bind.AutoCreate);
}
protected override void OnDestroy()
{
base.OnDestroy();
if (!isConfigurationChange)
{
if (isBound)
{
UnbindService(demoServiceConnection);
isBound = false;
}
}
}
public override Java.Lang.Object OnRetainNonConfigurationInstance()
{
base.OnRetainNonConfigurationInstance();
isConfigurationChange = true;
return demoServiceConnection;
}
class DemoServiceConnection : Java.Lang.Object, IServiceConnection
{
DemoActivity activity;
DemoServiceBinder binder;
public DemoServiceBinder Binder
{
get
{
return binder;
}
}
public DemoServiceConnection(DemoActivity activity)
{
this.activity = activity;
}
public void OnServiceConnected(ComponentName name, IBinder service)
{
var demoServiceBinder = service as DemoServiceBinder;
if (demoServiceBinder != null)
{
var binder = (DemoServiceBinder)service;
activity.binder = binder;
activity.isBound = true;
this.binder = (DemoServiceBinder)service;
}
}
public void OnServiceDisconnected(ComponentName name)
{
activity.isBound = false;
}
}
}
And the code for the Service:
[Service]
[IntentFilter(new String[]{"DemoService"})]
public class DemoService : Service
{
DemoServiceBinder binder;
private static System.Timers.Timer aTimer;
public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug ("DemoService", "DemoService started");
StartServiceInForeground ();
DoThis ();
return StartCommandResult.NotSticky;
}
void StartServiceInForeground ()
{
var ongoing = new Notification (Resource.Drawable.Icon, "DemoService in foreground");
var pendingIntent = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(DemoActivity)), 0);
ongoing.SetLatestEventInfo (this, "DemoService", "DemoService is running in the foreground", pendingIntent);
StartForeground ((int)NotificationFlags.ForegroundService, ongoing);
}
public override void OnDestroy ()
{
base.OnDestroy ();
aTimer.Stop();
aTimer.Dispose();
}
void SendNotification ()
{
var nMgr = (NotificationManager)GetSystemService (NotificationService);
var notification = new Notification (Resource.Drawable.Icon, "Message from demo service");
var pendingIntent = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(DemoActivity)), 0);
notification.SetLatestEventInfo (this, "Demo Service Notification", "Message from demo service", pendingIntent);
nMgr.Notify (0, notification);
}
public void DoThis()
{
Intent demoServiceIntent = new Intent("DemoService");
Toast.MakeText (this, "The demo service has started", ToastLength.Long).Show ();
Log.Debug("DemoService", "DoWork() started");
//SetTimer();
var t = new Thread (() => {
SendNotification ();
SetTimer();
Log.Debug("DemoService", "Timer is set");
}
);
}
public override Android.OS.IBinder OnBind (Android.Content.Intent intent)
{
binder = new DemoServiceBinder (this);
return binder;
}
public string GetText ()
{
string message = Verification.GetResponseMessage();
if (message !="")
{
KillTimer();
}
return message;
}
private static void KillTimer()
{
aTimer.Stop();
}
private static void SetTimer()
{
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Verification.Verify();
}
}
public class DemoServiceBinder : Binder
{
DemoService service;
public DemoServiceBinder (DemoService service)
{
this.service = service;
}
public DemoService GetDemoService ()
{
return service;
}
}
public class Verification
{
public string Verify(){
static string responsemessage;
}
}
public static string GetResponseMessage()
{
if (responsemessage != null)
{
return responsemessage;
}
else
{
return "";
}
}
}
}