1 package ro
.ieval
.fonbot
;
3 import static ro
.ieval
.fonbot
.R
.string
.*;
5 import java
.net
.MalformedURLException
;
7 import java
.util
.Arrays
;
8 import java
.util
.Locale
;
10 import org
.eclipse
.jdt
.annotation
.NonNull
;
11 import org
.eclipse
.jdt
.annotation
.Nullable
;
13 import ro
.ieval
.fonbot
.Address
.Protocol
;
14 import android
.content
.Context
;
15 import android
.content
.Intent
;
16 import android
.content
.SharedPreferences
;
17 import android
.database
.Cursor
;
18 import android
.location
.LocationManager
;
19 import android
.media
.AudioManager
;
20 import android
.net
.Uri
;
21 import android
.preference
.PreferenceManager
;
22 import android
.provider
.ContactsContract
.PhoneLookup
;
23 import android
.telephony
.SmsManager
;
24 import android
.util
.Log
;
25 import android
.widget
.Toast
;
28 * Copyright © 2013 Marius Gavrilescu
30 * This file is part of FonBot.
32 * FonBot is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, either version 3 of the License, or
35 * (at your option) any later version.
37 * FonBot is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
42 * You should have received a copy of the GNU General Public License
43 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
47 * Utility functions and enums used in various places.
49 * @author Marius Gavrilescu <marius@ieval.ro>
51 public final class Utils
{
53 * Enum of all FonBot commands.
55 * @author Marius Gavrilescu <marius@ieval.ro>
57 @SuppressWarnings("javadoc")
58 public static enum Command
{
59 TOAST
, ECHO
, SMS
, FLASH
, WIFI
,
60 BLUETOOTH
, DIAL
, RING
, SPEAK
, VIBRATE
,
61 DIALOG
, LOCATION
, NOLOCATION
, RINGER
, NCFILE
,
62 PHOTO
, SETNOTIFICATION
, DELNOTIFICATION
, SETPASSWORD
, HELP
,
63 WIPE
, LOCK
, VIEW
, PLAY
, PAUSE
,
64 NEXT
, PREV
, BATT
, CALLLOG
, SMSLOG
,
65 LS
, RM
, CONTACTS
, DISABLE
, ENABLE
,
66 POLL
, HANGUP
, ANSWER
, LAUNCH
, DATA
,
67 GPS
, GLOCATION
, REBOOT
, NOTIFY
, SCREENCAP
,
72 * 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.
74 * @author Marius Gavrilescu <marius@ieval.ro>
77 public static enum MessageType
{
78 /** SMS notifications */
80 /** Phone state (idle, offhook or ringing) notifications */
82 /** Lockscreen failed password notifications */
84 /** Device admin enable/disable notifications */
86 /** Coarse battery status (low battery, ok battery) notifications */
88 /** Fine battery status notifications */
90 /** Headset plug/unplug notifications */
92 /** Phone booted notifications */
97 * 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).
99 * @author Marius Gavrilescu <marius@ieval.ro>
101 public static enum WipeType
{
102 /** Factory reset the phone, without touching the SD card */
104 /** Factory reset the phone and wipe the SD card too */
109 * Enum of ringer modes.
111 * @author Marius Gavrilescu <marius@ieval.ro>
113 public static enum RingerMode
{
116 /** Sound is off, vibrate is on */
118 /** Sound is off, vibrate is off */
123 * Enum of location providers
125 * @author Marius Gavrilescu <marius@ieval.ro>
127 public static enum LocationProvider
{
128 /** The network location provider */
130 /** The GPS location provider */
135 * Enum of toast lengths.
137 * @author Marius Gavrilescu <marius@ieval.ro>
139 private static enum ToastLength
{
147 * Enum of the values on and off. Used for boolean arguments.
149 * @author Marius Gavrilescu <marius@ieval.ro>
151 @SuppressWarnings("javadoc")
152 private static enum OnOff
{
157 * Enum of ongoing event types
159 * @author Marius Gavrilescu <marius@ieval.ro>
161 public static enum OngoingEvent
{
162 /** Location tracking is active. Registered by {@link Command#LOCATION}, unregistered by {@link Command#NOLOCATION} */
163 LOCATION(location_tracking_is_active
),
164 /** The phone is ringing. Registered/unregistered by {@link Command#RING} */
167 /** String resource: the event description */
168 public final int resource
;
171 * Constructs an OngoingEvent from its event description.
173 * @param resource the event description
175 private OngoingEvent(final int resource
) {
176 this.resource
=resource
;
180 /** Confirmation string for the {@link Command#WIPE WIPE} command. */
181 public static final String WIPE_CONFIRM_STRING
="I am aware this cannot be undone";
184 * Converts a Nullable object into a NonNull one.
186 * @param object the Nullable object to convert
187 * @return a NonNull object equivalent to the Nullable parameter
188 * @throws AssertionError if the given object is null
190 public static <T
> T
toNonNull(@Nullable T object
) throws AssertionError
{
192 Log
.wtf(Utils
.class.getName(), "toNonNull called with null");
193 throw new AssertionError("Log.wtf did not terminate the process");
199 * Join an array of Objects with elements separated by a separator into a single string.
201 * @param separator the separator
202 * @param offset the offset into the array
203 * @param args the array of Objects to join
204 * @return the joined string
206 public static String
join(final String separator
,final int offset
,final Object
[] args
){
207 final StringBuilder sb
=new StringBuilder(240);
208 sb
.append(args
[offset
]);
209 for (int i
= offset
+1; i
< args
.length
; i
++) {
210 sb
.append(separator
);
213 return toNonNull(sb
.toString());
217 * Join an array of Objects with elements separated by a separator into a single string.
219 * @param separator the separator
220 * @param args the array of objects to join
221 * @return the joined string
223 public static String
join(final String separator
, final Object
[] args
){
224 return join(separator
,0,args
);
228 * Send a notification to the user.
230 * @param context Context instance
231 * @param type notification type
232 * @param resource String resource for the message text
234 public static void sendMessage(final Context context
, final MessageType type
, final int resource
){
235 sendMessage(context
, type
, toNonNull(context
.getString(resource
)));
239 * Send a notification to the user.
241 * @param context Context instance
242 * @param type notification type
243 * @param resource String resource for the message text
244 * @param args format parameters for the resource
246 public static void sendMessage(final Context context
, final MessageType type
, final int resource
, final Object
... args
){
247 sendMessage(context
, type
, toNonNull(context
.getString(resource
, args
)));
251 * Send a message to a certain Address.
253 * @param context Context instance
254 * @param address destination Address
255 * @param resource String resource for the message text
257 public static void sendMessage(final Context context
, final Address address
, final int resource
){
258 sendMessage(context
, address
, toNonNull(context
.getString(resource
)));
262 * Send a message to a certain Address.
264 * @param context Context instance
265 * @param address destination Address
266 * @param resource String resource for the message text
267 * @param args format parameters for the resource
269 public static void sendMessage(final Context context
, final Address address
, final int resource
, final Object
... args
){
270 sendMessage(context
, address
, toNonNull(context
.getString(resource
, args
)));
274 * Send a notification to the user.
276 * @param context Context instance
277 * @param type notification type
278 * @param msg the notification text
280 public static void sendMessage(final Context context
, final MessageType type
,final String msg
){
281 final SharedPreferences sp
=PreferenceManager
.getDefaultSharedPreferences(context
);
282 final String address
=sp
.getString(type
.toString(),null);
285 sendMessage(context
, new Address(address
), msg
);
289 * Send a message to a certain Address.
291 * @param context Context instance
292 * @param address destination Address
293 * @param message the message text
295 public static void sendMessage(final Context context
, final Address address
, final String message
){
296 switch(address
.protocol
){
298 new HttpCallExecutableRunnable("/send", toNonNull(Arrays
.asList(new Header("X-Destination", toNonNull(address
.data
)))), context
, null, true, address
.requestId
== null ? message
: address
.requestId
+ " " + message
).execute();
302 SmsManager
.getDefault().sendTextMessage(address
.data
, null, message
, null, null);
306 final Intent intent
= new Intent(FonBotLocalActivity
.RESPONSE_RECEIVED_ACTION
);
307 intent
.putExtra(FonBotLocalActivity
.EXTRA_RESPONSE
, message
);
308 context
.sendBroadcast(intent
);
317 * Splits a string into words.
319 * @param string the string
320 * @return an array of words
322 public static String
[] shellwords(final String string
){
323 return toNonNull(string
.split("[ ]+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"));//TODO: Make this handle backslash escapes
327 * Returns the name associated with a phone number.
329 * @param context Context instance
330 * @param number phone number to search for
331 * @return the name associated with this number, or null if the number was not found in the contacts.
333 public static @Nullable String
callerId(final Context context
, final String number
){
334 final Cursor cursor
=context
.getContentResolver().query(
335 Uri
.withAppendedPath(PhoneLookup
.CONTENT_FILTER_URI
, Uri
.encode(number
)),
336 new String
[]{PhoneLookup
.DISPLAY_NAME
},
341 if(cursor
.moveToFirst()){
342 final String name
=cursor
.getString(0);
351 * Registers an ongoing event.
353 * @param context Context instance
354 * @param event event to register
356 public static void registerOngoing(final Context context
, final OngoingEvent event
){
357 final Intent intent
=new Intent(context
, FonBotMainService
.class);
358 intent
.setAction(FonBotMainService
.ACTION_PUT_ONGOING
);
359 intent
.putExtra(FonBotMainService
.EXTRA_ONGOING_ID
, event
.ordinal());
360 context
.startService(intent
);
364 * Unregisters an ongoing event
366 * @param context Context instance
367 * @param event event to unregister
369 public static void unregisterOngoing(final Context context
, final OngoingEvent event
){
370 final Intent intent
=new Intent(context
, FonBotMainService
.class);
371 intent
.setAction(FonBotMainService
.ACTION_DELETE_ONGOING
);
372 intent
.putExtra(FonBotMainService
.EXTRA_ONGOING_ID
, event
.ordinal());
373 context
.startService(intent
);
377 * Gets the server URL according to the user preferences.
379 * @param context Context instance
380 * @param path URL path
381 * @return the server URL
382 * @throws MalformedURLException if the user preferences create an invalid URL
384 public static URL
getServerURL(final Context context
, final String path
) throws MalformedURLException
{
385 final String protocol
=PreferenceManager
.getDefaultSharedPreferences(context
).getString("protocol", "https");
386 final String hostname
=PreferenceManager
.getDefaultSharedPreferences(context
).getString("hostname", "fonbot.ieval.ro");
387 final int port
=Integer
.parseInt(PreferenceManager
.getDefaultSharedPreferences(context
).getString("port", "443"));
388 final URL url
=new URL(protocol
, hostname
, port
, path
);
393 * Executes a given command
395 * @param context Context instance
396 * @param cmd Command to execute
397 * @param args arguments for the command
398 * @param replyTo Address to send replies to
400 private static void processCommand(final Context context
, final Command cmd
,final String
[] args
,final Address replyTo
){
401 if(Heavy
.isCommandDisabled(context
, cmd
)){
402 sendMessage(context
, replyTo
, command_disabled
, cmd
.toString());
408 if(args
.length
< 1 || args
.length
> 2){
409 Heavy
.help(context
, replyTo
, toNonNull(Command
.TOAST
));
414 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]));
417 switch(ToastLength
.valueOf(args
[1].toUpperCase(Locale
.ENGLISH
))){
419 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]), Toast
.LENGTH_LONG
);
422 Heavy
.toast(context
, replyTo
, toNonNull(args
[0]), Toast
.LENGTH_SHORT
);
424 } catch(IllegalArgumentException e
){
425 sendMessage(context
, replyTo
, invalid_length_allowed_values_are
, join(", ",toNonNull(ToastLength
.values())));
432 Heavy
.help(context
, replyTo
, toNonNull(Command
.ECHO
));
435 sendMessage(context
, replyTo
, join(" ",args
));
440 Heavy
.help(context
, replyTo
, toNonNull(Command
.SMS
));
443 Heavy
.sms(context
, replyTo
, toNonNull(args
[0]), join(" ", 1, args
));
447 if(args
.length
!= 1){
448 Heavy
.help(context
, replyTo
, toNonNull(Command
.FLASH
));
453 Heavy
.flash(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
454 } catch(IllegalArgumentException e
) {
455 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
461 Heavy
.help(context
, replyTo
, toNonNull(Command
.WIFI
));
465 Heavy
.wifi(context
, replyTo
);
468 Heavy
.wifi(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
469 } catch(IllegalArgumentException e
) {
470 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
477 Heavy
.help(context
, replyTo
, toNonNull(Command
.BLUETOOTH
));
481 Heavy
.bluetooth(context
, replyTo
);
484 Heavy
.bluetooth(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
485 } catch(IllegalArgumentException e
) {
486 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
493 Heavy
.help(context
, replyTo
, toNonNull(Command
.DIAL
));
496 Heavy
.dial(context
, replyTo
, toNonNull(args
[0]));
501 Heavy
.help(context
, replyTo
, toNonNull(Command
.RING
));
505 Heavy
.ring(context
, replyTo
);
508 Heavy
.ring(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
509 } catch(IllegalArgumentException e
){
510 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
517 Heavy
.help(context
, replyTo
, toNonNull(Command
.SPEAK
));
520 Heavy
.speak(context
, replyTo
, join(" ",args
));
525 Heavy
.help(context
, replyTo
, toNonNull(Command
.VIBRATE
));
530 ms
=Long
.parseLong(args
[0]);
531 } catch(NumberFormatException e
){
532 sendMessage(context
, replyTo
, could_not_parse_ms
);
535 Heavy
.vibrate(context
, replyTo
, ms
);
538 case DIALOG
://TODO: Should add an edittext
540 Heavy
.help(context
, replyTo
, toNonNull(Command
.DIALOG
));
543 final String
[] buttons
=new String
[args
.length
-1];
544 System
.arraycopy(args
,1,buttons
,0,buttons
.length
);
545 Heavy
.dialog(context
, replyTo
, toNonNull(args
[0]), buttons
);
549 if(args
.length
>3||args
.length
<1){
550 Heavy
.help(context
, replyTo
, toNonNull(Command
.LOCATION
));
554 final @NonNull String provider
;
556 switch(LocationProvider
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))){
558 provider
=toNonNull(LocationManager
.GPS_PROVIDER
);
562 provider
=toNonNull(LocationManager
.NETWORK_PROVIDER
);
565 } catch(IllegalArgumentException e
){
566 sendMessage(context
, replyTo
, cannot_parse_provider_allowed_values_are
, join(", ",toNonNull(LocationProvider
.values())));
571 final float minDistance
;
575 minTime
=Long
.parseLong(args
[1]);
576 } catch (NumberFormatException e
){
577 sendMessage(context
, replyTo
, cannot_parse_min_time
);
585 minDistance
=Float
.parseFloat(args
[2]);
586 } catch (NumberFormatException e
){
587 sendMessage(context
, replyTo
, cannot_parse_min_distance
);
592 Heavy
.location(context
, replyTo
, provider
, minTime
, minDistance
);
596 Heavy
.nolocation(context
, replyTo
);
601 Heavy
.help(context
, replyTo
, toNonNull(Command
.RINGER
));
605 Heavy
.ringer(context
, replyTo
);
608 final RingerMode rm
=RingerMode
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
));
611 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_NORMAL
);
614 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_VIBRATE
);
617 Heavy
.ringer(context
, replyTo
, AudioManager
.RINGER_MODE_SILENT
);
620 } catch (IllegalArgumentException e
){
621 Utils
.sendMessage(context
, replyTo
, invalid_ringer_mode_valid_values_are
, join(", ",toNonNull(RingerMode
.values())));
628 Heavy
.help(context
, replyTo
, toNonNull(Command
.NCFILE
));
632 final int ncfilePort
;
634 ncfilePort
=Integer
.parseInt(args
[2]);
635 } catch (NumberFormatException e
){
636 sendMessage(context
, replyTo
, cannot_parse_port
);
639 Heavy
.ncfile(context
, replyTo
, toNonNull(args
[0]), toNonNull(args
[1]), ncfilePort
);
644 Heavy
.help(context
, replyTo
, toNonNull(Command
.PHOTO
));
648 final int cameraNumber
;
650 cameraNumber
=Integer
.parseInt(args
[0]);
651 } catch (NumberFormatException e
){
652 sendMessage(context
, replyTo
, cannot_parse_camera_number
);
658 photoPort
=Integer
.parseInt(args
[2]);
659 } catch (NumberFormatException e
){
660 sendMessage(context
, replyTo
, cannot_parse_port
);
663 Heavy
.photo(context
, replyTo
, cameraNumber
, toNonNull(args
[1]), photoPort
);
666 case SETNOTIFICATION
:
668 Heavy
.help(context
, replyTo
, toNonNull(Command
.SETNOTIFICATION
));
673 PreferenceManager
.getDefaultSharedPreferences(context
).edit()
674 .putString(MessageType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)).toString(), replyTo
.toString())
676 sendMessage(context
, replyTo
, notification_enabled
);
677 } catch (IllegalArgumentException e
){
678 sendMessage(context
, replyTo
, messagetype_should_be_one_of
, join(", ",toNonNull(MessageType
.values())));
684 case DELNOTIFICATION
:
686 Heavy
.help(context
, replyTo
, toNonNull(Command
.DELNOTIFICATION
));
691 PreferenceManager
.getDefaultSharedPreferences(context
).edit()
692 .remove(MessageType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)).toString())
694 sendMessage(context
, replyTo
, notification_disabled
);
695 } catch (IllegalArgumentException e
){
696 sendMessage(context
, replyTo
, messagetype_should_be_one_of
, join(", ",toNonNull(MessageType
.values())));
704 Heavy
.help(context
, replyTo
, toNonNull(Command
.SETPASSWORD
));
710 Heavy
.setPassword(context
, replyTo
);
712 Heavy
.setPassword(context
, replyTo
, toNonNull(args
[0]));
713 } catch (SecurityException e
){
714 sendMessage(context
, replyTo
, security_exception
+e
.getMessage());
720 Heavy
.help(context
, replyTo
, toNonNull(Command
.WIPE
));
724 if(!args
[1].equalsIgnoreCase(WIPE_CONFIRM_STRING
)){
725 sendMessage(context
, replyTo
, the_second_argument_to_wipe_must_be
, WIPE_CONFIRM_STRING
);
730 Heavy
.wipe(context
, toNonNull(WipeType
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
731 } catch (IllegalArgumentException e
){
732 sendMessage(context
, replyTo
, wipetype_should_be_one_of
, join (", ",toNonNull(WipeType
.values())));
733 } catch (SecurityException e
){
734 sendMessage(context
, replyTo
, security_exception
, e
.getMessage());
740 Heavy
.lock(context
, replyTo
);
741 } catch (SecurityException e
){
742 sendMessage(context
, replyTo
, security_exception
, e
.getMessage());
748 Heavy
.help(context
, replyTo
, toNonNull(Command
.VIEW
));
752 Heavy
.view(context
, replyTo
, toNonNull(Uri
.parse(args
[0])));
756 Heavy
.musicPlayerCommand(context
, replyTo
, "play");
760 Heavy
.musicPlayerCommand(context
, replyTo
, "pause");
764 Heavy
.musicPlayerCommand(context
, replyTo
, "next");
768 Heavy
.musicPlayerCommand(context
, replyTo
, "previous");
772 Heavy
.batt(context
, replyTo
);
776 if (args
.length
> 1) {
777 Heavy
.help(context
, replyTo
, toNonNull(Command
.CALLLOG
));
781 if (args
.length
== 0)
782 Heavy
.calllog(context
, replyTo
, 5);
785 Heavy
.calllog(context
, replyTo
, Integer
.parseInt(args
[0]));
786 } catch (IllegalArgumentException e
){
787 sendMessage(context
, replyTo
, cannot_parse_count
);
793 if (args
.length
> 1) {
794 Heavy
.help(context
, replyTo
, toNonNull(Command
.SMSLOG
));
798 if (args
.length
== 0)
799 Heavy
.smslog(context
, replyTo
, 5);
802 Heavy
.smslog(context
, replyTo
, Integer
.parseInt(args
[0]));
803 } catch (IllegalArgumentException e
) {
804 sendMessage(context
, replyTo
, cannot_parse_count
);
810 if(args
.length
!= 1){
811 Heavy
.help(context
, replyTo
, toNonNull(Command
.HELP
));
816 Heavy
.help(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
817 } catch (IllegalArgumentException e
) {
818 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
823 if(args
.length
!= 1){
824 Heavy
.help(context
, replyTo
, toNonNull(Command
.LS
));
828 Heavy
.ls(context
, replyTo
, toNonNull(args
[0]));
832 if(args
.length
!= 1){
833 Heavy
.help(context
, replyTo
, toNonNull(Command
.RM
));
837 Heavy
.rm(context
, replyTo
, toNonNull(args
[0]));
841 if(args
.length
!= 1){
842 Heavy
.help(context
, replyTo
, toNonNull(Command
.CONTACTS
));
846 Heavy
.contacts(context
, replyTo
, toNonNull(args
[0]));
850 if(replyTo
.protocol
!= Protocol
.LOCAL
|| args
.length
!= 1){
851 Heavy
.help(context
, replyTo
, toNonNull(Command
.DISABLE
));
856 Heavy
.disable(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
857 } catch (IllegalArgumentException e
){
858 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
863 if(replyTo
.protocol
!= Protocol
.LOCAL
|| args
.length
!= 1){
864 Heavy
.help(context
, replyTo
, toNonNull(Command
.ENABLE
));
869 Heavy
.enable(context
, replyTo
, toNonNull(Command
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
))));
870 } catch (IllegalArgumentException e
){
871 sendMessage(context
, replyTo
, no_such_command_command_list
, join(", ", toNonNull(Command
.values())));
876 Heavy
.poll(context
, replyTo
);
880 Heavy
.hangup(context
, replyTo
);
884 Heavy
.answer(context
, replyTo
);
889 Heavy
.help(context
, replyTo
, toNonNull(Command
.LAUNCH
));
892 Heavy
.launch(context
, replyTo
, toNonNull(args
[0]));
897 Heavy
.help(context
, replyTo
, toNonNull(Command
.DATA
));
902 Heavy
.data(context
, replyTo
);
906 Heavy
.data(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
907 } catch(IllegalArgumentException e
) {
908 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
914 Heavy
.help(context
, replyTo
, toNonNull(Command
.GPS
));
919 Heavy
.gps(context
, replyTo
);
924 Heavy
.gps(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
925 } catch(IllegalArgumentException e
) {
926 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
932 Heavy
.help(context
, replyTo
, toNonNull(Command
.GLOCATION
));
937 Heavy
.glocation(context
, replyTo
);
942 Heavy
.glocation(context
, replyTo
, OnOff
.valueOf(args
[0].toUpperCase(Locale
.ENGLISH
)) == OnOff
.ON
);
943 } catch(IllegalArgumentException e
) {
944 sendMessage(context
, replyTo
, could_not_parse_argument_allowed_values_are
, join(", ", toNonNull(OnOff
.values())));
950 Heavy
.help(context
, replyTo
, toNonNull(Command
.REBOOT
));
954 Heavy
.reboot(context
, replyTo
, args
.length
==0?
null:args
[0]);
958 if(args
.length
!=1 && args
.length
!=3){
959 Heavy
.help(context
, replyTo
, toNonNull(Command
.NOTIFY
));
965 id
=Integer
.parseInt(args
[0]);
966 } catch (NumberFormatException e
){
967 sendMessage(context
, replyTo
, R
.string
.could_not_parse_id
);
972 Heavy
.notify(context
, replyTo
, id
);
974 Heavy
.notify(context
, replyTo
, id
, toNonNull(args
[1]), toNonNull(args
[2]));
978 if(args
.length
!= 1){
979 Heavy
.help(context
, replyTo
, toNonNull(Command
.SCREENCAP
));
983 Heavy
.screencap(context
, replyTo
, args
[0]);
987 Heavy
.torch(context
, replyTo
);
991 if(args
.length
!= 3){
992 Heavy
.help(context
, replyTo
, toNonNull(Command
.GETFILE
));
996 final int getfilePort
;
998 getfilePort
=Integer
.parseInt(args
[2]);
999 } catch (NumberFormatException e
){
1000 sendMessage(context
, replyTo
, cannot_parse_port
);
1003 Heavy
.getfile(context
, replyTo
, toNonNull(args
[0]), toNonNull(args
[1]), getfilePort
);
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
);