forked from reactiveui/ReactiveUI
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContextExtensions.cs
More file actions
106 lines (88 loc) · 3.72 KB
/
ContextExtensions.cs
File metadata and controls
106 lines (88 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using System.Reactive.Linq;
using Android.Content;
using Android.OS;
namespace ReactiveUI
{
public static class ContextExtensions
{
/// <summary>
/// Binds the service.
/// </summary>
/// <returns>The observable sequence of service binders.</returns>
/// <param name="context">The Context to bind the Service from.</param>
/// <param name="intent">Identifies the service to connect to. The Intent may specify either an explicit component name, or a logical description (action, category, etc) to match an IntentFilter published by a service.</param>
/// <param name="flags">Operation options for the binding. The default is Bind.None.</param>
public static IObservable<IBinder> ServiceBound (this Context context, Intent intent, Bind flags = Bind.None)
{
return ServiceBound<IBinder> (context, intent, flags);
}
/// <summary>
/// Binds the service.
/// </summary>
/// <returns>The observable sequence of service binders.</returns>
/// <param name="context">The Context to bind the Service from.</param>
/// <param name="intent">Identifies the service to connect to. The Intent may specify either an explicit component name, or a logical description (action, category, etc) to match an IntentFilter published by a service.</param>
/// <param name="flags">Operation options for the binding. The default is Bind.None.</param>
/// <typeparam name="TBinder">The type of the returned service binder.</typeparam>
public static IObservable<TBinder> ServiceBound<TBinder> (this Context context, Intent intent, Bind flags = Bind.None)
where TBinder
: class
, IBinder
{
return Observable.Create<TBinder> (observer => {
var connection = new ServiceConnection<TBinder> (context, observer);
try {
if (!context.BindService (intent, connection, flags))
observer.OnError (new Exception ("Service bind failed!"));
}
catch(Exception ex) {
observer.OnError (ex);
}
return connection;
});
}
/// <summary>
/// A private implementation of IServiceConnection and IDisposable.
/// </summary>
class ServiceConnection<TBinder>
: Java.Lang.Object
, IServiceConnection
where TBinder
: class
, IBinder
{
readonly Context context;
readonly IObserver<TBinder> observer;
public ServiceConnection (Context context, IObserver<TBinder> observer)
{
this.context = context;
this.observer = observer;
}
#region IServiceConnection implemention
void IServiceConnection.OnServiceConnected (ComponentName name, IBinder binder)
{
observer.OnNext ((TBinder)binder);
}
void IServiceConnection.OnServiceDisconnected (ComponentName name)
{
// lost connection to the remote service but it may be revived
observer.OnNext (null);
}
#endregion
#region Dispose implementation
bool disposed;
protected override void Dispose (bool disposing)
{
if (!disposed) {
if (disposing) {
context.UnbindService (this);
disposed = true;
}
}
base.Dispose (disposing);
}
#endregion
}
}
}