-
Notifications
You must be signed in to change notification settings - Fork 226
/
SpeechActivationService.java
248 lines (222 loc) · 7.63 KB
/
SpeechActivationService.java
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
* Copyright 2011 Greg Milette and Adam Stroud
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package root.gast.speech.activation;
import root.gast.R;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
/**
* Persistently run a speech activator in the background.
* Use {@link Intent}s to start and stop it
* @author Greg Milette <<a
* href="mailto:gregorym@gmail.com">gregorym@gmail.com</a>>
*
*/
public class SpeechActivationService extends Service implements
SpeechActivationListener
{
private static final String TAG = "SpeechActivationService";
public static final String NOTIFICATION_ICON_RESOURCE_INTENT_KEY =
"NOTIFICATION_ICON_RESOURCE_INTENT_KEY";
public static final String ACTIVATION_TYPE_INTENT_KEY =
"ACTIVATION_TYPE_INTENT_KEY";
public static final String ACTIVATION_RESULT_INTENT_KEY =
"ACTIVATION_RESULT_INTENT_KEY";
public static final String ACTIVATION_RESULT_BROADCAST_NAME =
"root.gast.playground.speech.ACTIVATION";
/**
* send this when external code wants the Service to stop
*/
public static final String ACTIVATION_STOP_INTENT_KEY =
"ACTIVATION_STOP_INTENT_KEY";
public static final int NOTIFICATION_ID = 10298;
private boolean isStarted;
private SpeechActivator activator;
@Override
public void onCreate()
{
super.onCreate();
isStarted = false;
}
public static Intent makeStartServiceIntent(Context context,
String activationType)
{
Intent i = new Intent(context, SpeechActivationService.class);
i.putExtra(ACTIVATION_TYPE_INTENT_KEY, activationType);
return i;
}
public static Intent makeServiceStopIntent(Context context)
{
Intent i = new Intent(context, SpeechActivationService.class);
i.putExtra(ACTIVATION_STOP_INTENT_KEY, true);
return i;
}
/**
* stop or start an activator based on the activator type and if an
* activator is currently running
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if (intent != null)
{
if (intent.hasExtra(ACTIVATION_STOP_INTENT_KEY))
{
Log.d(TAG, "stop service intent");
activated(false);
}
else
{
if (isStarted)
{
// the activator is currently started
// if the intent is requesting a new activator
// stop the current activator and start
// the new one
if (isDifferentType(intent))
{
Log.d(TAG, "is differnet type");
stopActivator();
startDetecting(intent);
}
else
{
Log.d(TAG, "already started this type");
}
}
else
{
// activator not started, start it
startDetecting(intent);
}
}
}
// restart in case the Service gets canceled
return START_REDELIVER_INTENT;
}
private void startDetecting(Intent intent)
{
Log.d(TAG, "extras: " + intent.getExtras().toString());
if (activator == null)
{
Log.d(TAG, "null activator");
}
activator = getRequestedActivator(intent);
Log.d(TAG, "started: " + activator.getClass().getSimpleName());
isStarted = true;
activator.detectActivation();
startForeground(NOTIFICATION_ID, getNotification(intent));
}
private SpeechActivator getRequestedActivator(Intent intent)
{
String type = intent.getStringExtra(ACTIVATION_TYPE_INTENT_KEY);
// create based on a type name
SpeechActivator speechActivator =
SpeechActivatorFactory.createSpeechActivator(this, this, type);
return speechActivator;
}
/**
* determine if the intent contains an activator type
* that is different than the currently running type
*/
private boolean isDifferentType(Intent intent)
{
boolean different = false;
if (activator == null)
{
return true;
}
else
{
SpeechActivator possibleOther = getRequestedActivator(intent);
different = !(possibleOther.getClass().getName().
equals(activator.getClass().getName()));
}
return different;
}
@Override
public void activated(boolean success)
{
// make sure the activator is stopped before doing anything else
stopActivator();
// broadcast result
Intent intent = new Intent(ACTIVATION_RESULT_BROADCAST_NAME);
intent.putExtra(ACTIVATION_RESULT_INTENT_KEY, success);
sendBroadcast(intent);
// always stop after receive an activation
stopSelf();
}
@Override
public void onDestroy()
{
Log.d(TAG, "On destroy");
super.onDestroy();
stopActivator();
stopForeground(true);
}
private void stopActivator()
{
if (activator != null)
{
Log.d(TAG, "stopped: " + activator.getClass().getSimpleName());
activator.stop();
isStarted = false;
}
}
@SuppressLint("NewApi")
private Notification getNotification(Intent intent)
{
// determine label based on the class
String name = SpeechActivatorFactory.getLabel(this, activator);
String message =
getString(R.string.speech_activation_notification_listening)
+ " " + name;
String title = getString(R.string.speech_activation_notification_title);
PendingIntent pi =
PendingIntent.getService(this, 0, makeServiceStopIntent(this),
0);
int icon = intent.getIntExtra(NOTIFICATION_ICON_RESOURCE_INTENT_KEY, R.drawable.icon);
Notification notification;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(icon)
.setWhen(System.currentTimeMillis()).setTicker(message)
.setContentTitle(title).setContentText(message)
.setContentIntent(pi);
notification = builder.getNotification();
}
else
{
notification =
new Notification(icon, message,
System.currentTimeMillis());
notification.setLatestEventInfo(this, title, message, pi);
}
return notification;
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}