This page is intended as a place to document the capabilities of the custom commands offered by the [AndroWish], the Tcl/Tk port to Android (excellent work, [chw]!). In the true Wiki spirit '''you''' are invited to extend this documentation. (You may have, already ([chw] definitely has): this information was harvested from the [AndroWish] page!) There are three Android-specific commands: 1. `[borg]` - control and interact with the Android OS. 1. `rfcomm` - transfer data over a Bluetooth serial port profile; akin to the TCL `socket` command. 1. `sdltk` - exposure of the SDL2 (Simple DirectMedia Layer) Android-related API. 1. `usbserial` - transfer data over USB-serial converters Documentation is provided in the order specified. ---- *** Name *** `borg` - control and interact with the Android OS. *** Synopsis *** borg cmd ?arg ...? *** Description *** This command integrates the capabilities of Tcl/Tk with an Android OS by way of several subcommands. These allow Tcl/Tk to go where it has never gone before by querying and controlling Bluetooth functionality, OS notifications (including device vibration and even speach), location information, etc. **** Bluetooth-Related Commands **** `borg bluetooth devices`: Returns a list suited for `array set` or `dict create` commands containing the Bluetooth address and friendly name of all paired Bluetooth devices. `borg bluetooth state`: Returns the current Bluetooth state: `on` or `off`. `borg bluetooth scanmode`: Returns the current Bluetooth scan mode (`off`, `passive`, `visible`, `connectable`, or `on`). `borg bluetooth myaddress`: Returns the Bluetooth address of the local default Bluetooth adapter. `borg remoteaddress address`: Returns the friendly name for the given Bluetooth address. **** USB-Related Commands **** `borg usbdevices`: Returns a list suited for the `array set` or `dict create` commands containing the USB device name and vendor/product identifieer of all currently connected USB devices. **** Network-Related Commands **** `borg networkinfo`: Returns the current state of the network: `none`, `wifi`, `mobile gsm`, etc. **** Destkop-Related Commands **** `borg shortcut add name-of-shortcut script-to-run ?png-icon-as-base-64-string?`: Adds an icon to the desktop, with the `name-of-shortcut` specified. The script, specified as `script-to-run` must use an absolute path must be readable by the user id under which the AndroWish package has been registered by the Android installer. The last (optional) parameter `png-icon-as-base-64-string` allows the icon graphic to be specified. If not provided, the AndroWish icon (Aladdin's lamp) is used. `borg shortcut delete name-of-shortcut`: Deletes an icon from desktop (depends on Android launcher support). **** Notification-Related Commands **** `borg notification add id title text`: Adds a notification with `title` and `text` into the Android notification area. The integer id, specified by the caller, is used to identify the notification on deletion. `borg notification delete ?id?`: Deletes a notification identified that was created with the `id` specified. If no `id` is provided, all notifications are deleted. `borg vibrate ms`: Turns on the vibration motor for integer `ms` milliseconds. `borg beep`: Plays the notification sound. `borg speak text ?lang pitch rate?`: Gets the Android to read out the string `text`. Optional parameter `lang` is the language code for the spoken language, e.g. en, en_US, de, es, etc. Optional parameters `pitch` and `rate` control the voice and speed as float values. For more information, see http://developer.android.com/reference/android/speech/tts/TextToSpeech.html `borg stopspeak`: Stops speech output. `borg isspeaking`: Returns true or false depending on state of speech output. `borg endspeak`: Stops speech output and releases system resources. `borg toast text ?flag?`: Displays a text notification `text` for a short period of time. The duration of that display is somewhat longer when `flag` is specified as true. `borg spinner on|off`: Displays or withdraws a spinner (rotating symbol indicating busy state) depending on argument. **** Location-Related Commands **** `borg location start ?minrate-in-ms? ?min-dist-in-m?`: Begins acquiring location data via the Android OS (which may choose to use GPS, network info, etc.). `borg location stop`: Ends location data acquisition. `borg location get`: Returns the location data (as an `array set` form) where the key is the location source. Location updates trigger a virtual event `<>` (currently untested) that is sent to all toplevel widgets. These toplevel event-handlers should, in turn, invoke `borg location get` to refresh their knowledge. **** System-Related Commands **** `borg displaymetrics`: Returns information about the display in form suitable for `array set`, e.g. display resolution, pixel density. See http://developer.android.com/reference/android/util/DisplayMetrics.html for details. `borg osbuildinfo`: Returns information about the operating system and device in form suitable for `array set`, e.g. Android API level, version, device name, manufacturer etc. See http://developer.android.com/reference/android/os/Build.html for details. `borg queryfeatures`: Returns information about features of the system (a lengthy list of strings) which is obtained from http://developer.android.com/reference/android/content/pm/PackageManager.html#getSystemAvailableFeatures() `borg packageinfo ?name?`: Returns information about installed packages or an individual package if its ''name'' is given. In the first case, a list with package names is returned, in the latter case a list of key value pairs with package information which can be used for ''array set'' or ''dict create''. **** Android Content (shared databases) **** `borg content query uri ?columns? ?where? ?whereargs? ?orderby?`: Performs a query on an Android content provider given by ''uri'' and returns a cursor token (a Tcl command which deals with that cursor). The optional ''columns'' are a comma separated list of database columns to appear in the result set. The optional ''where'' and ''whereargs'' parameters form the SQL WHERE clause of the query. Question mark parameter markers in ''where'' are positionally substituted by the information from the ''whereargs'' list. The optional ''orderby'' is the SQL ORDERBY part of the query. Example: set cursor [borg content query content://settings/system] # initially, cursor points before first row while {[$cursor move 1]} { puts [$cursor getrow] } `borg content delete uri selection ?value ...?`: Deletes rows from an Android content provider given by ''uri'' and returns the number of deleted rows. ''selection'' forms the SQL WHERE clause of the deletion where question mark parameter markers are substituted by ''value''. Example: borg content delete content://settings/system name=? my_item `borg content insert uri key value ...`: Inserts a row into an Android content provider given by ''uri'' and returns another URI which identifies the inserted row. ''key'' and ''value'' are pairs of column name and column value for the SQL INSERT operation. Example: borg content insert content://settings/system name my_item value "Some value" -> content://settings/system/4711 `borg content update uri values ?selection? ?args?`: Updates zero or more rows of an Android content provider given by ''uri'' and returns the number of updated rows. ''values'' is a list made up of a sequence of column names and column values. ''selection'' is the optional SQL WHERE clause with question mark parameter markers. The parameter markers are substituted by the values from ''args''. Example: # system settings wants the name in the URI borg content update content://settings/system/my_item {value {New Value}} **** Cursors from Android Content queries **** When a ''borg content query'' returned a cursor token, this token is a Tcl command to deal with the query's result set: `$cursor close`: Finishes the query and deletes the Tcl command. `$cursor columnnames`: Returns a list of column names of the result set. `$cursor count`: Returns the number of rows of the result set. `$cursor getblob index`: Returns the ''index''th column (zero-based) of the current row of the result set as a base64 encoded string. `$cursor getdouble index`: Returns the ''index''th column (zero-based) of the current row of the result set as a floating point number. `$cursor getint index`: Returns the ''index''th column (zero-based) of the current row of the result set as a integer number. `$cursor getpos`: Returns the index of the current row (zero-based). `$cursor getrow`: Returns the current row as a Tcl list made up of strings. Blobs from the result set are converted into base64 encoded strings. `$cursor getstring index`: Returns the ''index''th column (zero-based) of the current row of the result set as a string. `$cursor isnull index`: Returns true when the ''index''th column (zero-based) of the current row of the result set is an SQL NULL value. `$cursor move pos`: Relative move of the current row index. Negative ''pos'' goes backward. `$cursor moveto pos`: Absolute move of the current row index. **** General **** `borg withdraw`: Hides the application window by putting it to the end of Android's activity stack. Can be useful when bound to the Back key ( on AndroWish). There's no opposite command, i.e. the application can be brought to front again only by user interaction. `borg onintent ?command?`: Sets or gets the callback command which is evaluated when the application received an Android intent. When evaluating that command, the parameters action name, URI, MIME type, categories, arguments from the intent are appended. When the callback is set for the first time, it gets immediately evaluated with the parameters of the current (startup) intent. `borg queryactivites action ?uri type categories component?`: Queries Android's activity manager for activities on the given intent parameters. `categories` and `component` are optional lists. The latter when non-empty must contain the two elements package name and class name. `borg queryservices action ?uri type categories component?`: Queries Android's activity manager for services on the given intent parameters, similar to `borg queryactivities`. `borg querybroadcastreceivers action ?uri type categories component?`: Queries Android's activity manager for broadcast receivers on the given intent parameters, similar to `borg queryactivities`. `borg speechrecognition args callback`: Use the speech recognition service. `args` is a parameter list to control the speech recognition (see http://developer.android.com/reference/android/speech/RecognizerIntent.html for details). `callback` is invoked when the speech recognition is complete. That procedure receives the parameters `retcode` and `data` as the callback for `borg activity`. `data` is a list of key value pairs suitable for `array set`. `borg alarm clear action ?uri type categories component?`: Clears an alarm whose pattern matches the given intent parameters. `borg alarm set when repeat action ?uri type categories component arg ...?`: Sets an alarm to fire at `when` (UN*X epoch, seconds) with repetition each `repeat` seconds, when `repeat` is greater than 0. The alarm sends an intent made up of the given intent parameters (`action` etc.). The `component` parameter is interpreted specially: when empty no component is set on the intent, when given as `self` the calling package/class is set as component for the intent (sending the intent to itself, i.e. the callback of `borg onintent` will receive it). In all other cases `component` must be a list with the two elements package name and class name. `arg` and following parameters are added to the intent as key value pairs of extra data. `borg alarm wakeup when repeat action ?uri type categories component arg ...?`: Like `borg alarm set` but this type of alarm is able to wake up the device when suspended (device behavior depends on lock screen settings). `borg activity action uri type ?categories? ?component? ?arguments? ?callback?`: This a very flexible command that allows extensive access to the Android OS and other applications. `categories`, `component`, and `arguments` are optional lists. `callback` is the name of the procedure that is evaluated when the activity `action` is complete. `arguments` are key-value pairs where the values are mapped to Java strings by default. If the key is a 2-element list made up of a data type indicator (int, byte, short, char, long, float, double, Uri) followed by the key, the value is converted to that data type. See below for some examples of this command. *** `borg activity` Examples *** Sample code to open a browser on this wiki: ====== borg activity android.intent.action.VIEW http://wiki.tcl.tk text/html ====== Sample code to capture an image (only makes thumbnails): ====== proc callback {retcode action uri mimetype categories data} { if {$retcode == -1} { # SUCCESS array set result $data if {[info exists result(data)]} { myphoto configure -data $result(data) } } } package require Img image create photo myphoto borg activity android.media.action.IMAGE_CAPTURE {} {} {} {} {} callback ====== Sample code to capture an image, which makes full size images but requires a file on external storage: ====== proc callback {filename retcode action uri mimetype categories data} { if {$retcode == -1} { # SUCCESS myphoto configure -file $filename catch {file delete -force $filename} } } package require Img image create photo myphoto set filename [file join $env(EXTERNAL_FILES) myphoto.jpeg] borg activity android.media.action.IMAGE_CAPTURE {} {} {} {} \ [list {Uri output} file://$filename] [list callback $filename] ====== Reading barcodes using the http://code.google.com/p/zxing barcode scanner (which needs to be be installed on your device): ====== proc barcode_read {code action uri type cat data} { array set result $data if {[info exists result(SCAN_RESULT)]} { # that is the barcode # result(SCAN_RESULT_FORMAT) is the barcode format } } borg activity com.google.zxing.client.android.SCAN {} {} {} {} {} barcode_read ====== ---- *** Name *** `rfcomm` - transfer data over a Bluetooth serial port profile; akin to the TCL `socket` command. *** Synopsis *** This command is used to transfer data over Bluetooth's serial port profile (SPP or SP). The arguments used are nearly identical to the TCL `socket`command. It returns a client or server channel handle that may be used with `gets`, `read`, `puts`, and `close`. For client channels, the remote address must be given as a one- or two-element list: the first element is the Bluetooth address, and the (optional) second element is the UUID of the remote service. For server channels, the first element is the UUID, and the optional second element is the friendly name of the service. Server mode functionality has not yet been verified. ---- *** Name *** `sdltk` - exposure of the SDL2 (Simple DirectMedia Layer) Android-related API. *** Synopsis *** This command is used to control portions of the Android system that the SDL2 framework exposes. Actual data processing for this framework is achieved by having handlers for virtual events. *** Description *** `sdltk powerinfo`: Returns a list of key-value pairs describing the state of the battery. `sdltk accelerometer on|off`: Turns the device accelerometer on and off. Creates a top-level virtual event <>. `sdltk textinput ?on|off ?x y ?hint???`: Returns the state of the virtual keyboard or switches the virtual keyboard on or off. The optional coordinate pair is a hint for the system where the insertion cursor is displayed in screen coordinates. This allows the system to pan the application's screen in order to display the insertion cursor when the virtual keyboard is active. The `hint` parameter is an integer which controls the kind of virtual keyboard to be displayed. Known values are 0 (normal keyboard), 2 (number input), 3 (phone number input), 4 (date/time input). `sdltk android`: Returns true when running on Android, false otherwise, i.e. when built for normal Linux platforms. `sdltk touchtranslate ?flag?`: Turns touchscreen event translation on or off, or reports the current translation state. When turned on, fast wipes with one finger are translated to mouse button 2 press/motion/release events to allow scrolling of listboxes, entries, and text widgets. Slow wipes still deliver mouse button 1 motion events. Holding down one finger for about a second is translated into mouse button 3 press for context menus. Pinch-to-zoom with two fingers is detected and reported as a virtual event named <> with %X and %Y giving the root window coordinate of the center of the two fingers, %x the distance between the two fingers, and %y the angle measured in 64 times degrees CCW starting at 3 o'clock. `sdltk screensaver ?on|off?`: Turns the screen saver on or off or reports current state of the screensaver. *** Events *** Using the sdltk framework usually requires liberal use of virtual event handlers. The virtual events include: `<>`: Event associated with the accelerometer (activated with `sdltk accelerometer on`). `%s` is the accelerometer axis {1..3} and `%x` is the accelerometer value in the range {-32768...+32767}. `<>`: A touch event. `<>`: A touch completion event. `<>`: A touch movement (sliding) event. The fields `%x` and `%y` are substituted with the finger position scaled to {0...9999}, `%X` and `%Y` with the difference scaled to {0...9999}, `%t` with the pressure scaled to {0...9999}, and `%s` with the finger identifier {1...10}. These substitutions are performed for all finger related touch events. *** Events related to the APP life cycle *** These events are direct translations from SDL events. They are reported to toplevel widgets only. `<>`: System is in low memory situation `<>`: APP is terminating `<>`: APP's screen will be put in background `<>`: APP's screen is in the background `<>`: APP's screen will be put in foreground `<>`: APP's screen is in the foreground *** Other events *** These events are generated for/by certain `borg` related commands. They are reported to toplevel widgets only. `<>`: Location information has been updated and can be read out using `borg location get`. `<>`: Network state has changed and can be read out using `borg networkinfo`. `<>`: Bluetooth state has changed and can be read out using `borg bluetooth state`. *** Touchscreen related *** `<>`: Pinch-to-zoom with two fingers, see `sdltk touchtranslate` and the following sample code. ====== proc showzoom {canvas rootx rooty dist angle state} { $canvas itemconf t -text "XY: $rootx,$rooty L: $dist P: $angle S: $state" $canvas delete a # state 0 -> zoom motion # state 1 -> zoom start # state 2 -> zoom end, 1st finger up # state 3 -> zoom end, 2nd finger up if {$state < 2} { set phi [expr {$angle / 64.0}] set x0 [expr {$rootx - [winfo rootx $canvas] - $dist / 2}] set x1 [expr {$x0 + $dist}] set y0 [expr {$rooty - [winfo rooty $canvas] - $dist / 2}] set y1 [expr {$y0 + $dist}] $canvas create arc $x0 $y0 $x1 $y1 -fill yellow -outline red -width 6 \ -start [expr {330 - $phi}] -extent -300.0 -tags a } } wm attributes . -fullscreen 1 canvas .c -bg black -bd 0 -highlightthickness 0 pack .c -side top -fill both -expand 1 -padx 0 -pady 0 set f [open [info script]] .c create text 30 120 -anchor nw -tag s -font {Courier 6} -text [read $f] \ -fill gray50 close $f .c create text 30 30 -anchor w -fill green -tag t -font {Helvetica 16} \ -text "Try pinch-to-zoom with two fingers" button .c.x -text Exit -command {exit 0} .c create window 30 60 -anchor nw -tag x -window .c.x bind .c <> {showzoom %W %X %Y %x %y %s} ====== `<>`: Following sample code illustrates using the 3 accelerometer axes. ====== proc showaccel {canvas axis value} { set ix 0 set iy 0 if {$axis == 1} { set ix [expr {$value / 256}] } elseif {$axis == 2} { set iy [expr {$value / 256}] } elseif {$axis == 3} { set ::pos(t) [expr {($value / 256) % 360}] } else { return } if {![info exists ::pos(x)]} { set ::pos(x) [expr [winfo width $canvas] / 4] set ::pos(y) [expr [winfo height $canvas] / 4] set ::pos(t) 0 } set ::pos(x) [expr {$::pos(x) + $ix}] set ::pos(y) [expr {$::pos(y) + $iy}] if {$::pos(x) < 50} { set ::pos(x) 50 } elseif {$::pos(x) > [winfo width $canvas] - 50} { set ::pos(x) [expr {[winfo width $canvas] - 50}] } if {$::pos(y) < 50} { set ::pos(y) 50 } elseif {$::pos(y) > [winfo height $canvas] - 50} { set ::pos(y) [expr {[winfo height $canvas] - 50}] } if {$axis == 3} { $canvas delete a set x0 [expr {$::pos(x) - 48}] set x1 [expr {$x0 + 96}] set y0 [expr {$::pos(y) - 48}] set y1 [expr {$y0 + 96}] $canvas create arc $x0 $y0 $x1 $y1 -fill yellow -outline red \ -width 6 -start [expr {330 - $::pos(t)}] -extent -300.0 -tags a } } wm attributes . -fullscreen 1 canvas .c -bg black -bd 0 -highlightthickness 0 pack .c -side top -fill both -expand 1 -padx 0 -pady 0 set f [open [info script]] .c create text 20 120 -anchor nw -tag s -font {Courier 5} -text [read $f] \ -fill gray50 close $f button .c.x -text Exit -command {exit 0} .c create window 30 60 -anchor nw -tag x -window .c.x bind . <> {showaccel .c %s %x} sdltk accelerometer on ====== ---- *** Name *** `usbserial` - transfer data over USB-serial converters *** Synopsis *** This command is used to transfer data supported USB-serial converters (see http://code.google.com/p/usb-serial-for-android/ for reference). When no further argument is given to the `usbserial` command, a list of supported USB device names is returned. When the USB device name of a supported USB-serial converter is given as argument, `usbserial` opens that USB device and returns a Tcl channel handle for it. That channel handle may be used with `fconfigure`, `gets`, `read`, `puts`, and `close`. The options `-mode`, `-ttycontrol`, and `-ttystatus` to `fconfigure` are supported by the channel. However, support for getting/setting control lines varies between different USB-serial converter chips. ---- *** Environment *** Some environment variables in the `env` array are setup on early startup of [AndroWish]. `env(EXTERNAL_FILES)`: App specific directory on external storage `env(EXTERNAL_STORAGE)`: Path name of external storage (could be internal SD card) `env(EXTERNAL_STORAGE2)`: Path name of external storage (real external SD card) `env(HOME)`: App's home directory (internal storage) `env(INTERNAL_STORAGE)`: App specific directory on internal storage (identical with `$env(HOME)`) `env(LANG)`: System language `env(LD_LIBRARY_PATH)`: Load path for shared libraries including app specific directory `env(OBB_DIR)`: On some Android versions extra stuff bundled with the app (unused as of 2014-02-05) `env(PACKAGE_CODE_PATH)`: Path name of the app's APK `env(PACKAGE_NAME)`: Package name where the app's main class comes from `env(PATH)`: Path for exec(n) including app specific directory `env(TMPDIR)`: Path name for temporary files ---- '''Revision History''' | 2014-26-01 | [LWS] - creation from [AndroWish] entries - with lots left out, possible misinterpretation, etc. A momentary editing collision with [chw]: sorry! | | 2014-02-02 | [LWS] - updated `borg shortcut add` with info from [AndroWish Feature Requests] and modified a portion of the barcode reading example | | 2014-02-03 | [chw] - updated `sdltk` command description, added more event descriptions | | 2014-02-05 | [chw] - added `borg toast` command description | | 2014-02-06 | [chw] - added description of environment variables | | 2014-02-08 | [chw] - added description for `borg displaymetrics` and `borg osbuildinfo` | | 2014-02-11 | [chw] - updated `borg speak` command description | | 2014-02-22 | [chw] - added description for `sdltk touchtranslate` and `<>` | | 2014-03-03 | [chw] - added description for `borg spinner` and `sdltk screensaver` | | 2014-03-07 | [chw] - improved `<>` description | | 2014-03-15 | [chw] - added description for `borg queryfeatures`, `borg packageinfo`, and `borg content` | | 2014-03-24 | [chw] - added description for `borg withdraw` | | 2014-04-30 | [chw] - added description for `borg alarm`, `borg speechrecognition`, `borg onintent`, and `borg query*` | | 2014-05-12 | [chw] - added `<>` sample code | | 2014-05-13 | [chw] - added description for `borg usbdevices` and `usbserial` | <>Android