1 package ro
.ieval
.fonbot
;
3 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_count
;
4 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_interval
;
5 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_min_distance
;
6 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_min_time
;
7 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_port
;
8 import static ro
.ieval
.fonbot
.R
.string
.cannot_parse_provider_allowed_values_are
;
9 import static ro
.ieval
.fonbot
.R
.string
.command_disabled
;
10 import static ro
.ieval
.fonbot
.R
.string
.could_not_parse_argument_allowed_values_are
;
11 import static ro
.ieval
.fonbot
.R
.string
.could_not_parse_ms
;
12 import static ro
.ieval
.fonbot
.R
.string
.error_while_processing_command
;
13 import static ro
.ieval
.fonbot
.R
.string
.invalid_length_allowed_values_are
;
14 import static ro
.ieval
.fonbot
.R
.string
.invalid_ringer_mode_valid_values_are
;
15 import static ro
.ieval
.fonbot
.R
.string
.location_tracking_is_active
;
16 import static ro
.ieval
.fonbot
.R
.string
.messagetype_should_be_one_of
;
17 import static ro
.ieval
.fonbot
.R
.string
.no_such_command_command_list
;
18 import static ro
.ieval
.fonbot
.R
.string
.notification_disabled
;
19 import static ro
.ieval
.fonbot
.R
.string
.notification_enabled
;
20 import static ro
.ieval
.fonbot
.R
.string
.ringing
;
21 import static ro
.ieval
.fonbot
.R
.string
.security_exception
;
22 import static ro
.ieval
.fonbot
.R
.string
.the_polling_service_is_running
;
23 import static ro
.ieval
.fonbot
.R
.string
.the_second_argument_to_wipe_must_be
;
24 import static ro
.ieval
.fonbot
.R
.string
.unknown_command
;
25 import static ro
.ieval
.fonbot
.R
.string
.wipetype_should_be_one_of
;
27 import java
.util
.Arrays
;
28 import java
.util
.Locale
;
30 import org
.eclipse
.jdt
.annotation
.NonNull
;
31 import org
.eclipse
.jdt
.annotation
.Nullable
;
33 import ro
.ieval
.fonbot
.Address
.Protocol
;
34 import android
.content
.Context
;
35 import android
.content
.Intent
;
36 import android
.content
.SharedPreferences
;
37 import android
.database
.Cursor
;
38 import android
.location
.LocationManager
;
39 import android
.media
.AudioManager
;
40 import android
.net
.Uri
;
41 import android
.preference
.PreferenceManager
;
42 import android
.provider
.ContactsContract
.PhoneLookup
;
43 import android
.telephony
.SmsManager
;
44 import android
.util
.Log
;
45 import android
.widget
.Toast
;
48 * Copyright © 2013 Marius Gavrilescu
50 * This file is part of FonBot.
52 * FonBot is free software: you can redistribute it and/or modify
53 * it under the terms of the GNU General Public License as published by
54 * the Free Software Foundation, either version 3 of the License, or
55 * (at your option) any later version.
57 * FonBot is distributed in the hope that it will be useful,
58 * but WITHOUT ANY WARRANTY; without even the implied warranty of
59 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60 * GNU General Public License for more details.
62 * You should have received a copy of the GNU General Public License
63 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
67 * Utility functions and enums used in various places.
69 * @author Marius Gavrilescu <marius@ieval.ro>
71 public final class Utils
{
73 * Enum of all FonBot commands.
75 * @author Marius Gavrilescu <marius@ieval.ro>
77 @SuppressWarnings("javadoc")
78 public static enum Command
{
79 TOAST
, ECHO
, SMS
, FLASH
, WIFI
,
80 BLUETOOTH
, DIAL
, RING
, SPEAK
, VIBRATE
,
81 DIALOG
, LOCATION
, NOLOCATION
, RINGER
, NCFILE
,
82 PHOTO
, SETNOTIFICATION
, DELNOTIFICATION
, SETPASSWORD
, HELP
,
83 WIPE
, LOCK
, VIEW
, PLAY
, PAUSE
,
84 NEXT
, PREV
, BATT
, CALLLOG
, SMSLOG
,
85 LS
, RM
, CONTACTS
, DISABLE
, ENABLE
,
86 POLL
, HANGUP
, ANSWER
, LAUNCH
, DATA
,
87 GPS
, GLOCATION
, REBOOT
, SHUTDOWN
, NOTIFY
91 * Enum of all message types. Each message type is a kind of notification which can be enabled/disabled by the user and directed to a certain address.
93 * @author Marius Gavrilescu <marius@ieval.ro>
96 public static enum MessageType
{
97 /** SMS notifications */
99 /** Phone state (idle, offhook or ringing) notifications */
101 /** Lockscreen failed password notifications */
103 /** Device admin enable/disable notifications */
105 /** Coarse battery status (low battery, ok battery) notifications */
107 /** Fine battery status notifications */
109 /** Headset plug/unplug notifications */
114 * Enum of wipe types. The two defined types are the data wipe (which does not include the SD card) and the full wipe (which includes the SD card).
116 * @author Marius Gavrilescu <marius@ieval.ro>
118 public static enum WipeType
{
119 /** Factory reset the phone, without touching the SD card */
121 /** Factory reset the phone and wipe the SD card too */
126 * Enum of ringer modes.
128 * @author Marius Gavrilescu <marius@ieval.ro>
130 public static enum RingerMode
{
133 /** Sound is off, vibrate is on */
135 /** Sound is off, vibrate is off */
140 * Enum of location providers
142 * @author Marius Gavrilescu <marius@ieval.ro>
144 public static enum LocationProvider
{
145 /** The network location provider */
147 /** The GPS location provider */
152 * Enum of toast lengths.
154 * @author Marius Gavrilescu <marius@ieval.ro>
156 private static enum ToastLength
{
164 * Enum of the values on and off. Used for boolean arguments.
166 * @author Marius Gavrilescu <marius@ieval.ro>
168 @SuppressWarnings("javadoc")
169 private static enum OnOff
{
174 * Enum of ongoing event types
176 * @author Marius Gavrilescu <marius@ieval.ro>
178 public static enum OngoingEvent
{
179 /** Location tracking is active. Registered by {@link Command#LOCATION}, unregistered by {@link Command#NOLOCATION} */
180 LOCATION(location_tracking_is_active
),
181 /** The phone is ringing. Registered/unregistered by {@link Command#RING} */
183 /** The polling alarm is on. Registered/unregistered by {@link Command#POLL} */
184 POLL(the_polling_service_is_running
);
186 /** String resource: the event description */
187 public final int resource
;
190 * Constructs an OngoingEvent from its event description.
192 * @param resource the event description
194 private OngoingEvent(final int resource
) {
195 this.resource
=resource
;
199 /** Confirmation string for the {@link Command#WIPE WIPE} command. */
200 public static final String WIPE_CONFIRM_STRING
="I am aware this cannot be undone";
203 * Converts a Nullable object into a NonNull one.
205 * @param object the Nullable object to convert
206 * @return a NonNull object equivalent to the Nullable parameter
207 * @throws AssertionError if the given object is null
209 public static <T
> T
toNonNull(@Nullable T object
) throws AssertionError
{
211 Log
.wtf(Utils
.class.getName(), "toNonNull called with null");
212 throw new AssertionError("Log.wtf did not terminate the process");
218 * Join an array of Objects with elements separated by a separator into a single string.
220 * @param separator the separator
221 * @param offset the offset into the array
222 * @param args the array of Objects to join
223 * @return the joined string
225 public static String
join(final String separator
,final int offset
,final Object
[] args
){
226 final StringBuilder sb
=new StringBuilder(240);
227 sb
.append(args
[offset
]);
228 for (int i
= offset
+1; i
< args
.length
; i
++) {
229 sb
.append(separator
);
232 return toNonNull(sb
.toString());
236 * Join an array of Objects with elements separated by a separator into a single string.
238 * @param separator the separator
239 * @param args the array of objects to join
240 * @return the joined string
242 public static String
join(final String separator
, final Object
[] args
){
243 return join(separator
,0,args
);
247 * Send a notification to the user.
249 * @param context Context instance
250 * @param type notification type
251 * @param resource String resource for the message text
253 public static void sendMessage(final Context context
, final MessageType type
, final int resource
){
254 sendMessage(context
, type
, toNonNull(context
.getString(resource
)));
258 * Send a notification to the user.
260 * @param context Context instance
261 * @param type notification type
262 * @param resource String resource for the message text
263 * @param args format parameters for the resource
265 public static void sendMessage(final Context context
, final MessageType type
, final int resource
, final Object
... args
){
266 sendMessage(context
, type
, toNonNull(context
.getString(resource
, args
)));
270 * Send a message to a certain Address.
272 * @param context Context instance
273 * @param address destination Address
274 * @param resource String resource for the message text
276 public static void sendMessage(final Context context
, final Address address
, final int resource
){
277 sendMessage(context
, address
, toNonNull(context
.getString(resource
)));
281 * Send a message to a certain Address.
283 * @param context Context instance
284 * @param address destination Address
285 * @param resource String resource for the message text
286 * @param args format parameters for the resource
288 public static void sendMessage(final Context context
, final Address address
, final int resource
, final Object
... args
){
289 sendMessage(context
, address
, toNonNull(context
.getString(resource
, args
)));
293 * Send a notification to the user.
295 * @param context Context instance
296 * @param type notification type
297 * @param msg the notification text
299 public static void sendMessage(final Context context
, final MessageType type
,final String msg
){
300 final SharedPreferences sp
=PreferenceManager
.getDefaultSharedPreferences(context
);
301 final String address
=sp
.getString(type
.toString(),null);
304 sendMessage(context
, new Address(address
), msg
);
308 * Send a message to a certain Address.
310 * @param context Context instance
311 * @param address destination Address
312 * @param message the message text
314 public static void sendMessage(final Context context
, final Address address
, final String message
){
315 switch(address
.protocol
){
317 new SendHttpMessageAsyncTask(toNonNull(Arrays
.asList(
318 new Header("X-Action", "SEND "+address
.data
))), context
).execute(message
);
322 SmsManager
.getDefault().sendTextMessage(address
.data
, null, message
, null, null);
326 final Intent intent
= new Intent(FonBotLocalActivity
.RESPONSE_RECEIVED_ACTION
);
327 intent
.putExtra(FonBotLocalActivity
.EXTRA_RESPONSE
, message
);
328 context
.sendBroadcast(intent
);
337 * Parses a HTTP response message of the form <code>(part1) part2</code>, returning <code>part2</code>.
339 * @param message the raw HTTP response message
340 * @return the extracted part
342 public static String
parseHttpMessage(final String message
){
343 final int indexOfParen
=message
.indexOf(')');
346 return toNonNull(message
.substring(indexOfParen
+2));
350 * Splits a string into words.
352 * @param string the string
353 * @return an array of words
355 public static String
[] shellwords(final String string
){
356 return toNonNull(string
.split("[ ]+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"));//TODO: Make this handle backslash escapes
360 * Returns the name associated with a phone number.
362 * @param context Context instance
363 * @param number phone number to search for
364 * @return the name associated with this number, or null if the number was not found in the contacts.
366 public static @Nullable String
callerId(final Context context
, final String number
){
367 final Cursor cursor
=context
.getContentResolver().query(
368 Uri
.withAppendedPath(PhoneLookup
.CONTENT_FILTER_URI
, Uri
.encode(number
)),
369 new String
[]{PhoneLookup
.DISPLAY_NAME
},
374 if(cursor
.moveToFirst()){
375 final String name
=cursor
.getString(0);
384 * Registers an ongoing event.
386 * @param context Context instance
387 * @param event event to register
389 public static void registerOngoing(final Context context
, final OngoingEvent event
){
390 final Intent intent
=new Intent(context
, FonBotMainService
.class);
391 intent
.setAction(FonBotMainService
.ACTION_PUT_ONGOING
);
392 intent
.putExtra(FonBotMainService
.EXTRA_ONGOING_ID
, event
.ordinal());
393 context
.startService(intent
);
397 * Unregisters an ongoing event
399 * @param context Context instance
400 * @param event event to unregister
402 public static void unregisterOngoing(final Context context
, final OngoingEvent event
){
403 final Intent intent
=new Intent(context
, FonBotMainService
.class);
404 intent
.setAction(FonBotMainService
.ACTION_DELETE_ONGOING
);
405 intent
.putExtra(FonBotMainService
.EXTRA_ONGOING_ID
, event
.ordinal());
406 context
.startService(intent
);
410 * Executes a given command
412 * @param context Context instance
413 * @param cmd Command to execute
414 * @param args arguments for the command
415 * @param replyTo Address to send replies to
417 private static void processCommand(final Context context
, final Command cmd
,final String
[] args
,final Address replyTo
){
418 if(Heavy
.isCommandDisabled(context
, cmd
)){
419 sendMessage(context
, replyTo
, command_disabled
);
425 if(args
.length
< 1 || args
.length
> 2){
426 Heavy
.help(context
, replyTo
, toNonNull(Command
.TOAST
));
431 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]));
434 switch(ToastLength
.valueOf(args
[1].toUpperCase(Locale
.ENGLISH
))){
436 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]), Toast
.LENGTH_LONG
);
439 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]), Toast
.LENGTH_SHORT
);
441 } catch(IllegalArgumentException e
){
442 sendMessage(context
, replyTo
, invalid_length_allowed_values_are
, join(", ",toNonNull(ToastLength
.values())));
449 Heavy
.help(context
, replyTo
, toNonNull(Command
.ECHO
));
452 sendMessage(context
, replyTo
, join(" ",args
));
457 Heavy
.help(context
, replyTo
, toNonNull(Command
.SMS
));
460 Heavy
.sms(context
, replyTo
, toNonNull(args
[0]), join(" ", 1, args
));
464 if(args
.length
!= 1){
465 Heavy
.help(context
, replyTo
, toNonNull(Command
.FLASH
));
470 Heavy
.flash(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
471 } catch(IllegalArgumentException e
) {
472 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
478 Heavy
.help(context
, replyTo
, toNonNull(Command
.WIFI
));
482 Heavy
.wifi(context
, replyTo
);
485 Heavy
.wifi(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
486 } catch(IllegalArgumentException e
) {
487 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
494 Heavy
.help(context
, replyTo
, toNonNull(Command
.BLUETOOTH
));
498 Heavy
.bluetooth(context
, replyTo
);
501 Heavy
.bluetooth(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
502 } catch(IllegalArgumentException e
) {
503 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
510 Heavy
.help(context
, replyTo
, toNonNull(Command
.DIAL
));
513 Heavy
.dial(context
, replyTo
, toNonNull(args
[0]));
518 Heavy
.help(context
, replyTo
, toNonNull(Command
.RING
));
522 Heavy
.ring(context
, replyTo
);
525 Heavy
.ring(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
526 } catch(IllegalArgumentException e
){
527 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
534 Heavy
.help(context
, replyTo
, toNonNull(Command
.SPEAK
));
537 Heavy
.speak(context
, replyTo
, join(" ",args
));
542 Heavy
.help(context
, replyTo
, toNonNull(Command
.VIBRATE
));
547 ms
=Long
.parseLong(args
[0]);
548 } catch(NumberFormatException e
){
549 sendMessage(context
, replyTo
, could_not_parse_ms
);
552 Heavy
.vibrate(context
, replyTo
, ms
);
555 case DIALOG
://TODO: Should add an edittext
557 Heavy
.help(context
, replyTo
, toNonNull(Command
.DIALOG
));
560 final String
[] buttons
=new String
[args
.length
-1];
561 System
.arraycopy(args
,1,buttons
,0,buttons
.length
);
562 Heavy
.dialog(context
, replyTo
, toNonNull(args
[0]), buttons
);
566 if(args
.length
>3||args
.length
<1){
567 Heavy
.help(context
, replyTo
, toNonNull(Command
.LOCATION
));
571 final @NonNull String provider
;
573 switch(LocationProvider
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))){
575 provider
=toNonNull(LocationManager
.GPS_PROVIDER
);
579 provider
=toNonNull(LocationManager
.NETWORK_PROVIDER
);
582 } catch(IllegalArgumentException e
){
583 sendMessage(context
, replyTo
, cannot_parse_provider_allowed_values_are
, join(", ",toNonNull(LocationProvider
.values())));
588 final float minDistance
;
592 minTime
=Long
.parseLong(args
[1]);
593 } catch (NumberFormatException e
){
594 sendMessage(context
, replyTo
, cannot_parse_min_time
);
602 minDistance
=Float
.parseFloat(args
[2]);
603 } catch (NumberFormatException e
){
604 sendMessage(context
, replyTo
, cannot_parse_min_distance
);
609 Heavy
.location(context
, replyTo
, provider
, minTime
, minDistance
);
613 Heavy
.nolocation(context
, replyTo
);
618 Heavy
.help(context
, replyTo
, toNonNull(Command
.RINGER
));
622 Heavy
.ringer(context
, replyTo
);
625 final RingerMode rm
=RingerMode
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
));
628 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_NORMAL
);
631 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_VIBRATE
);
634 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_SILENT
);
637 } catch (IllegalArgumentException e
){
638 Utils
.sendMessage(context
, replyTo
, invalid_ringer_mode_valid_values_are
, join(", ",toNonNull(RingerMode
.values())));
645 Heavy
.help(context
, replyTo
, toNonNull(Command
.NCFILE
));
649 final int ncfilePort
;
651 ncfilePort
=Integer
.parseInt(args
[2]);
652 } catch (NumberFormatException e
){
653 sendMessage(context
, replyTo
, cannot_parse_port
);
656 Heavy
.ncfile(context
, replyTo
, toNonNull(args
[0]), toNonNull(args
[1]), ncfilePort
);
661 Heavy
.help(context
, replyTo
, toNonNull(Command
.PHOTO
));
666 photoPort
=Integer
.parseInt(args
[1]);
667 } catch (NumberFormatException e
){
668 sendMessage(context
, replyTo
, cannot_parse_port
);
671 Heavy
.photo(context
, replyTo
, toNonNull(args
[0]), photoPort
);
674 case SETNOTIFICATION
:
676 Heavy
.help(context
, replyTo
, toNonNull(Command
.SETNOTIFICATION
));
681 PreferenceManager
.getDefaultSharedPreferences(context
).edit()
682 .putString(MessageType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)).toString(), replyTo
.toString())
684 sendMessage(context
, replyTo
, notification_enabled
);
685 } catch (IllegalArgumentException e
){
686 sendMessage(context
, replyTo
, messagetype_should_be_one_of
, join(", ",toNonNull(MessageType
.values())));
692 case DELNOTIFICATION
:
694 Heavy
.help(context
, replyTo
, toNonNull(Command
.DELNOTIFICATION
));
699 PreferenceManager
.getDefaultSharedPreferences(context
).edit()
700 .remove(MessageType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)).toString())
702 sendMessage(context
, replyTo
, notification_disabled
);
703 } catch (IllegalArgumentException e
){
704 sendMessage(context
, replyTo
, messagetype_should_be_one_of
, join(", ",toNonNull(MessageType
.values())));
712 Heavy
.help(context
, replyTo
, toNonNull(Command
.SETPASSWORD
));
718 Heavy
.setPassword(context
, replyTo
);
720 Heavy
.setPassword(context
, replyTo
, toNonNull(args
[0]));
721 } catch (SecurityException e
){
722 sendMessage(context
, replyTo
, security_exception
+e
.getMessage());
728 Heavy
.help(context
, replyTo
, toNonNull(Command
.WIPE
));
732 if(!args
[1].equalsIgnoreCase(WIPE_CONFIRM_STRING
)){
733 sendMessage(context
, replyTo
, the_second_argument_to_wipe_must_be
, WIPE_CONFIRM_STRING
);
738 Heavy
.wipe(context
, toNonNull(WipeType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
739 } catch (IllegalArgumentException e
){
740 sendMessage(context
, replyTo
, wipetype_should_be_one_of
, join (", ",toNonNull(WipeType
.values())));
741 } catch (SecurityException e
){
742 sendMessage(context
, replyTo
, security_exception
, e
.getMessage());
748 Heavy
.lock(context
, replyTo
);
749 } catch (SecurityException e
){
750 sendMessage(context
, replyTo
, security_exception
, e
.getMessage());
756 Heavy
.help(context
, replyTo
, toNonNull(Command
.VIEW
));
760 Heavy
.view(context
, replyTo
, toNonNull(Uri
.parse(args
[0])));
764 Heavy
.musicPlayerCommand(context
, replyTo
, "play");
768 Heavy
.musicPlayerCommand(context
, replyTo
, "pause");
772 Heavy
.musicPlayerCommand(context
, replyTo
, "next");
776 Heavy
.musicPlayerCommand(context
, replyTo
, "previous");
780 Heavy
.batt(context
, replyTo
);
784 if (args
.length
> 1) {
785 Heavy
.help(context
, replyTo
, toNonNull(Command
.CALLLOG
));
789 if (args
.length
== 0)
790 Heavy
.calllog(context
, replyTo
, 5);
793 Heavy
.calllog(context
, replyTo
, Integer
.parseInt(args
[0]));
794 } catch (IllegalArgumentException e
){
795 sendMessage(context
, replyTo
, cannot_parse_count
);
801 if (args
.length
> 1) {
802 Heavy
.help(context
, replyTo
, toNonNull(Command
.SMSLOG
));
806 if (args
.length
== 0)
807 Heavy
.smslog(context
, replyTo
, 5);
810 Heavy
.smslog(context
, replyTo
, Integer
.parseInt(args
[0]));
811 } catch (IllegalArgumentException e
) {
812 sendMessage(context
, replyTo
, cannot_parse_count
);
818 if(args
.length
!= 1){
819 Heavy
.help(context
, replyTo
, toNonNull(Command
.HELP
));
824 Heavy
.help(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
825 } catch (IllegalArgumentException e
) {
826 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
831 if(args
.length
!= 1){
832 Heavy
.help(context
, replyTo
, toNonNull(Command
.LS
));
836 Heavy
.ls(context
, replyTo
, toNonNull(args
[0]));
840 if(args
.length
!= 1){
841 Heavy
.help(context
, replyTo
, toNonNull(Command
.RM
));
845 Heavy
.rm(context
, replyTo
, toNonNull(args
[0]));
849 if(args
.length
!= 1){
850 Heavy
.help(context
, replyTo
, toNonNull(Command
.CONTACTS
));
854 Heavy
.contacts(context
, replyTo
, toNonNull(args
[0]));
858 if(replyTo
.protocol
!= Protocol
.LOCAL
|| args
.length
!= 1){
859 Heavy
.help(context
, replyTo
, toNonNull(Command
.DISABLE
));
864 Heavy
.disable(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
865 } catch (IllegalArgumentException e
){
866 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
871 if(replyTo
.protocol
!= Protocol
.LOCAL
|| args
.length
!= 1){
872 Heavy
.help(context
, replyTo
, toNonNull(Command
.ENABLE
));
877 Heavy
.enable(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
878 } catch (IllegalArgumentException e
){
879 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
885 Heavy
.help(context
, replyTo
, toNonNull(Command
.POLL
));
890 Heavy
.poll(context
, replyTo
);
896 interval
=Long
.parseLong(args
[0]);
897 } catch(NumberFormatException e
){
898 sendMessage(context
, replyTo
, cannot_parse_interval
);
902 Heavy
.poll(context
, replyTo
, interval
);
906 Heavy
.hangup(context
, replyTo
);
910 Heavy
.answer(context
, replyTo
);
915 Heavy
.help(context
, replyTo
, toNonNull(Command
.LAUNCH
));
918 Heavy
.launch(context
, replyTo
, toNonNull(args
[0]));
923 Heavy
.help(context
, replyTo
, toNonNull(Command
.DATA
));
928 Heavy
.data(context
, replyTo
);
932 Heavy
.data(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
933 } catch(IllegalArgumentException e
) {
934 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
940 Heavy
.help(context
, replyTo
, toNonNull(Command
.GPS
));
945 Heavy
.gps(context
, replyTo
);
950 Heavy
.gps(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
951 } catch(IllegalArgumentException e
) {
952 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
958 Heavy
.help(context
, replyTo
, toNonNull(Command
.GLOCATION
));
963 Heavy
.glocation(context
, replyTo
);
968 Heavy
.glocation(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
969 } catch(IllegalArgumentException e
) {
970 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
976 Heavy
.help(context
, replyTo
, toNonNull(Command
.REBOOT
));
980 Heavy
.reboot(context
, replyTo
, args
.length
==0?
null:args
[0]);
984 //TODO: implement command
988 if(args
.length
!=1 && args
.length
!=3){
989 Heavy
.help(context
, replyTo
, toNonNull(Command
.NOTIFY
));
994 id
=Integer
.parseInt(args
[0]);
995 } catch (NumberFormatException e
){
996 sendMessage(context
, replyTo
, R
.string
.could_not_parse_id
);
1001 Heavy
.notify(context
, replyTo
, id
);
1003 Heavy
.notify(context
, replyTo
, id
, toNonNull(args
[1]), toNonNull(args
[2]));
1010 * Executes a given command
1012 * @param context Context instance
1013 * @param cmd Command to execute
1014 * @param args arguments for the command
1015 * @param replyTo Address to send replies to
1017 public static void processCommand(final Context context
, final String cmd
,final String
[] args
,final Address replyTo
){
1018 final @NonNull Command command
;
1020 command
=toNonNull(Command
.valueOf(cmd
.toUpperCase(Locale
.ENGLISH
)));
1021 } catch (IllegalArgumentException e
){
1022 sendMessage(context
, replyTo
, unknown_command
, cmd
.toUpperCase(Locale
.ENGLISH
), e
.getMessage());
1027 processCommand(context
, command
,args
,replyTo
);
1028 } catch(Exception e
){
1029 sendMessage(context
, replyTo
, error_while_processing_command
, e
.getClass().getName(), e
.getMessage());
1030 Log
.w(Utils
.class.getName(), "Error while processing command", e
);