git.haldean.org droidcopter / e0fccc0
removed svn files that amarino won't be needing anymore... Benjamin Bardin 11 years ago
33 changed file(s) with 0 addition(s) and 6871 deletion(s). Raw diff Collapse all Expand all
+0
-101
at/abraxas/amarino/.svn/all-wcprops less more
0 K 25
1 svn:wc:ra_dav:version-url
2 V 53
3 /svn/!svn/ver/23/trunk/amarino/src/at/abraxas/amarino
4 END
5 AmarinoService.java
6 K 25
7 svn:wc:ra_dav:version-url
8 V 73
9 /svn/!svn/ver/23/trunk/amarino/src/at/abraxas/amarino/AmarinoService.java
10 END
11 AmarinoIntent.java
12 K 25
13 svn:wc:ra_dav:version-url
14 V 72
15 /svn/!svn/ver/16/trunk/amarino/src/at/abraxas/amarino/AmarinoIntent.java
16 END
17 package.html
18 K 25
19 svn:wc:ra_dav:version-url
20 V 65
21 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/package.html
22 END
23 EventListAdapter.java
24 K 25
25 svn:wc:ra_dav:version-url
26 V 74
27 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/EventListAdapter.java
28 END
29 Event.java
30 K 25
31 svn:wc:ra_dav:version-url
32 V 63
33 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/Event.java
34 END
35 MainScreen.java
36 K 25
37 svn:wc:ra_dav:version-url
38 V 68
39 /svn/!svn/ver/2/trunk/amarino/src/at/abraxas/amarino/MainScreen.java
40 END
41 BTDevice.java
42 K 25
43 svn:wc:ra_dav:version-url
44 V 66
45 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/BTDevice.java
46 END
47 Monitoring.java
48 K 25
49 svn:wc:ra_dav:version-url
50 V 68
51 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/Monitoring.java
52 END
53 Amarino.java
54 K 25
55 svn:wc:ra_dav:version-url
56 V 66
57 /svn/!svn/ver/18/trunk/amarino/src/at/abraxas/amarino/Amarino.java
58 END
59 DeviceDiscovery.java
60 K 25
61 svn:wc:ra_dav:version-url
62 V 74
63 /svn/!svn/ver/10/trunk/amarino/src/at/abraxas/amarino/DeviceDiscovery.java
64 END
65 EventListActivity.java
66 K 25
67 svn:wc:ra_dav:version-url
68 V 75
69 /svn/!svn/ver/2/trunk/amarino/src/at/abraxas/amarino/EventListActivity.java
70 END
71 PlugInListAdapter.java
72 K 25
73 svn:wc:ra_dav:version-url
74 V 75
75 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/PlugInListAdapter.java
76 END
77 MessageBuilder.java
78 K 25
79 svn:wc:ra_dav:version-url
80 V 73
81 /svn/!svn/ver/23/trunk/amarino/src/at/abraxas/amarino/MessageBuilder.java
82 END
83 RemoteControl.java
84 K 25
85 svn:wc:ra_dav:version-url
86 V 71
87 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/RemoteControl.java
88 END
89 AmarinoDbAdapter.java
90 K 25
91 svn:wc:ra_dav:version-url
92 V 75
93 /svn/!svn/ver/16/trunk/amarino/src/at/abraxas/amarino/AmarinoDbAdapter.java
94 END
95 Plugin.java
96 K 25
97 svn:wc:ra_dav:version-url
98 V 64
99 /svn/!svn/ver/1/trunk/amarino/src/at/abraxas/amarino/Plugin.java
100 END
+0
-581
at/abraxas/amarino/.svn/entries less more
0 10
1
2 dir
3 28
4 http://amarino.googlecode.com/svn/trunk/amarino/src/at/abraxas/amarino
5 http://amarino.googlecode.com/svn
6
7
8
9 2010-10-25T15:40:49.525557Z
10 23
11 bonifaz.kaufmann
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 87dd5177-5231-7982-c9c5-4deadf6c03d2
27
28 log
29 dir
30
31 AmarinoService.java
32 file
33
34
35
36
37 2011-04-26T14:39:39.490111Z
38 5f09148e4dec6521ef1c100cb4cbfd25
39 2010-10-25T15:40:49.525557Z
40 23
41 bonifaz.kaufmann
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 25642
64
65 AmarinoIntent.java
66 file
67
68
69
70
71 2011-04-26T14:39:39.490111Z
72 99f915c5f133d54fab96141c7a44b0e4
73 2010-08-23T20:28:21.971025Z
74 16
75 bonifaz.kaufmann
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 17320
98
99 visualizer
100 dir
101
102 package.html
103 file
104
105
106
107
108 2011-04-26T14:39:39.494111Z
109 6a844b0220fcc44f39c3f1a317da4bcb
110 2010-06-10T13:38:22.246184Z
111 1
112 bonifaz.kaufmann
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 181
135
136 EventListAdapter.java
137 file
138
139
140
141
142 2011-04-26T14:39:39.490111Z
143 cc6f662d406fd61cac225c3ff63dc467
144 2010-06-10T13:38:22.246184Z
145 1
146 bonifaz.kaufmann
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 4702
169
170 plugin
171 dir
172
173 Event.java
174 file
175
176
177
178
179 2011-04-26T14:39:39.494111Z
180 e78b505db0f82279c05c2c0930564111
181 2010-06-10T13:38:22.246184Z
182 1
183 bonifaz.kaufmann
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 2742
206
207 MainScreen.java
208 file
209
210
211
212
213 2011-04-26T14:39:39.494111Z
214 bf6354fc2f241eb37373e4e8e89b8d5d
215 2010-07-01T10:20:06.798820Z
216 2
217 bonifaz.kaufmann
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 17240
240
241 BTDevice.java
242 file
243
244
245
246
247 2011-04-26T14:39:39.494111Z
248 07206d996a7e27800f1dfaa5b3a9ca41
249 2010-06-10T13:38:22.246184Z
250 1
251 bonifaz.kaufmann
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 2534
274
275 Monitoring.java
276 file
277
278
279
280
281 2011-04-26T14:39:39.494111Z
282 18906a421b330222e693616fbf42611b
283 2010-06-10T13:38:22.246184Z
284 1
285 bonifaz.kaufmann
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307 9054
308
309 Amarino.java
310 file
311
312
313
314
315 2011-04-26T14:39:39.494111Z
316 805b5bc337577ec117f936945640c8a8
317 2010-08-25T13:08:29.132375Z
318 18
319 bonifaz.kaufmann
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 27356
342
343 DeviceDiscovery.java
344 file
345
346
347
348
349 2011-04-26T14:39:39.498111Z
350 f00c1017ee825358c26b6eadb0829ede
351 2010-07-08T22:19:04.182431Z
352 10
353 bonifaz.kaufmann
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 5684
376
377 EventListActivity.java
378 file
379
380
381
382
383 2011-04-26T14:39:39.498111Z
384 90ba712e7504b88682a5671abc03f4b9
385 2010-07-01T10:20:06.798820Z
386 2
387 bonifaz.kaufmann
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 21213
410
411 MessageBuilder.java
412 file
413
414
415
416
417 2011-04-26T14:39:39.498111Z
418 d81b07ada94064189c01e75a08871f24
419 2010-10-25T15:40:49.525557Z
420 23
421 bonifaz.kaufmann
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443 9826
444
445 PlugInListAdapter.java
446 file
447
448
449
450
451 2011-04-26T14:39:39.498111Z
452 a3f951300bd412626f3532b3447d8d85
453 2010-06-10T13:38:22.246184Z
454 1
455 bonifaz.kaufmann
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 2547
478
479 RemoteControl.java
480 file
481
482
483
484
485 2011-04-26T14:39:39.498111Z
486 06db7baa4a85c59a958e579c625e80f7
487 2010-06-10T13:38:22.246184Z
488 1
489 bonifaz.kaufmann
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511 2342
512
513 AmarinoDbAdapter.java
514 file
515
516
517
518
519 2011-04-26T14:39:39.502111Z
520 63fb8dd375b7b207a5dd8032a235b2b7
521 2010-08-23T20:28:21.971025Z
522 16
523 bonifaz.kaufmann
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545 14143
546
547 Plugin.java
548 file
549
550
551
552
553 2011-04-26T14:39:39.502111Z
554 c9265bb9eab6720cd5b14c2b7a0df715
555 2010-06-10T13:38:22.246184Z
556 1
557 bonifaz.kaufmann
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579 1352
580
+0
-678
at/abraxas/amarino/.svn/text-base/Amarino.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import java.util.regex.Pattern;
21
22 import android.content.Context;
23 import android.content.Intent;
24
25 /**
26 * This class is part of the Amarino Library and bundles some very useful methods to communicate
27 * with Arduino.
28 * <p>
29 * @author Bonifaz Kaufmann
30 * </p>
31 * $Id: Amarino.java 444 2010-06-10 13:11:59Z abraxas $
32 */
33 public class Amarino {
34
35 /**
36 * Only static methods, no need to get an instance of Amarino
37 */
38 private Amarino(){};
39
40 /**
41 * Establish a connection to the Bluetooth device with the given address.
42 * This method uses {@link at.abraxas.amarino.AmarinoIntent#ACTION_CONNECT} to initiate a connection.
43 *
44 * You might want to know if your connection was successful or not.
45 * To get feedback from Amarino register a
46 * <a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a>
47 * for the following intents.
48 * <ul>
49 * <li><em>{@link at.abraxas.amarino.AmarinoIntent#ACTION_CONNECTED}</em></li>
50 * <li><em>{@link at.abraxas.amarino.AmarinoIntent#ACTION_DISCONNECTED}</em></li>
51 * <li><em>{@link at.abraxas.amarino.AmarinoIntent#ACTION_CONNECTION_FAILED}</em></li>
52 * <li><em>{@link at.abraxas.amarino.AmarinoIntent#ACTION_PAIRING_REQUESTED}</em></li>
53 * </ul>
54 *
55 * Amarino will broadcast one of the four intents after your have called {@link #connect(Context, String)}
56 *
57 * @param context the context
58 * @param address address of your Arduino Bluetooth module
59 * <pre>e.g. "00:06:54:4B:31:7E"</pre>
60 */
61 public static void connect(Context context, String address){
62 Intent intent = new Intent(AmarinoIntent.ACTION_CONNECT);
63 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address);
64 context.sendBroadcast(intent);
65 }
66
67 /**
68 * Disconnect from a Bluetooth device
69 *
70 * For feedback register a
71 * <a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a>
72 * for the {@link at.abraxas.amarino.AmarinoIntent#ACTION_DISCONNECTED} intent.
73 *
74 * @param context the context
75 * @param address address of your Arduino Bluetooth module, should be the same
76 * which you used to connect to the device
77 */
78 public static void disconnect(Context context, String address){
79 Intent intent = new Intent(AmarinoIntent.ACTION_DISCONNECT);
80 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address);
81 context.sendBroadcast(intent);
82 }
83
84 /**
85 * Sends a boolean value to Arduino
86 *
87 * @param context the context
88 * @param address the Bluetooth device you want to send data to
89 * @param flag the flag Arduino has registered a function for to receive this data
90 * @param data your data you want to send
91 */
92 public static void sendDataToArduino(Context context, String address, char flag, boolean data) {
93 Intent intent = getSendIntent(address, AmarinoIntent.BOOLEAN_EXTRA, flag);
94 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
95 context.sendBroadcast(intent);
96 }
97
98 /**
99 * Sends a byte value to Arduino
100 *
101 * @param context the context
102 * @param address the Bluetooth device you want to send data to
103 * @param flag the flag Arduino has registered a function for to receive this data
104 * @param data your data you want to send
105 */
106 public static void sendDataToArduino(Context context, String address, char flag, byte data) {
107 Intent intent = getSendIntent(address, AmarinoIntent.BYTE_EXTRA, flag);
108 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
109 context.sendBroadcast(intent);
110 }
111
112 /**
113 * Sends a char value to Arduino
114 *
115 * @param context the context
116 * @param address the Bluetooth device you want to send data to
117 * @param flag the flag Arduino has registered a function for to receive this data
118 * @param data your data you want to send
119 */
120 public static void sendDataToArduino(Context context, String address, char flag, char data) {
121 Intent intent = getSendIntent(address, AmarinoIntent.CHAR_EXTRA, flag);
122 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
123 context.sendBroadcast(intent);
124 }
125
126 /**
127 * Sends a short value to Arduino
128 *
129 * @param context the context
130 * @param address the Bluetooth device you want to send data to
131 * @param flag the flag Arduino has registered a function for to receive this data
132 * @param data your data you want to send
133 */
134 public static void sendDataToArduino(Context context, String address, char flag, short data) {
135 Intent intent = getSendIntent(address, AmarinoIntent.SHORT_EXTRA, flag);
136 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
137 context.sendBroadcast(intent);
138 }
139
140 /**
141 * Sends an int value to Arduino
142 *
143 * @param context the context
144 * @param address the Bluetooth device you want to send data to
145 * @param flag the flag Arduino has registered a function for to receive this data
146 * @param data your data you want to send
147 */
148 public static void sendDataToArduino(Context context, String address, char flag, int data) {
149 Intent intent = getSendIntent(address, AmarinoIntent.INT_EXTRA, flag);
150 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
151 context.sendBroadcast(intent);
152 }
153
154 /**
155 * Sends a long value to Arduino
156 *
157 * <p><i>If you do not exactly know what you do, you absolutely shouldn't really use this method,
158 * since Arduino cannot receive Android's 32-bit long values.</i></p>
159 *
160 * @param context the context
161 * @param address the Bluetooth device you want to send data to
162 * @param flag the flag Arduino has registered a function for to receive this data
163 * @param data your data you want to send
164 */
165 public static void sendDataToArduino(Context context, String address, char flag, long data) {
166 Intent intent = getSendIntent(address, AmarinoIntent.LONG_EXTRA, flag);
167 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
168 context.sendBroadcast(intent);
169 }
170
171 /**
172 * Sends a float value to Arduino
173 *
174 * @param context the context
175 * @param address the Bluetooth device you want to send data to
176 * @param flag the flag Arduino has registered a function for to receive this data
177 * @param data your data you want to send
178 */
179 public static void sendDataToArduino(Context context, String address, char flag, float data) {
180 Intent intent = getSendIntent(address, AmarinoIntent.FLOAT_EXTRA, flag);
181 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
182 context.sendBroadcast(intent);
183 }
184
185 /**
186 * Sends a double value to Arduino
187 *
188 * <p><i>If you do not exactly know what you do, you absolutely shouldn't really use this method,
189 * since Arduino cannot receive Android's 32-bit double values.</i></p>
190 *
191 * @param context the context
192 * @param address the Bluetooth device you want to send data to
193 * @param flag the flag Arduino has registered a function for to receive this data
194 * @param data your data you want to send
195 */
196 public static void sendDataToArduino(Context context, String address, char flag, double data) {
197 Intent intent = getSendIntent(address, AmarinoIntent.DOUBLE_EXTRA, flag);
198 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
199 context.sendBroadcast(intent);
200 }
201
202 /**
203 * Sends a String to Arduino
204 *
205 * <p><i>The buffer of an Arduino is small, your String should not be longer than 62 characters</i></p>
206 * @assertion: (data.length() <= 62)
207 *
208 * @param context the context
209 * @param address the Bluetooth device you want to send data to
210 * @param flag the flag Arduino has registered a function for to receive this data
211 * @param data your data you want to send
212 */
213 public static void sendDataToArduino(Context context, String address, char flag, String data) {
214 Intent intent = getSendIntent(address, AmarinoIntent.STRING_EXTRA, flag);
215 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
216 context.sendBroadcast(intent);
217 }
218
219 /**
220 * Sends an boolean array to Arduino
221 *
222 * @param context the context
223 * @param address the Bluetooth device you want to send data to
224 * @param flag the flag Arduino has registered a function for to receive this data
225 * @param data your data you want to send
226 */
227 public static void sendDataToArduino(Context context, String address, char flag, boolean[] data) {
228 Intent intent = getSendIntent(address, AmarinoIntent.BOOLEAN_ARRAY_EXTRA, flag);
229 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
230 context.sendBroadcast(intent);
231 }
232
233 /**
234 * Sends an byte array to Arduino
235 *
236 * @param context the context
237 * @param address the Bluetooth device you want to send data to
238 * @param flag the flag Arduino has registered a function for to receive this data
239 * @param data your data you want to send
240 */
241 public static void sendDataToArduino(Context context, String address, char flag, byte[] data) {
242 Intent intent = getSendIntent(address, AmarinoIntent.BYTE_ARRAY_EXTRA, flag);
243 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
244 context.sendBroadcast(intent);
245 }
246
247 /**
248 * Sends a char array to Arduino
249 *
250 * @param context the context
251 * @param address the Bluetooth device you want to send data to
252 * @param flag the flag Arduino has registered a function for to receive this data
253 * @param data your data you want to send
254 */
255 public static void sendDataToArduino(Context context, String address, char flag, char[] data) {
256 Intent intent = getSendIntent(address, AmarinoIntent.CHAR_ARRAY_EXTRA, flag);
257 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
258 context.sendBroadcast(intent);
259 }
260
261 /**
262 * Sends a short array to Arduino
263 *
264 * @param context the context
265 * @param address the Bluetooth device you want to send data to
266 * @param flag the flag Arduino has registered a function for to receive this data
267 * @param data your data you want to send
268 */
269 public static void sendDataToArduino(Context context, String address, char flag, short[] data) {
270 Intent intent = getSendIntent(address, AmarinoIntent.SHORT_ARRAY_EXTRA, flag);
271 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
272 context.sendBroadcast(intent);
273 }
274
275 /**
276 * Sends an int array to Arduino
277 *
278 * @param context the context
279 * @param address the Bluetooth device you want to send data to
280 * @param flag the flag Arduino has registered a function for to receive this data
281 * @param data your data you want to send
282 */
283 public static void sendDataToArduino(Context context, String address, char flag, int[] data) {
284 Intent intent = getSendIntent(address, AmarinoIntent.INT_ARRAY_EXTRA, flag);
285 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
286 context.sendBroadcast(intent);
287 }
288
289 /**
290 * Sends a long array to Arduino
291 *
292 * <p><i>If you do not exactly know what you do, you absolutely shouldn't really use this method,
293 * since Arduino cannot receive Android's 32-bit long values.</i></p>
294 *
295 * @param context the context
296 * @param address the Bluetooth device you want to send data to
297 * @param flag the flag Arduino has registered a function for to receive this data
298 * @param data your data you want to send
299 */
300 public static void sendDataToArduino(Context context, String address, char flag, long[] data) {
301 Intent intent = getSendIntent(address, AmarinoIntent.LONG_ARRAY_EXTRA, flag);
302 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
303 context.sendBroadcast(intent);
304 }
305
306 /**
307 * Sends a float array to Arduino
308 *
309 * @param context the context
310 * @param address the Bluetooth device you want to send data to
311 * @param flag the flag Arduino has registered a function for to receive this data
312 * @param data your data you want to send
313 */
314 public static void sendDataToArduino(Context context, String address, char flag, float[] data) {
315 Intent intent = getSendIntent(address, AmarinoIntent.FLOAT_ARRAY_EXTRA, flag);
316 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
317 context.sendBroadcast(intent);
318 }
319
320 /**
321 * Sends a double array to Arduino
322 *
323 * <p><i>If you do not exactly know what you do, you absolutely shouldn't really use this method,
324 * since Arduino cannot receive Android's 32-bit double values.</i></p>
325 *
326 * @param context the context
327 * @param address the Bluetooth device you want to send data to
328 * @param flag the flag Arduino has registered a function for to receive this data
329 * @param data your data you want to send
330 */
331 public static void sendDataToArduino(Context context, String address, char flag, double[] data) {
332 Intent intent = getSendIntent(address, AmarinoIntent.DOUBLE_ARRAY_EXTRA, flag);
333 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
334 context.sendBroadcast(intent);
335 }
336
337 /**
338 * Sends a String array to Arduino
339 *
340 * <p><i>The buffer of an Arduino is small, your String should not be longer than 62 characters.</i></p>
341 * @assertion: for each (String s : data) { assert(s.length() <= 62); }
342 *
343 * @param context the context
344 * @param address the Bluetooth device you want to send data to
345 * @param flag the flag Arduino has registered a function for to receive this data
346 * @param data your data you want to send
347 */
348 public static void sendDataToArduino(Context context, String address, char flag, String[] data) {
349 Intent intent = getSendIntent(address, AmarinoIntent.STRING_ARRAY_EXTRA, flag);
350 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
351 context.sendBroadcast(intent);
352 }
353
354
355 /* methods normally used by plug-in developers */
356
357 /**
358 * Used by plug-in developers to send a boolean value.
359 *
360 * <p>This method can only be used within a plugin!
361 * If you want to send data from your own standalone application, use
362 * {@link #sendDataToArduino(Context context, String address, char flag, boolean data)} instead.</p>
363 *
364 * @param context the context
365 * @param pluginId you received this id when
366 * @param data your data you want to send
367 */
368 public static void sendDataFromPlugin(Context context, int pluginId, boolean data){
369 Intent intent = getPluginSendIntent(AmarinoIntent.BOOLEAN_EXTRA, pluginId);
370 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
371 context.sendBroadcast(intent);
372 }
373
374 /**
375 * Used by plug-in developers to send a byte value.
376 *
377 * <p>This method can only be used within a plugin!
378 * If you want to send data from your own standalone application, use
379 * {@link #sendDataToArduino(Context context, String address, char flag, byte data)} instead.</p>
380 *
381 * @param context the context
382 * @param pluginId you received this id when
383 * @param data your data you want to send
384 */
385 public static void sendDataFromPlugin(Context context, int pluginId, byte data){
386 Intent intent = getPluginSendIntent(AmarinoIntent.BYTE_EXTRA, pluginId);
387 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
388 context.sendBroadcast(intent);
389 }
390
391 /**
392 * Used by plug-in developers to send a char value.
393 *
394 * <p>This method can only be used within a plugin!
395 * If you want to send data from your own standalone application, use
396 * {@link #sendDataToArduino(Context context, String address, char flag, char data)} instead.</p>
397 *
398 * @param context the context
399 * @param pluginId you received this id when
400 * @param data your data you want to send
401 */
402 public static void sendDataFromPlugin(Context context, int pluginId, char data){
403 Intent intent = getPluginSendIntent(AmarinoIntent.CHAR_EXTRA, pluginId);
404 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
405 context.sendBroadcast(intent);
406 }
407
408 /**
409 * Used by plug-in developers to send a int value.
410 *
411 * <p>This method can only be used within a plugin!
412 * If you want to send data from your own standalone application, use
413 * {@link #sendDataToArduino(Context context, String address, char flag, int data)} instead.</p>
414 *
415 * @param context the context
416 * @param pluginId you received this id when
417 * @param data your data you want to send
418 */
419 public static void sendDataFromPlugin(Context context, int pluginId, int data){
420 Intent intent = getPluginSendIntent(AmarinoIntent.INT_EXTRA, pluginId);
421 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
422 context.sendBroadcast(intent);
423 }
424
425 /**
426 * Used by plug-in developers to send a long value.
427 *
428 * <p>This method can only be used within a plugin!
429 * If you want to send data from your own standalone application, use
430 * {@link #sendDataToArduino(Context context, String address, char flag, long data)} instead.</p>
431 *
432 * @param context the context
433 * @param pluginId you received this id when
434 * @param data your data you want to send
435 */
436 public static void sendDataFromPlugin(Context context, int pluginId, long data){
437 Intent intent = getPluginSendIntent(AmarinoIntent.LONG_EXTRA, pluginId);
438 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
439 context.sendBroadcast(intent);
440 }
441
442 /**
443 * Used by plug-in developers to send a float value.
444 *
445 * <p>This method can only be used within a plugin!
446 * If you want to send data from your own standalone application, use
447 * {@link #sendDataToArduino(Context context, String address, char flag, float data)} instead.</p>
448 *
449 * @param context the context
450 * @param pluginId you received this id when
451 * @param data your data you want to send
452 */
453 public static void sendDataFromPlugin(Context context, int pluginId, float data){
454 Intent intent = getPluginSendIntent(AmarinoIntent.FLOAT_EXTRA, pluginId);
455 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
456 context.sendBroadcast(intent);
457 }
458
459 /**
460 * Used by plug-in developers to send a double value.
461 *
462 * <p>This method can only be used within a plugin!
463 * If you want to send data from your own standalone application, use
464 * {@link #sendDataToArduino(Context context, String address, char flag, double data)} instead.</p>
465 *
466 * @param context the context
467 * @param pluginId you received this id when
468 * @param data your data you want to send
469 */
470 public static void sendDataFromPlugin(Context context, int pluginId, double data){
471 Intent intent = getPluginSendIntent(AmarinoIntent.DOUBLE_EXTRA, pluginId);
472 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
473 context.sendBroadcast(intent);
474 }
475
476 /**
477 * Used by plug-in developers to send a String value.
478 *
479 * <p>This method can only be used within a plugin!
480 * If you want to send data from your own standalone application, use
481 * {@link #sendDataToArduino(Context context, String address, char flag, String data)} instead.</p>
482 *
483 * @param context the context
484 * @param pluginId you received this id when
485 * @param data your data you want to send
486 */
487 public static void sendDataFromPlugin(Context context, int pluginId, String data){
488 Intent intent = getPluginSendIntent(AmarinoIntent.STRING_EXTRA, pluginId);
489 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
490 context.sendBroadcast(intent);
491 }
492
493 /**
494 * Used by plug-in developers to send a boolean array.
495 *
496 * <p>This method can only be used within a plugin!
497 * If you want to send data from your own standalone application, use
498 * {@link #sendDataToArduino(Context context, String address, char flag, boolean[] data)} instead.</p>
499 *
500 * @param context the context
501 * @param pluginId you received this id when
502 * @param data your data you want to send
503 */
504 public static void sendDataFromPlugin(Context context, int pluginId, boolean[] data){
505 Intent intent = getPluginSendIntent(AmarinoIntent.BOOLEAN_ARRAY_EXTRA, pluginId);
506 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
507 context.sendBroadcast(intent);
508 }
509
510 /**
511 * Used by plug-in developers to send a byte array.
512 *
513 * <p>This method can only be used within a plugin!
514 * If you want to send data from your own standalone application, use
515 * {@link #sendDataToArduino(Context context, String address, char flag, byte[] data)} instead.</p>
516 *
517 * @param context the context
518 * @param pluginId you received this id when
519 * @param data your data you want to send
520 */
521 public static void sendDataFromPlugin(Context context, int pluginId, byte[] data){
522 Intent intent = getPluginSendIntent(AmarinoIntent.BYTE_ARRAY_EXTRA, pluginId);
523 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
524 context.sendBroadcast(intent);
525 }
526
527 /**
528 * Used by plug-in developers to send a char array.
529 *
530 * <p>This method can only be used within a plugin!
531 * If you want to send data from your own standalone application, use
532 * {@link #sendDataToArduino(Context context, String address, char flag, char[] data)} instead.</p>
533 *
534 * @param context the context
535 * @param pluginId you received this id when
536 * @param data your data you want to send
537 */
538 public static void sendDataFromPlugin(Context context, int pluginId, char[] data){
539 Intent intent = getPluginSendIntent(AmarinoIntent.CHAR_ARRAY_EXTRA, pluginId);
540 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
541 context.sendBroadcast(intent);
542 }
543
544 /**
545 * Used by plug-in developers to send a short array.
546 *
547 * <p>This method can only be used within a plugin!
548 * If you want to send data from your own standalone application, use
549 * {@link #sendDataToArduino(Context context, String address, char flag, short[] data)} instead.</p>
550 *
551 * @param context the context
552 * @param pluginId you received this id when
553 * @param data your data you want to send
554 */
555 public static void sendDataFromPlugin(Context context, int pluginId, short[] data){
556 Intent intent = getPluginSendIntent(AmarinoIntent.SHORT_ARRAY_EXTRA, pluginId);
557 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
558 context.sendBroadcast(intent);
559 }
560
561 /**
562 * Used by plug-in developers to send a int array.
563 *
564 * <p>This method can only be used within a plugin!
565 * If you want to send data from your own standalone application, use
566 * {@link #sendDataToArduino(Context context, String address, char flag, int[] data)} instead.</p>
567 *
568 * @param context the context
569 * @param pluginId you received this id when
570 * @param data your data you want to send
571 */
572 public static void sendDataFromPlugin(Context context, int pluginId, int[] data){
573 Intent intent = getPluginSendIntent(AmarinoIntent.INT_ARRAY_EXTRA, pluginId);
574 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
575 context.sendBroadcast(intent);
576 }
577
578 /**
579 * Used by plug-in developers to send a long array.
580 *
581 * <p>This method can only be used within a plugin!
582 * If you want to send data from your own standalone application, use
583 * {@link #sendDataToArduino(Context context, String address, char flag, long[] data)} instead.</p>
584 *
585 * @param context the context
586 * @param pluginId you received this id when
587 * @param data your data you want to send
588 */
589 public static void sendDataFromPlugin(Context context, int pluginId, long[] data){
590 Intent intent = getPluginSendIntent(AmarinoIntent.LONG_ARRAY_EXTRA, pluginId);
591 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
592 context.sendBroadcast(intent);
593 }
594
595 /**
596 * Used by plug-in developers to send a float array.
597 *
598 * <p>This method can only be used within a plugin!
599 * If you want to send data from your own standalone application, use
600 * {@link #sendDataToArduino(Context context, String address, char flag, float[] data)} instead.</p>
601 *
602 * @param context the context
603 * @param pluginId you received this id when
604 * @param data your data you want to send
605 */
606 public static void sendDataFromPlugin(Context context, int pluginId, float[] data){
607 Intent intent = getPluginSendIntent(AmarinoIntent.FLOAT_ARRAY_EXTRA, pluginId);
608 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
609 context.sendBroadcast(intent);
610 }
611
612 /**
613 * Used by plug-in developers to send a double array.
614 *
615 * <p>This method can only be used within a plugin!
616 * If you want to send data from your own standalone application, use
617 * {@link #sendDataToArduino(Context context, String address, char flag, double[] data)} instead.</p>
618 *
619 * @param context the context
620 * @param pluginId you received this id when
621 * @param data your data you want to send
622 */
623 public static void sendDataFromPlugin(Context context, int pluginId, double[] data){
624 Intent intent = getPluginSendIntent(AmarinoIntent.DOUBLE_ARRAY_EXTRA, pluginId);
625 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
626 context.sendBroadcast(intent);
627 }
628
629 /**
630 * Used by plug-in developers to send a String array.
631 *
632 * <p>This method can only be used within a plugin!
633 * If you want to send data from your own standalone application, use
634 * {@link #sendDataToArduino(Context context, String address, char flag, String[] data)} instead.</p>
635 *
636 * @param context the context
637 * @param pluginId you received this id when
638 * @param data your data you want to send
639 */
640 public static void sendDataFromPlugin(Context context, int pluginId, String[] data){
641 Intent intent = getPluginSendIntent(AmarinoIntent.STRING_ARRAY_EXTRA, pluginId);
642 intent.putExtra(AmarinoIntent.EXTRA_DATA, data);
643 context.sendBroadcast(intent);
644 }
645
646
647 /**
648 * Convenient method to check if a given Bluetooth address is in proper format.
649 *
650 * <p>A correct Bluetooth address has 17 charaters and the following format: xx:xx:xx:xx:xx:xx</p>
651 *
652 * @param address the address to prove
653 * @return true if the address is in proper format, otherwise false
654 */
655 public static boolean isCorrectAddressFormat(String address){
656 if (address.length() != 17) return false;
657 // TODO use regular expression to check format needs more specific regex
658 return Pattern.matches("[[A-F][0-9][:]]+", address.toUpperCase());
659 }
660
661
662
663 private static Intent getPluginSendIntent(int dataType, int pluginId){
664 Intent intent = new Intent(AmarinoIntent.ACTION_SEND);
665 intent.putExtra(AmarinoIntent.EXTRA_DATA_TYPE, dataType);
666 intent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, pluginId);
667 return intent;
668 }
669
670 private static Intent getSendIntent(String address, int dataType, char flag){
671 Intent intent = new Intent(AmarinoIntent.ACTION_SEND);
672 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address);
673 intent.putExtra(AmarinoIntent.EXTRA_DATA_TYPE, dataType);
674 intent.putExtra(AmarinoIntent.EXTRA_FLAG, flag);
675 return intent;
676 }
677 }
+0
-356
at/abraxas/amarino/.svn/text-base/AmarinoDbAdapter.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import java.util.ArrayList;
21
22 import android.content.ContentValues;
23 import android.content.Context;
24 import android.database.Cursor;
25 import android.database.SQLException;
26 import android.database.sqlite.SQLiteDatabase;
27 import android.database.sqlite.SQLiteOpenHelper;
28 import android.util.Log;
29 import at.abraxas.amarino.log.Logger;
30
31 /**
32 * $Id: AmarinoDbAdapter.java 444 2010-06-10 13:11:59Z abraxas $
33 */
34 public class AmarinoDbAdapter {
35
36 public static final String KEY_DEVICE_ID = "_id";
37 public static final String KEY_DEVICE_NAME = "name";
38 public static final String KEY_DEVICE_ADDRESS = "device_address";
39
40 public static final String KEY_EVENT_ID = "_id";
41 public static final String KEY_EVENT_NAME = "event_name";
42 public static final String KEY_EVENT_DESC = "desc";
43 public static final String KEY_EVENT_VISUALIZER = "visualizer";
44 public static final String KEY_EVENT_VISUALIZER_MIN = "minVal";
45 public static final String KEY_EVENT_VISUALIZER_MAX = "maxVal";
46 public static final String KEY_EVENT_FLAG = "flag";
47 public static final String KEY_EVENT_PACKAGE_NAME = "package";
48 public static final String KEY_EVENT_EDIT_CLASS_NAME = "edit_class";
49 public static final String KEY_EVENT_SERVICE_CLASS_NAME = "service_class";
50 public static final String KEY_EVENT_PLUGIN_ID = "plugin_id";
51 public static final String KEY_EVENT_DEVICE_ID = "device_id";
52
53 private static final boolean DEBUG = true;
54 private static final String TAG = "AmarinoDbAdapter";
55 private static final int DATABASE_VERSION = 2;
56
57 private static final String DATABASE_NAME = "amarino_2.db";
58 private static final String DEVICE_TABLE_NAME = "devices_tbl";
59 private static final String EVENT_TABLE_NAME = "events_tbl";
60
61
62 private DatabaseHelper mDbHelper;
63 private SQLiteDatabase mDb;
64 private final Context mCtx;
65
66
67 private static class DatabaseHelper extends SQLiteOpenHelper {
68
69 DatabaseHelper(Context context) {
70 super(context, DATABASE_NAME, null, DATABASE_VERSION);
71 }
72
73 @Override
74 public void onCreate(SQLiteDatabase db) {
75 Log.d(TAG, "create database tables");
76 /* Create Devices Table */
77 db.execSQL("CREATE TABLE " + DEVICE_TABLE_NAME + " ("
78 + KEY_DEVICE_ID + " INTEGER PRIMARY KEY,"
79 + KEY_DEVICE_ADDRESS + " TEXT UNIQUE,"
80 + KEY_DEVICE_NAME + " TEXT"
81 + ");");
82
83 db.execSQL("CREATE TABLE " + EVENT_TABLE_NAME + " ("
84 + KEY_EVENT_ID + " INTEGER PRIMARY KEY,"
85 + KEY_EVENT_NAME + " TEXT NOT NULL,"
86 + KEY_EVENT_DESC + " TEXT,"
87 + KEY_EVENT_VISUALIZER + " INTEGER,"
88 + KEY_EVENT_VISUALIZER_MIN + " NUMBER,"
89 + KEY_EVENT_VISUALIZER_MAX + " NUMBER,"
90 + KEY_EVENT_FLAG + " INTEGER NOT NULL,"
91 + KEY_EVENT_PACKAGE_NAME + " TEXT NOT NULL,"
92 + KEY_EVENT_EDIT_CLASS_NAME + " TEXT NOT NULL,"
93 + KEY_EVENT_SERVICE_CLASS_NAME + " TEXT NOT NULL,"
94 + KEY_EVENT_PLUGIN_ID + " INTEGER NOT NULL,"
95 + KEY_EVENT_DEVICE_ID + " INTEGER REFERENCES " + DEVICE_TABLE_NAME + "(_id) "
96 + ");");
97
98 }
99
100 @Override
101 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
102 Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
103 + newVersion + ", which will destroy all old data");
104
105 db.execSQL("DROP TABLE IF EXISTS " + DEVICE_TABLE_NAME);
106 db.execSQL("DROP TABLE IF EXISTS " + EVENT_TABLE_NAME);
107 onCreate(db);
108 Log.d(TAG, "upgrade db");
109 }
110
111 }
112
113 /**
114 * Constructor - takes the context to allow the database to be
115 * opened/created
116 *
117 * @param ctx the Context within which to work
118 */
119 public AmarinoDbAdapter(Context ctx) {
120 this.mCtx = ctx;
121 }
122
123 /**
124 * Open the database. If it cannot be opened, try to create a new
125 * instance of the database. If it cannot be created, throw an exception to
126 * signal the failure
127 *
128 * @return this (self reference, allowing this to be chained in an
129 * initialization call)
130 * @throws SQLException if the database could be neither opened or created
131 */
132 public AmarinoDbAdapter open() throws SQLException {
133 mDbHelper = new DatabaseHelper(mCtx);
134 mDb = mDbHelper.getWritableDatabase();
135 return this;
136 }
137
138 public void close() {
139 mDbHelper.close();
140 }
141
142
143 /**
144 * Create a new device using the address and name provided. If the device is
145 * successfully created return the new rowId for that device, otherwise return
146 * a -1 to indicate failure.
147 *
148 * @param address the address of the device
149 * @param name the name of the device
150 * @return rowId or -1 if failed
151 */
152 public long createDevice(BTDevice device) {
153 ContentValues initialValues = new ContentValues();
154 initialValues.put(KEY_DEVICE_ADDRESS, device.address);
155 initialValues.put(KEY_DEVICE_NAME, (device.name == null) ? "NONAME" : device.name);
156
157 return mDb.insert(DEVICE_TABLE_NAME, null, initialValues);
158 }
159
160 /**
161 * Delete the device with the given rowId
162 *
163 * @param rowId id of device to delete
164 * @return true if deleted, false otherwise
165 */
166 public boolean deleteDevice(long deviceId) {
167 int numEvents = deleteEvents(deviceId);
168 if (DEBUG) Logger.d(TAG, "delete device with id " + deviceId + ": " + numEvents + " associated events removed");
169 return mDb.delete(DEVICE_TABLE_NAME, KEY_DEVICE_ID + "=" + deviceId, null) > 0;
170 }
171
172 public BTDevice getDevice(String address){
173 BTDevice device = null;
174 Cursor c = mDb.query(DEVICE_TABLE_NAME, null, KEY_DEVICE_ADDRESS + " like ?", new String[]{address}, null, null, null);
175
176 if (c == null){
177 return null;
178 }
179 if (c.moveToFirst()){
180 String name = c.getString(c.getColumnIndex(KEY_DEVICE_NAME));
181 long id = c.getLong(c.getColumnIndex(KEY_DEVICE_ID));
182 device = new BTDevice(id, address, name);
183 }
184 c.close();
185 return device;
186 }
187
188
189 /**
190 * Return a list of all devices in the database
191 *
192 * @return ArrayList over all devices
193 */
194 public ArrayList<BTDevice> fetchAllDevices() {
195 ArrayList<BTDevice> devices = new ArrayList<BTDevice>();
196
197 Cursor c = mDb.query(DEVICE_TABLE_NAME, null, null, null, null, null, null);
198
199 if (c == null){
200 return devices;
201 }
202 if (c.moveToFirst()){
203 do {
204 String address = c.getString(c.getColumnIndex(KEY_DEVICE_ADDRESS));
205 String name = c.getString(c.getColumnIndex(KEY_DEVICE_NAME));
206 long id = c.getLong(c.getColumnIndex(KEY_DEVICE_ID));
207 devices.add(new BTDevice(id, address, name));
208 }
209 while(c.moveToNext());
210 }
211
212 c.close();
213 return devices;
214 }
215
216
217 /**
218 * Create a new event associated with a specific device. If the event is
219 * successfully created return the new rowId for that event, otherwise return
220 * a -1 to indicate failure.
221 *
222 * @param address the address of the device
223 * @param name the name of the device
224 * @return rowId or -1 if failed
225 */
226 public long createEvent(Event event) {
227 ContentValues initialValues = new ContentValues();
228 initialValues.put(KEY_EVENT_NAME, event.name);
229 initialValues.put(KEY_EVENT_DESC, event.desc);
230 initialValues.put(KEY_EVENT_VISUALIZER, event.visualizer);
231 initialValues.put(KEY_EVENT_VISUALIZER_MIN, event.visualizerMinValue);
232 initialValues.put(KEY_EVENT_VISUALIZER_MAX, event.visualizerMaxValue);
233 initialValues.put(KEY_EVENT_FLAG, (int)event.flag);
234 initialValues.put(KEY_EVENT_PACKAGE_NAME, event.packageName);
235 initialValues.put(KEY_EVENT_EDIT_CLASS_NAME, event.editClassName);
236 initialValues.put(KEY_EVENT_SERVICE_CLASS_NAME, event.serviceClassName);
237 initialValues.put(KEY_EVENT_PLUGIN_ID, event.pluginId);
238 initialValues.put(KEY_EVENT_DEVICE_ID, event.deviceId);
239
240 return mDb.insert(EVENT_TABLE_NAME, null, initialValues);
241 }
242
243
244 /**
245 * Delete the event with the given rowId
246 *
247 * @param rowId id of event to delete
248 * @return true if deleted, false otherwise
249 */
250 public boolean deleteEvent(long rowId) {
251 return mDb.delete(EVENT_TABLE_NAME, KEY_EVENT_ID + "=" + rowId, null) > 0;
252 }
253
254 /**
255 * Delete all events associated to the given device
256 * @param deviceId
257 * @return
258 */
259 public int deleteEvents(long deviceId){
260 return mDb.delete(EVENT_TABLE_NAME, KEY_EVENT_DEVICE_ID + "=" + deviceId, null);
261 }
262
263 public Event getEvent(long deviceId, int pluginId){
264 Event e = null;
265 Cursor c = mDb.query(EVENT_TABLE_NAME, null,
266 KEY_EVENT_DEVICE_ID + "=? AND " + KEY_EVENT_PLUGIN_ID + "=?",
267 new String[]{String.valueOf(deviceId), String.valueOf(pluginId)}, null, null, null);
268
269 if (c == null){
270 if (DEBUG) Logger.d(TAG, "no event found for device with id: " + deviceId + " and pluginId:" + pluginId);
271 return null;
272 }
273 if (c.moveToFirst()){
274 long id = c.getLong(c.getColumnIndex(KEY_EVENT_ID));
275 String name = c.getString(c.getColumnIndex(KEY_EVENT_NAME));
276 String desc = c.getString(c.getColumnIndex(KEY_EVENT_DESC));
277 int visualizer = c.getInt(c.getColumnIndex(KEY_EVENT_VISUALIZER));
278 float minVal = c.getFloat(c.getColumnIndex(KEY_EVENT_VISUALIZER_MIN));
279 float maxVal = c.getFloat(c.getColumnIndex(KEY_EVENT_VISUALIZER_MAX));
280 char flag = (char) c.getInt(c.getColumnIndex(KEY_EVENT_FLAG));
281 String packageName= c.getString(c.getColumnIndex(KEY_EVENT_PACKAGE_NAME));
282 String editClassName= c.getString(c.getColumnIndex(KEY_EVENT_EDIT_CLASS_NAME));
283 String serviceClassName= c.getString(c.getColumnIndex(KEY_EVENT_SERVICE_CLASS_NAME));
284
285 e = new Event(id, name, desc, visualizer, flag, packageName, editClassName,
286 serviceClassName, pluginId, deviceId);
287 e.visualizerMinValue = minVal;
288 e.visualizerMaxValue = maxVal;
289 }
290
291 c.close();
292 return e;
293 }
294
295 /**
296 * Return a list of all events for a given device
297 *
298 * @return ArrayList of all events for the given device
299 */
300 public ArrayList<Event> fetchEvents(long deviceId) {
301 ArrayList<Event> events = new ArrayList<Event>();
302
303 Cursor c = mDb.query(EVENT_TABLE_NAME, null, KEY_EVENT_DEVICE_ID + "=" + deviceId ,
304 null, null, null, null);
305
306 if (c == null){
307 if (DEBUG) Logger.d(TAG, "no events found for device with id: " + deviceId);
308 return events;
309 }
310 if (c.moveToFirst()){
311 do {
312 long id = c.getLong(c.getColumnIndex(KEY_EVENT_ID));
313 String name = c.getString(c.getColumnIndex(KEY_EVENT_NAME));
314 String desc = c.getString(c.getColumnIndex(KEY_EVENT_DESC));
315 int visualizer = c.getInt(c.getColumnIndex(KEY_EVENT_VISUALIZER));
316 float minVal = c.getFloat(c.getColumnIndex(KEY_EVENT_VISUALIZER_MIN));
317 float maxVal = c.getFloat(c.getColumnIndex(KEY_EVENT_VISUALIZER_MAX));
318 char flag = (char) c.getInt(c.getColumnIndex(KEY_EVENT_FLAG));
319 String packageName= c.getString(c.getColumnIndex(KEY_EVENT_PACKAGE_NAME));
320 String editClassName= c.getString(c.getColumnIndex(KEY_EVENT_EDIT_CLASS_NAME));
321 String serviceClassName= c.getString(c.getColumnIndex(KEY_EVENT_SERVICE_CLASS_NAME));
322 int pluginId = c.getInt(c.getColumnIndex(KEY_EVENT_PLUGIN_ID));
323
324 Event e = new Event(id, name, desc, visualizer, flag, packageName, editClassName,
325 serviceClassName, pluginId, deviceId);
326 e.visualizerMinValue = minVal;
327 e.visualizerMaxValue = maxVal;
328
329 events.add(e);
330 if (DEBUG) Logger.d(TAG, "event found: " + e.name + " - id=" + e.pluginId);
331 }
332 while(c.moveToNext());
333 }
334 else {
335 if (DEBUG) Logger.d(TAG, "no events found for device with id: " + deviceId);
336 }
337
338 c.close();
339 return events;
340 }
341
342
343 public int updateEvent(Event event){
344 ContentValues values = new ContentValues();
345
346 values.put(KEY_EVENT_VISUALIZER, event.visualizer);
347 values.put(KEY_EVENT_VISUALIZER_MIN, event.visualizerMinValue);
348 values.put(KEY_EVENT_VISUALIZER_MAX, event.visualizerMaxValue);
349
350 return mDb.update(EVENT_TABLE_NAME, values, KEY_EVENT_ID + "=" + event.id, null);
351 }
352
353
354
355 }
+0
-533
at/abraxas/amarino/.svn/text-base/AmarinoIntent.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 /**
21 * AmarinoIntent is a collection of Intents and Extras used by Amarino to
22 * perform actions. You can either use these intents directly or you can use the
23 * convenient functions in {@link at.abraxas.amarino.Amarino} to communicate
24 * with Amarino. The way your application communicates with Amarino happens
25 * exclusively via Intents. For more information about Intents in general please
26 * refer to the <a
27 * href="http://developer.android.com/reference/android/content/Intent.html"
28 * >Android Reference</a> and learn everything about Intents.
29 *
30 * <p>
31 * The most important intents in Amarino are:
32 * </p>
33 *
34 * <ul>
35 * <li>{@link #ACTION_CONNECT} - connect to a Bluetooth device</li>
36 * <li>{@link #ACTION_DISCONNECT} - disconnect from a Bluetooth device</li>
37 * <li>{@link #ACTION_SEND} - send data to Arduino</li>
38 * <li>{@link #ACTION_RECEIVED} - received data from Arduino</li>
39 * </ul>
40 *
41 * <p>
42 * The {@link #ACTION_CONNECT}, {@link #ACTION_DISCONNECT} and
43 * {@link #ACTION_SEND} intents are supposed to be broadcasted by your
44 * application in order to use Amarino to fulfill your request.
45 * {@link #ACTION_RECEIVED} however is used the other way around. Amarino will
46 * broadcast this intent if it has received new data from Arduino. If you want
47 * to receive these data, your application has to implement a <a href=
48 * "http://developer.android.com/reference/android/content/BroadcastReceiver.html"
49 * >BroadcastReceiver</a> catching the {@link #ACTION_RECEIVED} intent.</br>
50 * SensorGraph is a neat example demonstrating the use of
51 * {@link #ACTION_CONNECT}, {@link #ACTION_DISCONNECT} and
52 * {@link #ACTION_RECEIVED}.
53 *
54 * <h3>Intents broadcasted by Amarino for feedback</h3>
55 * <p>
56 * Sometimes it is important to have feedback if an operation was successful or
57 * not. Amarino normally provides feedback by broadcasting intents with detailed
58 * information. We already have heart about {@link #ACTION_RECEIVED} which is
59 * indeed also a feedback intent.
60 * </p>
61 * <p>
62 * Feedback intents are:
63 * </p>
64 *
65 * <ul>
66 * <li>{@link #ACTION_RECEIVED} - Amarino received data from Arduino</li>
67 * <li>{@link #ACTION_CONNECTED} - connection has been established</li>
68 * <li>{@link #ACTION_DISCONNECTED} - disconnected from a device</li>
69 * <li>{@link #ACTION_CONNECTION_FAILED} - connection attempt was not successful
70 * </li>
71 * <li>{@link #ACTION_PAIRING_REQUESTED} - a notification message to pair the
72 * device has popped up</li>
73 * <li>{@link #ACTION_CONNECTED_DEVICES} - the list of connected devices is
74 * broadcasted after a request was made using
75 * {@link #ACTION_GET_CONNECTED_DEVICES}</li>
76 * </ul>
77 *
78 * <p>
79 * To receive feedback your have to register a <a href=
80 * "http://developer.android.com/reference/android/content/BroadcastReceiver.html"
81 * >BroadcastReceiver</a> for information you are interested in.
82 * </p>
83 *
84 * <p>
85 *
86 * @author Bonifaz Kaufmann
87 * </p>
88 * $Id: AmarinoIntent.java 444 2010-06-10 13:11:59Z abraxas $
89 */
90 public interface AmarinoIntent {
91
92 /**
93 * Activity Action: Tell <i>Amarino</i> to connect to a device
94 * <p>
95 * Input:
96 * <em>{@link at.abraxas.amarino.AmarinoIntent#EXTRA_DEVICE_ADDRESS}</em> -
97 * The address of the device <i>Amarino</i> should connect to.
98 * </p>
99 * <p>
100 * Output: one of the following actions will be broadcasted
101 * </p>
102 * <ul>
103 * <li><em>{@link #ACTION_CONNECTED}</em></li>
104 * <li><em>{@link #ACTION_DISCONNECTED}</em></li>
105 * <li><em>{@link #ACTION_CONNECTION_FAILED}</em></li>
106 * <li><em>{@link #ACTION_PAIRING_REQUESTED}</em></li>
107 * </ul>
108 *
109 * <p>
110 * Example
111 * </p>
112 *
113 * <pre>
114 * Intent intent = new Intent(AmarinoIntent.ACTION_CONNECT);
115 * intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, DEVICE_ADDRESS);
116 * sendBroadcast(intent);
117 * </pre>
118 */
119 public static final String ACTION_CONNECT = "amarino.intent.action.CONNECT";
120
121 /**
122 * Activity Action: Tell <i>Amarino</i> to disconnect from a device
123 * <p>
124 * Input: <em>{@link #EXTRA_DEVICE_ADDRESS}</em> - The address of the device
125 * <i>Amarino</i> should disconnect from.
126 * </p>
127 * <p>
128 * Output: the following action will be broadcasted
129 * </p>
130 * <ul>
131 * <li><em>{@link #ACTION_DISCONNECTED}</em></li>
132 * </ul>
133 *
134 * <p>
135 * Example
136 * </p>
137 *
138 * <pre>
139 * Intent intent = new Intent(AmarinoIntent.ACTION_DISCONNECT);
140 * intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, DEVICE_ADDRESS);
141 * sendBroadcast(intent);
142 * </pre>
143 */
144 public static final String ACTION_DISCONNECT = "amarino.intent.action.DISCONNECT";
145
146 /**
147 * Activity Action: Tell <i>Amarino</i> to send data to Arduino
148 * <p>
149 * Input: following EXTRAS must be within your intent
150 * </p>
151 * <ul>
152 * <li><em>{@link #EXTRA_DEVICE_ADDRESS}</em> - The address of the device
153 * <i>Amarino</i> should send data to</li>
154 * <li><em>{@link #EXTRA_DATA_TYPE}</em> - The type of data shipped with
155 * this intent</li>
156 * <li><em>{@link #EXTRA_DATA}</em> - The actual data you want to send. Be
157 * sure the format of that data matches the data type you specified in
158 * EXTRA_DATA_TYPE</li>
159 * <li><em>{@link #EXTRA_FLAG}</em> - The flag to which the data correspond
160 * to. If EXTRA_FLAG is not set, 'a' will be used by default.</li>
161 * </ul>
162 *
163 * <p>
164 * Apart from <em>{@link #EXTRA_FLAG}</em> all EXTRAS are mandatory,
165 * otherwise <i>Amarino</i> will not forward your data to Arduino.
166 * </p>
167 *
168 * <p>
169 * Output: Amarino forwards the data to the given address if the device is
170 * connected
171 * </p>
172 */
173 public static final String ACTION_SEND = "amarino.intent.action.SEND";
174
175 /**
176 * Broadcast Action sent by <i>Amarino</i>: <i>Amarino</i> broadcasts any
177 * received data from Arduino so that your application can receive them.
178 *
179 * <p>
180 * The Intent will have the following EXTRAS:
181 * </p>
182 * <ul>
183 * <li><em>{@link #EXTRA_DEVICE_ADDRESS}</em></li>
184 * <li><em>{@link #EXTRA_DATA_TYPE}</em></li>
185 * <li><em>{@link #EXTRA_DATA}</em></li>
186 * </ul>
187 *
188 * <p>
189 * <b>Example</b>
190 * </p>
191 *
192 * <pre>
193 *
194 * public class YourReceiver extends BroadcastReceiver {
195 *
196 * &#064;Override
197 * public void onReceive(Context context, Intent intent) {
198 * String data = null;
199 * final String address = intent.getStringExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS);
200 * final int dataType = intent.getIntExtra(AmarinoIntent.EXTRA_DATA_TYPE, -1);
201 *
202 * if (dataType == AmarinoIntent.STRING_EXTRA) {
203 * data = intent.getStringExtra(AmarinoIntent.EXTRA_DATA);
204 *
205 * if (data != null) {
206 * // do whatever you want to do with the data
207 * mValueTV.setText(data);
208 * }
209 * }
210 * }
211 * }
212 *
213 *</pre>
214 */
215 public static final String ACTION_RECEIVED = "amarino.intent.action.RECEIVED";
216
217 /**
218 * Broadcast Action sent by <i>Amarino</i>: A connection to a device has
219 * been established
220 *
221 * <p>
222 * The Intent will have the following extra value:
223 * <ul>
224 * <li><em>{@link #EXTRA_DEVICE_ADDRESS}</em> - the address of the connected
225 * device.</li>
226 * </ul>
227 * </p>
228 */
229 public static final String ACTION_CONNECTED = "amarino.intent.action.CONNECTED";
230
231 /**
232 * Broadcast Action sent by <i>Amarino</i>: The connection to a device has
233 * been disconnected
234 *
235 * <p>
236 * The Intent will have the following extra value:
237 * <ul>
238 * <li><em>{@link #EXTRA_DEVICE_ADDRESS}</em> - the address of the
239 * disconnected device.</li>
240 * </ul>
241 * </p>
242 */
243 public static final String ACTION_DISCONNECTED = "amarino.intent.action.DISCONNECTED";
244
245 /**
246 * Broadcast Action sent by <i>Amarino</i>: A connection attempt to a device
247 * was not successful
248 *
249 * <p>
250 * The Intent will have the following extra value:
251 * <ul>
252 * <li><em>{@link #EXTRA_DEVICE_ADDRESS}</em> - the address of the device
253 * which could not be connected</li>
254 * </ul>
255 * <p>
256 * There are many reasons why this might happen.
257 * </p>
258 * <ul>
259 * <li>Check if your Bluetooth module on your Arduino is powered and
260 * properly connected</li>
261 * <li>Due to an unexpected state either Bluetooth device might be in an
262 * undefined state, reset your Bluetooth adapters.</li>
263 * <li>Check the log of your phone using adb to gain more information why
264 * the connection cannot be established.</li>
265 * </ul>
266 * </p>
267 */
268 public static final String ACTION_CONNECTION_FAILED = "amarino.intent.action.CONNECTION_FAILED";
269
270 /**
271 * Broadcast Action sent by <i>Amarino</i>: Indicates that a pairing request
272 * has been started.
273 *
274 * <p>
275 * This action goes along with a pairing request notification in your status
276 * bar.
277 * </p>
278 */
279 public static final String ACTION_PAIRING_REQUESTED = "amarino.intent.action.PAIRING_REQUESTED";
280
281 /**
282 * Activity Action: Request the connected devices list from <i>Amarino</i>
283 * <p>
284 * Input: nothing
285 * </p>
286 * <p>
287 * Output: <i>Amarino</i> will broadcast the result as
288 * <em>{@link #ACTION_CONNECTED_DEVICES}</em>
289 * </p>
290 *
291 * <p>
292 * When you request the connected devices list you should always have a
293 * BroadcastReceiver ready to receive the result from <i>Amarino</i>
294 * </p>
295 */
296 public static final String ACTION_GET_CONNECTED_DEVICES = "amarino.intent.action.ACTION_GET_CONNECTED_DEVICES";
297
298 /**
299 * Broadcast Action sent by <i>Amarino</i>: The list of currently connected
300 * devices
301 *
302 * <p>
303 * The Intent will have the following extra value:
304 * </p>
305 * <ul>
306 * <li><em>{@link #EXTRA_CONNECTED_DEVICES}</em></li>
307 * </ul>
308 *
309 * <p>
310 * This action is only broadcasted if you have requested the list of device
311 * before by sending {@link #ACTION_GET_CONNECTED_DEVICES}
312 * </p>
313 */
314 public static final String ACTION_CONNECTED_DEVICES = "amarino.intent.action.ACTION_CONNECTED_DEVICES";
315
316 /**
317 * used to enaable a specific plug-in, needs EXTRA_PLUGIN_ID to be set
318 */
319
320 public static final String ACTION_ENABLE = "amarino.intent.action.ENABLE";
321
322 /**
323 * used to disable a specific plug-in, needs EXTRA_PLUGIN_ID to be set
324 */
325 public static final String ACTION_DISABLE = "amarino.intent.action.DISABLE";
326
327 /**
328 * disables all plug-ins if there is no active connection
329 */
330 static final String ACTION_DISABLE_ALL = "amarino.intent.action.DISABLE_ALL";
331
332 /**
333 * calls the edit activity of a plug-in
334 */
335 public static final String ACTION_EDIT_PLUGIN = "amarino.intent.action.EDIT_PLUGIN";
336
337 /**
338 * Type: BTDevice
339 */
340 static final String EXTRA_DEVICE = "amarino.intent.extra.DEVICE";
341
342 /**
343 * Type: String
344 *
345 * <pre>
346 * e.g. "00:06:54:4B:31:7E"
347 * </pre>
348 */
349 public static final String EXTRA_DEVICE_ADDRESS = "amarino.intent.extra.DEVICE_ADDRESS";
350
351 /**
352 * Type: String[] - an array containing the addresses of all connected
353 * devices
354 */
355 public static final String EXTRA_CONNECTED_DEVICE_ADDRESSES = "amarino.intent.extra.CONNECTED_DEVICE_ADDRESSES";
356
357 /**
358 * Type: int
359 * <p>
360 * either <em>{@link #CONNECTED}</em>, <em>{@link #DISCONNECTED}</em> or
361 * <em>{@link #CONNECTING}</em>
362 * </p>
363 *
364 */
365 public static final String EXTRA_DEVICE_STATE = "amarino.intent.extra.DEVICE_STATE";
366
367 /**
368 * Describes the state in {@link #EXTRA_DEVICE_STATE}
369 */
370 public static final int CONNECTED = 1001;
371
372 /**
373 * Describes the state in {@link #EXTRA_DEVICE_STATE}
374 */
375 public static final int DISCONNECTED = 1002;
376
377 /**
378 * Describes the state in {@link #EXTRA_DEVICE_STATE}
379 */
380 public static final int CONNECTING = 1003;
381
382 /**
383 * Type: char
384 * <p>
385 * the flag is the identifier for your data used by Arduino to determine
386 * which function to call. Relates to
387 *
388 * <pre>
389 * registerFunction(flag, functionPointer);
390 * </pre>
391 *
392 * in your Arduino sketch.
393 * </p>
394 */
395 public static final String EXTRA_FLAG = "amarino.intent.extra.FLAG";
396
397 /**
398 * <p>the type of data attached to an intent</p>
399 *
400 * <p>
401 * You have to pass in the type of extra you going to send;
402 * for example: BOOLEAN_EXTRA, BYTE_EXTRA, STRING_EXTRA, INTEGER_EXTRA, etc.
403 * </p>
404 */
405 public static final String EXTRA_DATA_TYPE = "amarino.intent.extra.DATA_TYPE";
406 /**
407 * boolean in Android is in Arduino 0=false, 1=true
408 */
409 public static final int BOOLEAN_EXTRA = 1;
410 public static final int BOOLEAN_ARRAY_EXTRA = 2;
411 /**
412 * byte is byte. In Arduino a byte stores an 8-bit unsigned number, from 0
413 * to 255.
414 */
415 public static final int BYTE_EXTRA = 3;
416 public static final int BYTE_ARRAY_EXTRA = 4;
417 /**
418 * char is char. In Arduino stored in 1 byte of memory
419 */
420 public static final int CHAR_EXTRA = 5;
421 public static final int CHAR_ARRAY_EXTRA = 6;
422 /**
423 * double is too large for Arduinos, better not to use this datatype
424 */
425 public static final int DOUBLE_EXTRA = 7;
426 public static final int DOUBLE_ARRAY_EXTRA = 8;
427 /**
428 * float in Android is float in Arduino (4 bytes)
429 */
430 public static final int FLOAT_EXTRA = 9;
431 public static final int FLOAT_ARRAY_EXTRA = 10;
432 /**
433 * int in Android is long in Arduino (4 bytes)
434 */
435 public static final int INT_EXTRA = 11;
436 public static final int INT_ARRAY_EXTRA = 12;
437 /**
438 * long in Android does not fit in Arduino data types, better not to use it
439 */
440 public static final int LONG_EXTRA = 13;
441 public static final int LONG_ARRAY_EXTRA = 14;
442 /**
443 * short in Android is like int in Arduino (2 bytes) 2^15
444 */
445 public static final int SHORT_EXTRA = 15;
446 public static final int SHORT_ARRAY_EXTRA = 16;
447 /**
448 * String in Android is char[] in Arduino
449 */
450 public static final int STRING_EXTRA = 17;
451 public static final int STRING_ARRAY_EXTRA = 18;
452
453 /**
454 * Type: depends on EXTRA_DATA_TYPE
455 */
456 public static final String EXTRA_DATA = "amarino.intent.extra.DATA";
457
458 /**
459 * Type: Integer - the id of your plug-in given to your EditActivity when it
460 * is called
461 */
462 public static final String EXTRA_PLUGIN_ID = "amarino.intent.extra.PLUGIN_ID";
463
464 /**
465 * Type: String - the name of your plug-in which is displayed to the user
466 */
467 public static final String EXTRA_PLUGIN_NAME = "amarino.intent.extra.PLUGIN_NAME";
468
469 /**
470 * Type: String - the description what your plug-in does
471 */
472 public static final String EXTRA_PLUGIN_DESC = "amarino.intent.extra.PLUGIN_DESC";
473
474 /**
475 * Type: String - the name of your plug-in service class (fully qualified)
476 * e.g. at.abraxas.amarino.plugins.compass.BackgroundService
477 */
478 public static final String EXTRA_PLUGIN_SERVICE_CLASS_NAME = "amarino.intent.extra.PLUGIN_CLASS_NAME";
479
480 /**
481 * Type: Integer - the type of visualizer you want to use to show data sent
482 * by a plug-in
483 * <p>
484 * must be one of
485 * </p>
486 * <ul>
487 * <li><em>{@link #VISUALIZER_TEXT}</em></li>
488 * <li><em>{@link #VISUALIZER_BARS}</em></li>
489 * <li><em>{@link #VISUALIZER_GRAPH}</em></li>
490 * </ul>
491 */
492 public static final String EXTRA_PLUGIN_VISUALIZER = "amarino.intent.extra.PLUGIN_VISUALIZER";
493
494 /**
495 * Displays the data coming from a plug-in as text
496 */
497 public static final int VISUALIZER_TEXT = 100;
498
499 /**
500 * Displays the data coming from a plug-in using bars.
501 *
502 * <i>Upper and lower bounds need to be specified when this visualizer is used.</i>
503 */
504 public static final int VISUALIZER_BARS = 101;
505
506 /**
507 * Displays the data coming from a plug-in within a graph.
508 *
509 * <i>Upper and lower bounds need to be specified when this visualizer is used.</i>
510 */
511 public static final int VISUALIZER_GRAPH = 102;
512
513 /**
514 * Type: Float - the minimum value to be expected
515 * <p>
516 * when using a graphical visualizer (em>{@link #VISUALIZER_BARS}</em> or
517 * em>{@link #VISUALIZER_GRAPH}</em>) this value must be set to initialize
518 * the visualizer
519 * </p>
520 */
521 public static final String EXTRA_VISUALIZER_MIN_VALUE = "amarino.intent.extra.VISUALIZER_MIN_VALUE";
522
523 /**
524 * Type: Float - the maximum value to be expected
525 * <p>
526 * when using a graphical visualizer this value must be set to initialize
527 * the visualizer
528 * </p>
529 */
530 public static final String EXTRA_VISUALIZER_MAX_VALUE = "amarino.intent.extra.VISUALIZER_MAX_VALUE";
531
532 }
+0
-774
at/abraxas/amarino/.svn/text-base/AmarinoService.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import it.gerdavax.easybluetooth.BtSocket;
21 import it.gerdavax.easybluetooth.LocalDevice;
22 import it.gerdavax.easybluetooth.ReadyListener;
23 import it.gerdavax.easybluetooth.RemoteDevice;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.UnsupportedEncodingException;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.Set;
36 import java.util.UUID;
37
38 import android.app.Notification;
39 import android.app.NotificationManager;
40 import android.app.PendingIntent;
41 import android.app.Service;
42 import android.content.BroadcastReceiver;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.IntentFilter;
46 import android.os.Binder;
47 import android.os.IBinder;
48 import android.util.Log;
49 import at.abraxas.amarino.log.Logger;
50
51 /**
52 * $Id: AmarinoService.java 444 2010-06-10 13:11:59Z abraxas $
53 */
54 public class AmarinoService extends Service {
55
56 private static final int NOTIFY_ID = 119561;
57 private static final String TAG = "AmarinoService";
58
59 private static final int BUSY = 1;
60 private static final int ACTIVE_CONNECTIONS = 2;
61 private static final int NO_CONNECTIONS = 3;
62
63 private final IBinder binder = new AmarinoServiceBinder();
64
65 private LocalDevice localDevice;
66 private PendingIntent launchIntent;
67 private Notification notification;
68 private NotificationManager notifyManager;
69 private AmarinoDbAdapter db;
70
71 /* most ppl will only use one Bluetooth device, thus lets start with capacity 1, <address, running thread> */
72 private HashMap<String, ConnectedThread> connections = new HashMap<String, ConnectedThread>(1);
73
74 /* need to know which plugin has been activated for which device, <pluginId, list of devices> */
75 private HashMap<Integer, List<BTDevice>> enabledEvents = new HashMap<Integer, List<BTDevice>>();
76
77 private int serviceState = NO_CONNECTIONS;
78
79
80
81 @Override
82 public void onCreate() {
83 Logger.d(TAG, "Background service created");
84 super.onCreate();
85
86 db = new AmarinoDbAdapter(this);
87
88 initNotificationManager();
89
90 // initialize reflection methods for backward compatibility of start and stopForeground
91 try {
92 mStartForeground = getClass().getMethod("startForeground",
93 mStartForegroundSignature);
94 mStopForeground = getClass().getMethod("stopForeground",
95 mStopForegroundSignature);
96 } catch (NoSuchMethodException e) {
97 // Running on an older platform.
98 mStartForeground = mStopForeground = null;
99 }
100
101 IntentFilter filter = new IntentFilter(AmarinoIntent.ACTION_SEND);
102 registerReceiver(receiver, filter);
103 }
104
105
106
107 @Override
108 public void onStart(Intent intent, int startId) {
109 handleStart(intent, startId);
110 }
111
112 @Override
113 public int onStartCommand(Intent intent, int flags, int startId) {
114 return handleStart(intent, startId);
115 }
116
117 private int handleStart(Intent intent, int startId){
118 //Logger.d(TAG, "onStart");
119 super.onStart(intent, startId);
120
121 if (intent == null) {
122 // here we might restore our state if we got killed by the system
123 // TODO
124 return START_STICKY;
125 }
126
127 String action = intent.getAction();
128 if (action == null) return START_STICKY;
129
130 // someone wants to send data to arduino
131 if (action.equals(AmarinoIntent.ACTION_SEND)){
132 forwardDataToArduino(intent);
133 return START_NOT_STICKY;
134 }
135
136 // publish the state of devices
137 if (action.equals(AmarinoIntent.ACTION_GET_CONNECTED_DEVICES)){
138 broadcastConnectedDevicesList();
139 return START_NOT_STICKY;
140 }
141
142 // this intent is used to surely disable all plug-ins
143 // if a user forgot to call force disable after force enable was called
144 if (action.equals(AmarinoIntent.ACTION_DISABLE_ALL)){
145 if (serviceState == NO_CONNECTIONS) {
146 disableAllPlugins();
147 stopSelf();
148 }
149 return START_NOT_STICKY;
150 }
151
152 /* --- CONNECT and DISCONNECT part --- */
153 String address = intent.getStringExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS);
154 if (address == null) {
155 Logger.d(TAG, "EXTRA_DEVICE_ADDRESS not found!");
156 return START_NOT_STICKY;
157 }
158
159 // connect and disconnect operations may take some time
160 // we don't want to shutdown our service while it does some work
161 serviceState = BUSY;
162
163 if (!Amarino.isCorrectAddressFormat(address)) {
164 Logger.d(TAG, getString(R.string.service_address_invalid, address));
165 sendConnectionFailed(address);
166 shutdownServiceIfNecessary();
167 }
168 else {
169 if (AmarinoIntent.ACTION_CONNECT.equals(action)){
170 Logger.d(TAG, "ACTION_CONNECT request received");
171 connect(address);
172 }
173 else if (AmarinoIntent.ACTION_DISCONNECT.equals(action)){
174 Logger.d(TAG, "ACTION_DISCONNECT request received");
175 disconnect(address);
176 }
177 }
178
179 return START_STICKY;
180 }
181
182
183 private void forwardDataToArduino(Intent intent){
184
185 final int pluginId = intent.getIntExtra(AmarinoIntent.EXTRA_PLUGIN_ID, -1);
186 // Log.d(TAG, "send from pluginID: " + pluginId);
187 if (pluginId == -1) {
188 // intent sent from another app which is not a plugin
189 final String address = intent.getStringExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS);
190 if (address == null) {
191 Logger.d(TAG, "Data not sent! EXTRA_DEVICE_ADDRESS not set.");
192 return;
193 }
194
195 String message = MessageBuilder.getMessage(intent);
196 if (message == null) return;
197
198 // cutoff leading flag and ACK_FLAG for logger
199 Logger.d(TAG, getString(R.string.service_message_to_send, message.substring(1, message.length()-1)));
200
201 try {
202 sendData(address, message.getBytes("ISO-8859-1"));
203 } catch (UnsupportedEncodingException e) {
204 // use default encoding as fallback alternative if encoding ISO 8859-1 is not possible
205 Logger.d(TAG, "Encoding message using ISO-8859-1 not possible");
206 sendData(address, message.getBytes());
207 }
208 }
209 else {
210 List<BTDevice> devices = enabledEvents.get(pluginId);
211
212 if (devices != null && devices.size() != 0){
213 for (BTDevice device : devices){
214 // we have to put the flag into the intent in order to fulfill the message builder requirements
215 intent.putExtra(AmarinoIntent.EXTRA_FLAG, device.events.get(pluginId).flag);
216 //Log.d(TAG, "flag" + device.events.get(pluginId).flag);
217
218 String message = MessageBuilder.getMessage(intent);
219 if (message == null) return;
220
221 Logger.d(TAG, getString(R.string.service_message_to_send, message.substring(1, message.length()-1)));
222
223 sendData(device.getAddress(), message.getBytes());
224 }
225 }
226 else {
227 Logger.d(TAG, "No device associated with plugin: " + pluginId);
228 }
229 }
230 }
231
232
233
234 @Override
235 public void onDestroy() {
236 super.onDestroy();
237 Logger.d(TAG, "Background service stopped");
238
239 // we do only stop our service if no connections are active, however Android may kill our service without warning
240 // clean up in case service gets killed from the system due to low memory condition
241 if (serviceState == ACTIVE_CONNECTIONS){
242 // TODO save which connections are active for recreating later when service is restarted
243
244 disableAllPlugins();
245 for (ConnectedThread t : connections.values()){
246 t.cancel();
247 }
248 }
249 unregisterReceiver(receiver);
250 cancelNotification();
251
252 }
253
254 private void shutdownService(boolean disablePlugins){
255 if (disablePlugins)
256 disableAllPlugins();
257 if (serviceState == NO_CONNECTIONS){
258 notifyManager.notify(NOTIFY_ID,
259 getNotification(getString(R.string.service_no_active_connections)));
260 Logger.d(TAG, getString(R.string.service_ready_to_shutdown));
261 stopSelf();
262 }
263 }
264
265 private void shutdownServiceIfNecessary() {
266 if (connections.size() == 0){
267 serviceState = NO_CONNECTIONS;
268 shutdownService(false);
269 }
270 else {
271 serviceState = ACTIVE_CONNECTIONS;
272 notifyManager.notify(NOTIFY_ID,
273 getNotification(getString(R.string.service_active_connections, connections.size())));
274 }
275 }
276
277
278 protected void connect(final String address){
279 if (address == null) return;
280 localDevice = LocalDevice.getInstance();
281 localDevice.init(this, new ReadyListener() {
282 @Override
283 public void ready() {
284 RemoteDevice device = localDevice.getRemoteForAddr(address);
285 localDevice.destroy();
286 new ConnectThread(device).start();
287 }
288 });
289
290 }
291
292 public void disconnect(final String address){
293 informPlugins(address, false);
294
295 ConnectedThread ct = connections.remove(address);
296 if (ct != null)
297 ct.cancel();
298
299 // end service if this was the last connection to disconnect
300 if (connections.size()==0){
301 serviceState = NO_CONNECTIONS;
302 shutdownService(true);
303 }
304 else {
305 serviceState = ACTIVE_CONNECTIONS;
306 notifyManager.notify(NOTIFY_ID,
307 getNotification(getString(R.string.service_active_connections, connections.size())));
308 }
309 }
310
311 public void sendData(final String address, byte[] data){
312 ConnectedThread ct = connections.get(address);
313 if (ct != null)
314 ct.write(data);
315 }
316
317
318
319 private void informPlugins(String address, boolean enable){
320 db.open();
321 BTDevice device = db.getDevice(address);
322
323 if (device != null){
324 ArrayList<Event> events = db.fetchEvents(device.id);
325 device.events = new HashMap<Integer, Event>();
326
327 for (Event e : events){
328 if (enable) {
329 // remember which plugin was started for which device address
330 List<BTDevice> devices = enabledEvents.get(e.pluginId);
331
332 if (devices == null) {
333 // plugin is not active
334 devices = new LinkedList<BTDevice>();
335 devices.add(device);
336 enabledEvents.put(e.pluginId, devices);
337 }
338 else {
339 // plugin already active, just add the new address
340 devices.add(device);
341 }
342 // add to our fast HashMap for later use when sending data we need fast retrival of pluginId->flag
343 device.events.put(e.pluginId, e);
344 // start plugin no matter if it was active or not, plugins must be able to handle consecutive start calls
345 informPlugIn(e, address, true);
346 }
347 else {
348 // only if this is the last device with a certain event attached, disable the plugin
349 List<BTDevice> devices = enabledEvents.get(e.pluginId);
350 if (devices != null) {
351 if (devices.remove(device)){
352 // address found and removed
353 if (devices.size()==0){
354 enabledEvents.remove(e.pluginId);
355 // was the last device which used this plugin, thus disable the plugin now
356 informPlugIn(e, address, false);
357 }
358 }
359 }
360 else {
361 Logger.d(TAG, "disable requested for Plugin " + e.name + " detected, but was never enabled");
362 // should not happen, but maybe disconnect was called without ever connecting before
363 informPlugIn(e, address, false);
364 }
365 // normally it shouldn't be any event with this id in device's events map, but we double check
366 device.events.remove(e.pluginId);
367 }
368 }
369 }
370 db.close();
371 }
372
373 private void informPlugIn(Event e, String address, boolean enable){
374 Logger.d(TAG, (enable ? getString(R.string.enable) : getString(R.string.disable)) + " " + e.name);
375 Intent intent;
376 if (enable)
377 intent = new Intent(AmarinoIntent.ACTION_ENABLE);
378 else
379 intent = new Intent(AmarinoIntent.ACTION_DISABLE);
380
381 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address);
382 intent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, e.pluginId);
383 intent.putExtra(AmarinoIntent.EXTRA_PLUGIN_SERVICE_CLASS_NAME, e.serviceClassName);
384
385 intent.setPackage(e.packageName);
386 sendBroadcast(intent);
387 }
388
389 private void disableAllPlugins(){
390 Intent intent = new Intent(AmarinoIntent.ACTION_DISABLE);
391 sendBroadcast(intent);
392 }
393
394 private void broadcastConnectedDevicesList() {
395 Intent returnIntent = new Intent(AmarinoIntent.ACTION_CONNECTED_DEVICES);
396 if (connections.size() == 0){
397 sendBroadcast(returnIntent);
398 shutdownService(false);
399 return;
400 }
401 Set<String> addresses = connections.keySet();
402 String[] result = new String[addresses.size()];
403 result = addresses.toArray(result);
404 returnIntent.putExtra(AmarinoIntent.EXTRA_CONNECTED_DEVICE_ADDRESSES, result);
405 sendBroadcast(returnIntent);
406 }
407
408 private void sendConnectionDisconnected(String address){
409 String info = getString(R.string.service_disconnected_from, address);
410 Logger.d(TAG, info);
411 notifyManager.notify(NOTIFY_ID, getNotification(info));
412
413 sendBroadcast(new Intent(AmarinoIntent.ACTION_DISCONNECTED)
414 .putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address));
415
416 broadcastConnectedDevicesList();
417 }
418
419 private void sendConnectionFailed(String address){
420 String info = getString(R.string.service_connection_to_failed, address);
421 Logger.d(TAG, info);
422 notifyManager.notify(NOTIFY_ID, getNotification(info));
423
424 sendBroadcast(new Intent(AmarinoIntent.ACTION_CONNECTION_FAILED)
425 .putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address));
426 }
427
428 private void sendPairingRequested(String address){
429 Logger.d(TAG, getString(R.string.service_pairing_request, address));
430 sendBroadcast(new Intent(AmarinoIntent.ACTION_PAIRING_REQUESTED)
431 .putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address));
432 }
433
434 private void sendConnectionEstablished(String address){
435 String info = getString(R.string.service_connected_to, address);
436 Logger.d(TAG, info);
437
438 sendBroadcast(new Intent(AmarinoIntent.ACTION_CONNECTED)
439 .putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, address));
440
441 broadcastConnectedDevicesList();
442
443 startForegroundCompat(NOTIFY_ID,
444 getNotification(getString(R.string.service_active_connections, connections.size())));
445
446
447 }
448
449
450 /* ---------- Binder ---------- */
451
452 @Override
453 public IBinder onBind(Intent intent) {
454 return binder;
455 }
456
457 public class AmarinoServiceBinder extends Binder {
458 AmarinoService getService() {
459 return AmarinoService.this;
460 }
461 }
462
463
464
465 /* ---------- Notification ---------- */
466
467 private void initNotificationManager() {
468 notifyManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
469
470 launchIntent = PendingIntent.getActivity(AmarinoService.this, 0,
471 new Intent(AmarinoService.this, MainScreen.class)
472 .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
473 }
474
475 private Notification getNotification(String title) {
476 notification = new Notification(R.drawable.icon_small, title, System.currentTimeMillis());
477 notification.flags |= Notification.FLAG_ONGOING_EVENT;
478 notification.flags |= Notification.FLAG_NO_CLEAR;
479 notification.setLatestEventInfo(this, title, getString(R.string.service_notify_text), launchIntent);
480 return notification;
481 }
482
483 private void cancelNotification(){
484 notifyManager.cancel(NOTIFY_ID);
485 }
486
487
488 /* ---------- Connection Threads ---------- */
489
490 /**
491 * ConnectThread tries to establish a connection and starts the communication thread
492 */
493 private class ConnectThread extends Thread {
494
495 //private static final String TAG = "ConnectThread";
496 private final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
497
498 private final RemoteDevice mDevice;
499 private BtSocket mSocket;
500
501 public ConnectThread(RemoteDevice device) {
502 mDevice = device;
503 }
504
505 public void run() {
506 try {
507 String info = getString(R.string.service_connecting_to, mDevice.getAddress());
508 Logger.d(TAG, info);
509 notifyManager.notify(NOTIFY_ID, getNotification(info));
510
511 boolean isPaired = false;
512
513 try {
514 isPaired = mDevice.ensurePaired();
515 }
516 catch (RuntimeException re){
517 re.printStackTrace();
518 }
519
520 if (!isPaired){
521 //Log.d(TAG, "not paired!");
522 sendPairingRequested(mDevice.getAddress());
523 shutdownServiceIfNecessary();
524 }
525 else {
526 //Log.d(TAG, "is paired!");
527 // Let main thread do some stuff to render UI immediately
528 Thread.yield();
529 // Get a BluetoothSocket to connect with the given BluetoothDevice
530 try {
531 mSocket = mDevice.openSocket(SPP_UUID);
532 } catch (Exception e) {
533 Logger.d(TAG, "Connection via SDP unsuccessful, try to connect via port directly");
534 // 1.x Android devices only work this way since SDP was not part of their firmware then
535 mSocket = mDevice.openSocket(1);
536 }
537
538 // Do work to manage the connection (in a separate thread)
539 manageConnectedSocket(mSocket);
540 }
541 }
542
543 catch (Exception e) {
544 sendConnectionFailed(mDevice.getAddress());
545 e.printStackTrace();
546 if (mSocket != null)
547 try {
548 mSocket.close();
549 } catch (IOException e1) {}
550 shutdownServiceIfNecessary();
551 return;
552 }
553 }
554
555 /** Will cancel an in-progress connection, and close the socket */
556 @SuppressWarnings("unused")
557 public void cancel() {
558 try {
559 if (mSocket != null) mSocket.close();
560 sendConnectionDisconnected(mDevice.getAddress());
561 }
562 catch (IOException e) { Log.e(TAG, "cannot close socket to " + mDevice.getAddress()); }
563 }
564
565 private void manageConnectedSocket(BtSocket socket){
566 Logger.d(TAG, "connection established.");
567 // pass the socket to a worker thread
568 String address = mDevice.getAddress();
569 ConnectedThread t = new ConnectedThread(socket, address);
570 connections.put(address, t);
571 t.start();
572
573 serviceState = ACTIVE_CONNECTIONS;
574
575 // now it is time to enable the plug-ins so that they can use our socket
576 informPlugins(address, true);
577 }
578 }
579
580 /**
581 * ConnectedThread is holding the socket for communication with a Bluetooth device
582 */
583 private class ConnectedThread extends Thread {
584 private final BtSocket mSocket;
585 private final InputStream mInStream;
586 private final OutputStream mOutStream;
587 private final String mAddress;
588 private StringBuffer forwardBuffer = new StringBuffer();
589
590 public ConnectedThread(BtSocket socket, String address) {
591 mSocket = socket;
592 this.mAddress = address;
593 InputStream tmpIn = null;
594 OutputStream tmpOut = null;
595
596 // Get the input and output streams, using temp objects because
597 // member streams are final
598 try {
599 tmpIn = socket.getInputStream();
600 tmpOut = socket.getOutputStream();
601 } catch (Exception e) { }
602
603 mInStream = tmpIn;
604 mOutStream = tmpOut;
605 }
606
607 public void run() {
608
609 byte[] buffer = new byte[1024]; // buffer store for the stream
610 int bytes = 0; // bytes returned from read()
611 String msg;
612
613 sendConnectionEstablished(mAddress);
614
615 // Keep listening to the InputStream until an exception occurs
616 while (true) {
617 try {
618 // Read from the InputStream
619 bytes = mInStream.read(buffer);
620
621 // Send the obtained bytes to the UI Activity
622 msg = new String(buffer, 0, (bytes != -1) ? bytes : 0 );
623 //Log.d(TAG, msg); // raw data with control flags
624
625 forwardData(msg);
626
627 } catch (IOException e) {
628 Logger.d(TAG, "communication to " + mAddress + " halted");
629 break;
630 }
631 }
632 }
633
634 private void forwardData(String data){
635 char c;
636 for (int i=0;i<data.length();i++){
637 c = data.charAt(i);
638 if (c == MessageBuilder.ARDUINO_MSG_FLAG){
639 // TODO this could be used to determine the data type
640 // if (i+1<data.length()){
641 // int dataType = data.charAt(i+1);
642 // i++;
643 // depending on the dataType we could convert the following data appropriately
644 // }
645 // else {
646 // // wait for the next char to be sent
647 // }
648 }
649 else if (c == MessageBuilder.ACK_FLAG){
650 // message complete send the data
651 forwardDataToOtherApps(forwardBuffer.toString());
652 forwardBuffer = new StringBuffer();
653 }
654 else {
655 forwardBuffer.append(c);
656 }
657 }
658 }
659
660 private void forwardDataToOtherApps(String msg){
661 Logger.d(TAG, "Arduino says: " + msg);
662 Intent intent = new Intent(AmarinoIntent.ACTION_RECEIVED);
663 intent.putExtra(AmarinoIntent.EXTRA_DATA, msg);
664 intent.putExtra(AmarinoIntent.EXTRA_DATA_TYPE, AmarinoIntent.STRING_EXTRA);
665 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, mAddress);
666 sendBroadcast(intent);
667 }
668
669 /* Call this from the main Activity to send data to the remote device */
670 public void write(byte[] bytes) {
671 try {
672 mOutStream.write(bytes);
673 Logger.d(TAG, "send to Arduino: " + new String(bytes));
674 } catch (IOException e) { }
675 }
676
677 /* Call this from the main Activity to shutdown the connection */
678 public void cancel() {
679 try {
680 mSocket.close();
681 sendConnectionDisconnected(mAddress);
682 } catch (IOException e) { Log.e(TAG, "cannot close socket to " + mAddress); }
683 }
684 }
685
686
687
688 /* ---------- BroadcastReceiver ---------- */
689
690 BroadcastReceiver receiver = new BroadcastReceiver() {
691
692 @Override
693 public void onReceive(Context context, Intent intent) {
694 final String action = intent.getAction();
695 if (action == null) return;
696 //Log.d(TAG, action);
697
698 if (AmarinoIntent.ACTION_SEND.equals(action)){
699 intent.setClass(context, AmarinoService.class);
700 startService(intent);
701 }
702 }
703 };
704
705
706
707 /* ---------- use setForeground() but be also backward compatible ---------- */
708
709 @SuppressWarnings("unchecked")
710 private static final Class[] mStartForegroundSignature = new Class[] {
711 int.class, Notification.class};
712 @SuppressWarnings("unchecked")
713 private static final Class[] mStopForegroundSignature = new Class[] {
714 boolean.class};
715
716 private Method mStartForeground;
717 private Method mStopForeground;
718 private Object[] mStartForegroundArgs = new Object[2];
719 private Object[] mStopForegroundArgs = new Object[1];
720
721
722 /**
723 * This is a wrapper around the new startForeground method, using the older
724 * APIs if it is not available.
725 */
726 void startForegroundCompat(int id, Notification notification) {
727 // If we have the new startForeground API, then use it.
728 if (mStartForeground != null) {
729 mStartForegroundArgs[0] = Integer.valueOf(id);
730 mStartForegroundArgs[1] = notification;
731 try {
732 mStartForeground.invoke(this, mStartForegroundArgs);
733 } catch (InvocationTargetException e) {
734 // Should not happen.
735 Log.w("MyApp", "Unable to invoke startForeground", e);
736 } catch (IllegalAccessException e) {
737 // Should not happen.
738 Log.w("MyApp", "Unable to invoke startForeground", e);
739 }
740 return;
741 }
742
743 // Fall back on the old API.
744 setForeground(true);
745 notifyManager.notify(id, notification);
746 }
747
748 /**
749 * This is a wrapper around the new stopForeground method, using the older
750 * APIs if it is not available.
751 */
752 void stopForegroundCompat(int id) {
753 // If we have the new stopForeground API, then use it.
754 if (mStopForeground != null) {
755 mStopForegroundArgs[0] = Boolean.TRUE;
756 try {
757 mStopForeground.invoke(this, mStopForegroundArgs);
758 } catch (InvocationTargetException e) {
759 // Should not happen.
760 Log.w("MyApp", "Unable to invoke stopForeground", e);
761 } catch (IllegalAccessException e) {
762 // Should not happen.
763 Log.w("MyApp", "Unable to invoke stopForeground", e);
764 }
765 return;
766 }
767
768 // Fall back on the old API. Note to cancel BEFORE changing the
769 // foreground state, since we could be killed at that point.
770 cancelNotification();
771 setForeground(false);
772 }
773 }
+0
-100
at/abraxas/amarino/.svn/text-base/BTDevice.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import it.gerdavax.easybluetooth.RemoteDevice;
21
22 import java.io.Serializable;
23 import java.util.HashMap;
24
25
26 /**
27 * $Id: BTDevice.java 444 2010-06-10 13:11:59Z abraxas $
28 */
29 public class BTDevice implements Serializable {
30
31 private static final long serialVersionUID = -6041931825295548358L;
32
33 long id = -1;
34 String address;
35 String name;
36 int state = AmarinoIntent.DISCONNECTED;
37 // <pluginID, event>
38 HashMap<Integer, Event> events;
39
40 public BTDevice(String address){
41 this.address = address;
42 }
43
44 public BTDevice(long id, String address, String name){
45 this.id = id;
46 this.address = address;
47 this.name = name;
48 }
49
50 public BTDevice(RemoteDevice rd){
51 this.address = rd.getAddress();
52 this.name = rd.getFriendlyName();
53 }
54
55 public String getAddress(){
56 return this.address;
57 }
58
59 public String getName(){
60 return this.name;
61 }
62
63 public boolean equals(Object o){
64 if (this == o)
65 return true;
66
67 if (o == null || (o.getClass() != this.getClass()))
68 return false;
69
70 BTDevice other = (BTDevice)o;
71 if (this.id == other.id && this.id != -1) {
72 return true;
73 }
74 if (this.address.equals(other.address)){
75 return true;
76 }
77 return false;
78 }
79
80 public BTDevice clone(){
81 BTDevice device = new BTDevice(this.id, this.address, this.name);
82 device.state = this.state;
83 return device;
84 }
85
86 @Override
87 public int hashCode() {
88 int hash = 7;
89 for (int i=0;i<address.length();i++)
90 hash += address.charAt(i);
91 return hash;
92 }
93
94 @Override
95 public String toString() {
96 return address + " - " + name;
97 }
98
99 }
+0
-186
at/abraxas/amarino/.svn/text-base/DeviceDiscovery.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import it.gerdavax.easybluetooth.LocalDevice;
21 import it.gerdavax.easybluetooth.ReadyListener;
22 import it.gerdavax.easybluetooth.RemoteDevice;
23 import it.gerdavax.easybluetooth.ScanListener;
24
25 import java.util.Vector;
26
27 import android.app.ListActivity;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.os.Bundle;
31 import android.util.Log;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.ViewGroup;
35 import android.view.Window;
36 import android.widget.BaseAdapter;
37 import android.widget.LinearLayout;
38 import android.widget.ListView;
39 import android.widget.TextView;
40
41 /**
42 * This ListActivity initiates a Bluetooth device discovery
43 * and shows a list of all discovered devices.
44 *
45 *
46 * Call this Activity using startActivityForResult,
47 * and it will returns the selected device address.
48 * Attached to the intent as an extra called ADDRESS_EXTRA.
49 *
50 * @author Bonifaz Kaufmann
51 *
52 * $Id: DeviceDiscovery.java 444 2010-06-10 13:11:59Z abraxas $
53 *
54 */
55 public class DeviceDiscovery extends ListActivity {
56
57 protected static String ADDRESS_EXTRA = "device_address";
58
59 @SuppressWarnings("unused")
60 private static final String TAG = "DeviceDiscovery";
61
62 private DeviceAdapter adapter;
63 private LocalDevice localDevice;
64
65 @Override
66 protected void onCreate(Bundle savedInstanceState) {
67 super.onCreate(savedInstanceState);
68 setTitle("Discovered Devices");
69 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
70 setContentView(R.layout.discovered_devices_list);
71
72 adapter = new DeviceAdapter();
73 setListAdapter(adapter);
74
75 setProgressBarIndeterminateVisibility(true);
76 localDevice = LocalDevice.getInstance();
77 }
78
79 @Override
80 protected void onStart() {
81 super.onStart();
82
83 localDevice.init(this, new ReadyListener(){
84
85 @Override
86 public void ready() {
87 localDevice.scan(new ScanListener(){
88
89 @Override
90 public void deviceFound(RemoteDevice device) {
91
92 synchronized(adapter.discoveredDevices){
93 Vector<RemoteDevice> addedDevices = adapter.discoveredDevices;
94 for (RemoteDevice rd : addedDevices){
95 if (rd.getAddress().equals(device.getAddress())){
96 Log.d(TAG, "device already in list -> renew");
97 adapter.discoveredDevices.remove(rd);
98 }
99 }
100 adapter.discoveredDevices.add(device);
101 }
102 adapter.notifyDataSetChanged();
103 }
104
105 @Override
106 public void scanCompleted() {
107 setProgressBarIndeterminateVisibility(false);
108 }
109 });
110 } // end ready()
111 });
112
113 }
114
115
116 @Override
117 protected void onStop() {
118 super.onStop();
119 // TODO change source of AndroidBluetoothLibrary to fix the bug
120 // this might run in an exception, because of a race condition
121 // see issue 22 at http://code.google.com/p/android-bluetooth/issues/detail?id=22
122 localDevice.destroy();
123 }
124
125
126 @Override
127 protected void onListItemClick(ListView lv, View view, int position, long id) {
128 super.onListItemClick(lv, view, position, id);
129 // since user selected already a device we do not need to scan for more devices
130 localDevice.stopScan();
131
132 final String address = ((RemoteDevice)adapter.getItem(position)).getAddress();
133 Intent i = new Intent();
134 i.putExtra(ADDRESS_EXTRA, address);
135 setResult(RESULT_OK, i);
136 finish();
137 }
138
139
140 private class DeviceAdapter extends BaseAdapter {
141
142 Vector<RemoteDevice> discoveredDevices = new Vector<RemoteDevice>();
143
144 public int getCount() {
145 if (discoveredDevices != null) {
146 return discoveredDevices.size();
147 }
148 return 0;
149 }
150
151 public Object getItem(int position) {
152 return discoveredDevices.get(position);
153 }
154
155 public long getItemId(int position) {
156 return 0;
157 }
158
159 public View getView(int position, View convertView, ViewGroup parent) {
160 LinearLayout view = null;
161
162 if (convertView == null) {
163 view = new LinearLayout(DeviceDiscovery.this);
164 String inflater = Context.LAYOUT_INFLATER_SERVICE;
165 LayoutInflater vi = (LayoutInflater) DeviceDiscovery.this.getSystemService(inflater);
166 vi.inflate(R.layout.discovered_devices_list_item, view, true);
167 } else {
168 view = (LinearLayout) convertView;
169 }
170
171 TextView addressTextView = (TextView) view.findViewById(R.id.device_address);
172 TextView nameTextView = (TextView) view.findViewById(R.id.device_name);
173
174 RemoteDevice device = discoveredDevices.get(position);
175 String address = device.getAddress();
176 String name = device.getFriendlyName();
177
178 addressTextView.setText(address);
179 nameTextView.setText((name==null) ? "NONAME" : name);
180
181 return view;
182 }
183 }
184
185 }
+0
-90
at/abraxas/amarino/.svn/text-base/Event.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 /**
21 * $Id: Event.java 444 2010-06-10 13:11:59Z abraxas $
22 */
23 public class Event {
24
25 public long id;
26 public String name;
27 public String desc;
28 public char flag;
29 public int visualizer;
30 public String packageName;
31 public String serviceClassName;
32 public String editClassName;
33 public int pluginId;
34 public long deviceId;
35 public String address;
36 public float visualizerMinValue = 0f;
37 public float visualizerMaxValue = 1024f;
38
39
40 public Event(String name, String desc, int visualizer, char flag,
41 String packageName, String editClassName, String serviceClassName, int pluginId, long deviceId){
42 this.flag = flag;
43 this.name = name;
44 this.desc = desc;
45 this.visualizer = visualizer;
46 this.packageName = packageName;
47 this.serviceClassName = serviceClassName;
48 this.editClassName = editClassName;
49 this.pluginId = pluginId;
50 this.deviceId = deviceId;
51 }
52
53 public Event(long id, String name, String desc, int visualizer, char flag,
54 String packageName, String editClassName, String serviceClassName, int pluginId, long deviceId){
55
56 this(name, desc, visualizer, flag, packageName, editClassName, serviceClassName, pluginId, deviceId);
57 this.id = id;
58 }
59
60 @Override
61 public boolean equals(Object o){
62 if (this == o)
63 return true;
64
65 if (o == null || (o.getClass() != this.getClass()))
66 return false;
67
68 Event e = (Event) o;
69 if (e.pluginId == this.pluginId && e.name.equals(this.name))
70 return true;
71 else
72 return false;
73 }
74
75 @Override
76 public int hashCode(){
77 return pluginId;
78 }
79
80 public String toString(){
81 return "Name: " + name +
82 "\nPackage: " + packageName +
83 "\nFlag: " + flag +
84 "\nId: " + pluginId +
85 "\ndeviceId: " + deviceId +
86 "\nVisualizer: " + visualizer;
87 }
88
89 }
+0
-637
at/abraxas/amarino/.svn/text-base/EventListActivity.java.svn-base less more
0 /*
1 Amarino - A prototyping software toolkit for Android and Arduino
2 Copyright (c) 2010 Bonifaz Kaufmann. All right reserved.
3
4 This application and its library is free software; you can redistribute
5 it and/or modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package at.abraxas.amarino;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import android.app.AlertDialog;
24 import android.app.ListActivity;
25 import android.content.BroadcastReceiver;
26 import android.content.Context;
27 import android.content.DialogInterface;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.content.pm.PackageManager;
31 import android.content.pm.ResolveInfo;
32 import android.os.Bundle;
33 import android.os.Handler;
34 import android.os.Message;
35 import android.util.Log;
36 import android.view.ContextMenu;
37 import android.view.Menu;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.view.ContextMenu.ContextMenuInfo;
41 import android.widget.AdapterView;
42 import android.widget.ListView;
43 import android.widget.TextView;
44 import android.widget.Toast;
45 import at.abraxas.amarino.log.Logger;
46 import at.abraxas.amarino.visualizer.Visualizer;
47
48 /**
49 *
50 * @author Bonifaz Kaufmann
51 *
52 * $Id: EventListActivity.java 444 2010-06-10 13:11:59Z abraxas $
53 */
54 public class EventListActivity extends ListActivity {
55
56 private static final boolean DEBUG = true;
57 private static final String TAG = "EventListActivity";
58 private static final int REQUEST_CREATE_EVENT = 1;
59 private static final int REQUEST_UPDATE_EVENT = 2;
60
61 private static final int MENU_ITEM_REMOVE_DEVICE = 1;
62 private static final int MENU_ITEM_ENABLE = 2;
63 private static final int MENU_ITEM_DISABLE = 3;
64
65 private static final int MENU_ITEM_REMOVE_ALL = 10;
66 private static final int MENU_ITEM_DISABLE_ALL = 11;
67
68 BTDevice device;
69 EventListAdapter eventListAdapter;
70 PlugInListAdapter pluginListAdapter;
71 AmarinoDbAdapter db;
72
73 Plugin selectedPlugin;
74
75 @Override
76 protected void onCreate(Bundle savedInstanceState) {
77 super.onCreate(savedInstanceState);
78 setContentView(R.layout.event_list);
79
80 db = new AmarinoDbAdapter(this);
81
82 Intent intent = getIntent();
83 if (intent != null){
84 device = (BTDevice) intent.getSerializableExtra(AmarinoIntent.EXTRA_DEVICE);
85 if (device == null) {
86 // there is something wrong, should never happen
87 }
88 setTitle(device.name + " - " + device.address);
89 }
90
91 buildPluginList();
92
93 ArrayList<Event> events = new ArrayList<Event>();
94 db.open();
95 events = db.fetchEvents(device.id);
96 Logger.d(TAG, "num of events: " + events.size());
97 db.close();
98 eventListAdapter = new EventListAdapter(this, events);
99 setListAdapter(eventListAdapter);
100
101 registerForContextMenu(getListView());
102 }
103
104
105 private void buildPluginList() {
106 PackageManager pm = this.getPackageManager();
107 List<ResolveInfo> editActivites = pm.queryIntentActivities(new Intent(AmarinoIntent.ACTION_EDIT_PLUGIN), 0);
108 Log.d(TAG, "Number of available plugins: " + editActivites.size());
109
110 ArrayList<Plugin> plugins = new ArrayList<Plugin>(editActivites.size());
111 for (ResolveInfo ri : editActivites){
112 Plugin p = new Plugin();
113 p.label = ri.loadLabel(pm).toString();
114 p.icon = ri.loadIcon(pm);
115 p.packageName = ri.activityInfo.packageName;
116 p.editClassName = ri.activityInfo.name;
117 plugins.add(p);
118 if (DEBUG) Log.d(TAG, p.toString());
119 }
120 pluginListAdapter = new PlugInListAdapter(this, plugins);
121 }
122
123 @Override
124 protected void onStart() {
125 super.onStart();
126 IntentFilter filter = new IntentFilter(AmarinoIntent.ACTION_SEND);
127 registerReceiver(receiver, filter);
128 }
129
130 @Override
131 protected void onStop() {
132 super.onStop();
133 unregisterReceiver(receiver);
134 startService(new Intent(this, AmarinoService.class)
135 .setAction(AmarinoIntent.ACTION_DISABLE_ALL));
136 }
137
138
139 @Override
140 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
141 // Setup the menu header
142 AdapterView.AdapterContextMenuInfo info;
143 info = (AdapterView.AdapterContextMenuInfo) menuInfo;
144 menu.setHeaderTitle(eventListAdapter.entries.get(info.position).name);
145
146 menu.add(0, MENU_ITEM_REMOVE_DEVICE, 0, R.string.remove);
147 menu.add(0, MENU_ITEM_ENABLE, 0, R.string.force_enable);
148 menu.add(0, MENU_ITEM_DISABLE, 0, R.string.force_disable);
149 }
150
151 @Override
152 public boolean onContextItemSelected(MenuItem item) {
153 AdapterView.AdapterContextMenuInfo info;
154 info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
155 Event e = eventListAdapter.entries.get(info.position);
156 switch (item.getItemId()) {
157 case MENU_ITEM_REMOVE_DEVICE:
158 // TODO disable event if it is the last one standing
159 db.open();
160 db.deleteEvent(e.id);
161 eventListAdapter.entries = db.fetchEvents(device.id);
162 eventListAdapter.notifyDataSetChanged();
163 db.close();
164 return true;
165
166 case MENU_ITEM_ENABLE:
167 enablePlugin(e);
168 return true;
169
170 case MENU_ITEM_DISABLE:
171 disablePlugin(e);
172 return true;
173 }
174 return false;
175 }
176
177
178
179 @Override
180 public boolean onCreateOptionsMenu(Menu menu) {
181 menu.add(0, MENU_ITEM_REMOVE_ALL, 0, R.string.remove_all);
182 menu.add(0, MENU_ITEM_DISABLE_ALL, 0, R.string.force_disable_all);
183
184 return true;
185 }
186
187
188 @Override
189 public boolean onOptionsItemSelected(MenuItem item) {
190 switch (item.getItemId()){
191 case MENU_ITEM_REMOVE_ALL:
192 // TODO maybe dialog to ask if user is sure
193 // TODO disable event if it is the last one standing
194 db.open();
195 for (Event e : eventListAdapter.entries){
196 db.deleteEvent(e.id);
197 }
198 eventListAdapter.entries = db.fetchEvents(device.id);
199 eventListAdapter.notifyDataSetChanged();
200 db.close();
201 break;
202
203 case MENU_ITEM_DISABLE_ALL:
204 for (Event e : eventListAdapter.entries){
205 disablePlugin(e);
206 }
207 break;
208 }
209 return super.onOptionsItemSelected(item);
210 }
211
212
213 private void enablePlugin(Event e) {
214 Intent enableIntent = new Intent(AmarinoIntent.ACTION_ENABLE);
215 enableIntent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, device.address);
216 enableIntent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, e.pluginId);
217 enableIntent.putExtra(AmarinoIntent.EXTRA_PLUGIN_SERVICE_CLASS_NAME, e.serviceClassName);
218 enableIntent.setPackage(e.packageName);
219 sendBroadcast(enableIntent);
220 }
221
222
223 private void disablePlugin(Event e) {
224 Intent disableIntent = new Intent(AmarinoIntent.ACTION_DISABLE);
225 disableIntent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, device.address);
226 disableIntent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, e.pluginId);
227 disableIntent.putExtra(AmarinoIntent.EXTRA_PLUGIN_SERVICE_CLASS_NAME, e.serviceClassName);
228 disableIntent.setPackage(e.packageName);
229 sendBroadcast(disableIntent);
230 }
231
232
233
234 @Override
235 protected void onListItemClick(ListView l, View v, int position, long id) {
236 super.onListItemClick(l, v, position, id);
237 Event event = eventListAdapter.entries.get(position);
238
239 Intent intent = new Intent(AmarinoIntent.ACTION_EDIT_PLUGIN);
240 intent.setClassName(event.packageName, event.editClassName);
241 intent.putExtra(AmarinoIntent.EXTRA_FLAG, event.flag);
242 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, device.address);
243 intent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, event.pluginId);
244 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
245
246 startActivityForResult(intent, REQUEST_UPDATE_EVENT);
247 }
248
249 public void addEventBtnClick(View view){
250 if (pluginListAdapter.entries.size() == 0){
251 Toast.makeText(EventListActivity.this, R.string.no_plugins_installed, Toast.LENGTH_LONG).show();
252 }
253 else {
254 showPlugins();
255 }
256 }
257
258 private void showPlugins(){
259 new AlertDialog.Builder(EventListActivity.this)
260 .setTitle("Add Event")
261 .setIcon(R.drawable.icon_very_small)
262 .setAdapter(pluginListAdapter, new DialogInterface.OnClickListener() {
263 @Override
264 public void onClick(DialogInterface dialog, int which) {
265 // start EditActivity of selected plugin
266 selectedPlugin = pluginListAdapter.entries.get(which);
267 Intent intent = new Intent(AmarinoIntent.ACTION_EDIT_PLUGIN);
268 intent.setClassName(selectedPlugin.packageName, selectedPlugin.editClassName);
269
270 intent.putExtra(AmarinoIntent.EXTRA_FLAG, getNextFlag());
271 intent.putExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS, device.address);
272 intent.putExtra(AmarinoIntent.EXTRA_PLUGIN_ID, selectedPlugin.label.hashCode());
273
274 startActivityForResult(intent, REQUEST_CREATE_EVENT);
275 }
276 })
277 .create()
278 .show();
279
280 }
281
282 @Override
283 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
284 super.onActivityResult(requestCode, resultCode, data);
285
286 if (resultCode == RESULT_OK){
287 int visualizer;
288 int pluginId;
289 Event event;
290
291 db.open();
292
293 switch(requestCode){
294
295 case REQUEST_CREATE_EVENT:
296 // retrieve plugin infos and create new event element
297 if (data == null) return;
298
299 String name = data.getStringExtra(AmarinoIntent.EXTRA_PLUGIN_NAME);
300 String desc = data.getStringExtra(AmarinoIntent.EXTRA_PLUGIN_DESC);
301 String serviceClassName = data.getStringExtra(AmarinoIntent.EXTRA_PLUGIN_SERVICE_CLASS_NAME);
302 visualizer = data.getIntExtra(AmarinoIntent.EXTRA_PLUGIN_VISUALIZER, -1);
303 pluginId = data.getIntExtra(AmarinoIntent.EXTRA_PLUGIN_ID, -1);
304
305 event = new Event(name, desc, visualizer, getNextFlag(),
306 selectedPlugin.packageName, selectedPlugin.editClassName,
307 serviceClassName, pluginId, device.id);
308
309 if (visualizer == AmarinoIntent.VISUALIZER_GRAPH || visualizer == AmarinoIntent.VISUALIZER_BARS){
310 event.visualizerMinValue = data.getFloatExtra(AmarinoIntent.EXTRA_VISUALIZER_MIN_VALUE, 0f);
311 event.visualizerMaxValue = data.getFloatExtra(AmarinoIntent.EXTRA_VISUALIZER_MAX_VALUE, 1024f);
312 }
313
314 Logger.d(TAG, event.toString());
315
316 if (!eventListAdapter.entries.contains(event)){
317 event.id = db.createEvent(event);
318 if (event.id < 0)
319 Logger.d(TAG, "Error creating event in database");
320 else
321 Logger.d(TAG, "Event added to database");
322 }
323 else {
324 Logger.d(TAG, "duplicate entry: event is alreay in your list");
325 }
326
327 break;
328
329 case REQUEST_UPDATE_EVENT:
330 if (data == null) return;
331
332 pluginId = data.getIntExtra(AmarinoIntent.EXTRA_PLUGIN_ID, -1);
333 event = db.getEvent(device.id, pluginId);
334
335 if (event != null){
336 event.visualizer = data.getIntExtra(AmarinoIntent.EXTRA_PLUGIN_VISUALIZER, -1);
337 if (event.visualizer == AmarinoIntent.VISUALIZER_GRAPH || event.visualizer == AmarinoIntent.VISUALIZER_BARS){
338 event.visualizerMinValue = data.getFloatExtra(AmarinoIntent.EXTRA_VISUALIZER_MIN_VALUE, 0f);
339 event.visualizerMaxValue = data.getFloatExtra(AmarinoIntent.EXTRA_VISUALIZER_MAX_VALUE, 1024f);
340 }
341
342 int num = db.updateEvent(event);
343 Logger.d(TAG, num + " event updated." + event.toString());
344 }
345 else {
346 Log.d(TAG, "Could not update. Event not found in database");
347 }
348 break;
349 }
350
351 eventListAdapter.entries = db.fetchEvents(device.id);
352 eventListAdapter.notifyDataSetChanged();
353 db.close();
354 }
355 }
356
357 private char getNextFlag(){
358 boolean flagInUse = false;
359
360 // search for free capital letter
361 for (int i=0; i<26; i++){
362 flagInUse = false;
363 for (Event e : eventListAdapter.entries){
364 if (e.flag == (65+i)){
365 flagInUse = true;
366 break;
367 }
368 }
369 if (!flagInUse){
370 return (char) (65+i); // 65 = 'A'
371 }
372 }
373
374
375 // if still no flag found we use small letters, should be extremely rare
376 for (int i=0; i<26; i++){
377 for (Event e : eventListAdapter.entries){
378 flagInUse = false;
379 if (e.flag == (97+i)){