This page is made to share your tips and tricks on this page that can help in making Android applications using AndroWish. Please try to be as specific as you can about AndroWish specific commands e.g. borg and sdltk . and touch screen events Please give as many relevant examples as you can.
Superlinux: An example on using <<PinchToZoom>> .
A simple way to zoom the size of your app by changing the default font of the whole GUI made by Tk :
set font_size 3 ;# default starting font size is set to 3 . set old_fingers_pinch_to_zoom_distance 0 ;# keeps track of the distance between the pinching fingers before moving the fingers to do the pinch move proc pinch_to_zoom { fingers_distance } { global old_fingers_pinch_to_zoom_distance global font_size if { $fingers_distance > $old_fingers_pinch_to_zoom_distance } { incr font_size font configure TkDefaultFont -size $font_size set old_fingers_pinch_to_zoom_distance $fingers_distance return } if { $fingers_distance < $old_fingers_pinch_to_zoom_distance } { if { $font_size <=3 } { set font_size 3 return } incr font_size -1 font configure TkDefaultFont -size $font_size set old_fingers_pinch_to_zoom_distance $fingers_distance return } } font configure TkDefaultFont -size $font_size bind . <<PinchToZoom>> { pinch_to_zoom %x } ;# remember that %x is the distance between pinching fingers # Activate <<PinchToZoom>> virtual event and disable auto zooming sdltk touchtranslate 3
HaO 2015-03-16: Thanks for the example. The following example takes the font size at the pinch start as reference for the pinch distance. In addition, it scales the distance by the screen size, as screen resolution is highly variant on smart phones.
sdltk touchtranslate 3 set PinchStartFontSize 3 set PinchStartValue 0 bind . <<PinchToZoom>> {+PinchToZoomDo %x %s} proc PinchToZoomDo {X State} { global PinchStartFontSize global PinchStartValue # State values: 0:Motion, 1:Start, 2:End 1st Finger, 2:End Both Fingers switch -exact .. $State { 1 { # Start set PinchStartValue $X set PinchStartFontSize [font actual TkDefaultFont -size] } 0 - 2 { # Motion, End set FontSize [expr { $PinchStartFontSize + ($X - $PinchStartValue) * 10 / [winfo screenwidth .] }] if {$FontSize < 3} {set FontSize 3} font configure TkDefaultFont -size $FontSize } } }
For the below, you will need SSHDroid installed on your Tablet:
JM 3/21/2014, If you use Windows PC to edit your scripts, you can use pscp launched like this from the DOS command line:
pscp -P 2222 C:\Tcl\code\logo2.tcl [email protected]:/sdcard/
In the example I am copying my logo2.tcl script to /sdcard/ on the Android device which IP address is 192.168.1.64 in this case. "admin" is the default password.
JM 8/9/2014, If using Ubuntu:
ssh -p 2222 [email protected]
See you specific port and ip address on the SSHDroid screen running on your Android.
default password is "admin"
JM 8/9/2014, my set of rc files...
Instructions:
From now on, you will be immediately prompted for the script to run when launching Androwish...
File #1 | init.tcl |
which I only use when I install a new Androwish version:
file delete /data/data/tk.tcl.wish/files/.wishrc file rename -force x.wishrc .wishrc file copy .wishrc /data/data/tk.tcl.wish/files
File #2 | x.wishrc |
File will renamed to hidden .wishrc with the init script above
set env(HOME) /sdcard cd ~ source wishrc.tcl
File #3 | wishrc.tcl |
this is used to immediately get a file browser dialog to select the script I want to run:
sdltk textinput on set script [tk_getOpenFile] if {$script != ""} { source $script console hide } else { puts "hello!" }
Superlinux - 2014-03-27 10:35:07
This is an example on how to send your text or HTML file to printing on paper using PrintBot.
You can find PrintBot in this link here
PrinterBot is a network printer driver for Android. It can run Internet Printing Protocol (IPP).
On Linux, as a test, install CUPS-PDF and CUPS printer server and make it shared on the local network.
borg activity net.jsecurity.printbot.action.PRINT "file:///mnt/sdcard/test-page.txt" "text/html" {} {} { borg toast "Printing completed" }
Well, AW made my first android tablet purchase worth every penny.
So, here's my .wishrc, with some console fun. Also handy for fat fingers. It adds buttons to the console window.
Warning, careful here if you mangle this, you might not have a console to use to correct your .wishrc file in the protected zone.
I have followed the lead here of having files in /sdcard/home which I can modify, and then copy as needed to the protected AW zone. So, it goes there first, and if wishrc.tcl is found, sources it after it modifies the console window.
The copyit button on the console window will do that for you if you use these folder conventions. It does want a confirmation. Same with exit. The +x/-x resize the x size of the console window. Bottom scrolls you to the bottom, and you can disable scrolling with the checkbox. I also increase the number of lines to 1000.
update: Fixed problem with width adjustments, seems wm geom . is different here than on my winxp system
if { $tcl_platform(os) != "Windows NT" } { # to test on winxp before going live on android set env(HOME) /sdcard/home cd ~ } else { console show } package require Tk # a menu item runs this, it's defined here, not inside the console eval proc menudo {} { puts "pressed-menu" } if [catch { console eval { if { ![info exist ::tk::do_scroll] } { set menuincr 0 ;# some consoles have an extra item in the edit menu (a font...) AW doesn't, so leave at 0 for now set fontsz {times 9} pack forget .console .sb .consoleframe pack [frame .frame -bg black] -side left -fill y -ipady 2 -pady 2 pack [button .frame.clear -bg blue -fg white -text Clear -command {.menubar.file invoke 2} -font $fontsz] -side top -fill x pack [button .frame.smaller -bg white -text {font -} -font $fontsz -command {.menubar.edit invoke [expr ( $menuincr+6 )];after 100 {.frame.repos invoke}}] -side top -fill x pack [button .frame.bigger -bg white -text {font +} -font $fontsz -command {.menubar.edit invoke [expr ( $menuincr+5 )];after 100 {.frame.repos invoke}}] -side top -fill x pack [button .frame.exit -bg red -fg white -text Exit -font $fontsz -command {exiter}] -side top -fill x pack [button .frame.repos -bg white -text Bottom -font $fontsz -command {.console see end; .console mark set insert end}] -side top -fill x pack [frame .frame.frame -bg black] -side top -fill x pack [button .frame.frame.m10 -bg gray -fg white -font $fontsz -text -x -command { if { [.console cget -width] > 30 } { .console config -width [expr ( [.console cget -width]-10 )] } }] -side top -fill x -expand 1 pack [button .frame.frame.p10 -bg gray -fg white -font $fontsz -text +x -command { if { [.console cget -width] < 120 } { .console config -width [expr ([.console cget -width]+10)] } }] -side top -fill x -expand 1 pack [checkbutton .frame.scroll -bg white -fg black -text scroll -font $fontsz -variable ::tk::do_scroll] -side top -fill x pack [button .frame.frame.mit -bg green -fg white -font $fontsz -text copyit -command copyit] -side top -fill x -expand 1 pack .consoleframe -in . -anchor center -expand 1 -fill both -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left pack .console -in .consoleframe -anchor center -expand 1 -fill both -ipadx 0 -ipady 0 -padx 1 -pady 1 -side left pack .sb -in .consoleframe -anchor center -expand 1 -fill both -ipadx 0 -ipady 0 -padx 1 -pady 1 -side right #puts "console width now [.console config -width] [wm geom .]" ;# hmmm, seems wm geom different across platforms here proc copyit {} { set answer [tk_messageBox -message "Please confirm\nto copy .wishrc" -icon question -type yesno] if { $answer == "yes" } { file copy -force .wishrc /data/data/tk.tcl.wish/files/ puts copied } } proc exiter {} { set answer [tk_messageBox -message "Please confirm to Exit." -icon question -type yesno] if { $answer == "yes" } { exit } } set ::tk::console::maxLines 1000 .menubar add casc -label Extra -menu [menu .menubar.extra -tearoff 0] proc menu+ {head label cmd} { set cmd2 [list consoleinterp eval $cmd] .menubar.$head add command -label $label -command $cmd2 ;# note this is defined outside the console eval... its in the normal namespace } menu+ extra menu menudo proc ::tk::ConsoleOutput {dest string} { set w .console $w insert output $string $dest ::tk::console::ConstrainBuffer $w $::tk::console::maxLines if {$::tk::do_scroll} {$w see insert} } set ::tk::do_scroll 1 } } } err_code] { puts $err_code } if { $tcl_platform(os) != "Windows NT" } { if { [file exist wishrc.tcl] } { puts "sourcing wishrc.tcl" source wishrc.tcl } else { puts stderr "wishrc.tcl not found" } }
Here's some more fun with the console and a little test of flashing a button. It should run on any 8.6 setup. I call it wishrc.tcl to test it on my tablet.
button .b -text "push me\nafter I stop" -command {wm wi .} -bg black -fg white pack .b -fill both -expand true proc uniqkey { } { set key [ expr { pow(2,31) + [ clock clicks ] } ] set key [ string range $key end-8 end-3 ] set key [ clock seconds ]$key return $key } proc sleep { ms } { set uniq [ uniqkey ] set ::__sleep__tmp__$uniq 0 after $ms set ::__sleep__tmp__$uniq 1 vwait ::__sleep__tmp__$uniq unset ::__sleep__tmp__$uniq } proc cputs {dest string} { if { ! [info exist ::tk::my_color_set] } { set ::tk::my_color_set 1 console eval { .console tag configure green -foreground \#00ff00 -background black .console tag configure yellowonblack -foreground yellow -background black -font {courier 14 bold} .console tag configure yellow -foreground yellow .console tag configure whiteonred -foreground white -background red .console tag configure red -foreground red } } console eval [list ::tk::ConsoleOutput $dest $string] } sleep 1000 wm geom . 200x200+100+100 sleep 2000 for {set m 0} {$m < 5} {incr m} { .b config -bg red -fg white sleep 50 .b config -bg white -fg red sleep 50 } parray env console show cputs whiteonred "white on red " cputs yellowonblack " And yellow on black and big\n"
Superlinux - 2014-05-05 12:29:55
I want to highlight a little thing which comes handy, and I know to any programmer this would look silly after you read it.
Now how about hearing the message of [ tk_messageBox ] ? Yes! I know there's [ borg speak $message ] ; but this is how you should utilize it:
set message "Warning! You are trespassing Java in Android using Tcl/Tk and AndroWish!" borg speak $message tk_messageBox -message $message -icon warning
set message "Warning! You are trespassing Java in Android using Tcl/Tk and AndroWish!" tk_messageBox -message $message -icon warning borg speak $message
This should show and prove you that [borg speak] works in a separate thread. -- RS 2014-05-08: As I just tested in an interactive wish on Windows 7, tk_messageBox just blocks until dismissed with the OK button.
HE 2014-08-17 I played today with menu and found it difficult to use them with the default font. I could read them but using them was quit difficult. The same with text inside entries and buttons. Comparing with windows I saw also that we can't be sure that we have STANDARD FONTS defined as a default value. And I saw that the font size results nearly to the same size regardless of the screen (at least on the both android devices, one 4" and one 8", and the win7 device). The following code changes the default value when used at the beginning of the code
option add *Menu.Font TkMenuFont widgetDefault option add *Button.Font TkTextFont widgetDefault option add *Entry.Font TkTextFont widgetDefault option add *Label.Font TkTextFont widgetDefault font configure TkMenuFont -size 12 font configure TkTextFont -size 12
I have to use 'font configure' because I couldn't find out how to change the named standard fonts with the option command.
The other value which is to small for me is the default width of the scrollbars. Looking for a device independent way I come to the following solution as a first draft:
set stdPixProMm 4 option add *Scrollbar.width [expr {16 * [winfo screenwidth .] * 1.0 / ([winfo screenmmwidth .] * $stdPixProMm)}] widgetDefault
The stdPixProMm defines the amount of pixels per mm on a standard screen. I'm not sure if this is the best value for it because I also found out that 'winfo screenmmwidth' and 'screenmmheight' on the win7 doesn't return the correct values. But the result provides on all three devices scrollbars with a width which is usable with fingers.
kc - 2014-09-30 03:17:15
Can anyone tell how to adjust screen brightness in androwish? I tried "borg content update" but it won't work.May be done with wrong parameter.Please help!
JDA - 2015-01-16 17:15
Is there a means in androwish to access openGL libraries?
Androwish rocks! I just discovered Androwish. I was able to download, install, and build the sample helloTclTk example and run it on my Motorola cell phone in addition to porting a small Tcl script. This all in less than a few hours (did not know how to build an android app). Androwish is simply awesome. Thank-you!!
chw 2015-02-27: The following solution works OOTB due to the default setting of "sdltk touchtranslate ...". It uses the middle mouse button emulation for panning the entire canvas with fast wipes. Slow wipes deliver still left mouse button events e.g. for moving the currently active canvas item.
set canvas [canvas $base.canvas -xscrollincrement 1 -yscrollincrement 1] # following lines borrowed from /assets/sdl2tk8.6/demos/items.tcl: bind $canvas <2> "$canvas scan mark %x %y" bind $canvas <B2-Motion> "$canvas scan dragto %x %y 1"
HaO 2019-05-07: I also tested it with text and tablelist widget with positive result:
set text [text $base.t ...] bind $text <2> "$text scan mark %x %y" bind $text <B2-Motion> "$text scan dragto %x %y"
For tablelist, it was helpful to configure -selectable 0 to all columns to not interfere with selection.
set table [tablelist $base.t ...] bind [$table bodytag] <2> "$table scan mark %x %y" bind [$table bodytag] <B2-Motion> "$table scan dragto %x %y" ... for {set row 0} {$row < [$table index end]} {incr row} { $table rowconfigure $row -selectable 0 }
chw 2015-09-11: Minimalist webcam using AndroWish's borg camera command
# http://<ip-of-device>:8080/.... takes a JPEG picture proc init {} { destroy .label borg camera close catch {image delete img} image create photo img -width 640 -height 480 borg camera open borg camera parameters picture-size 640x480 jpeg-quality 80 bind . <<ImageCapture>> {borg camera image img} borg camera start pack [label .label -image img] socket -server request 8080 } proc request {sock args} { chan configure $sock -translation binary -blocking 0 -buffering none after 100 catch {chan read $sock 1000} err chan configure $sock -blocking 1 if {![borg camera takejpeg]} { chan close $sock return } bind . <<PictureTaken>> [list send_jpeg $sock] chan puts -nonewline $sock \ "HTTP/1.0 200 OK\rConnection: close\r\nContent-Type: image/jpeg\r\n\r\n" } proc send_jpeg {sock} { bind . <<PictureTaken>> {} catch {chan puts -nonewline $sock [borg camera jpeg]} catch {chan close $sock} borg camera start } init
JM 9/5/2017, when using the webcam example from the VFS mounted assets folder, something does not work on my phone to get the IP address and appears OFFLINE, but it is actually ONLINE.
Other than that, knowing the IP address by means of SSHDroid, the sample works great.
JM 9/28/2019, A fix for the above as follows:
proc netstat {} { set url OFFLINE set col red if {[string match "wifi*" [borg networkinfo]]} { set wifi [borg systemproperties wifi.interface] if {![catch {set ip [borg systemproperties dhcp.${wifi}.ipaddress]}] && ($ip ne "")} { set url "http://${ip}:${::port}/" set col green unset wifi } } else { array set t [borg tetherinfo] if {$t(active) ne ""} { catch {set wifi [borg systemproperties wifi.tethering.interface]} if {![info exists wifi]} { set wifi $t(active) } } } if {[info exists wifi]} { catch { set ip [exec ifconfig $wifi] set i [lsearch $ip inet] if {$i > 0} { set ipAddr [lindex $ip $i+1] set ip [lindex [split $ipAddr :] 1] set url "http://${ip}:${::port}/" set col green } } } .c itemconfigure txt -text $url -stroke $col }
Provided wifi hardware exists, and the device is connected by dhcp:
borg systemproperties wifi.interface ;# find wifi interface, here 'wlan0' borg systemproperties dhcp.wlan0.ipaddress ;# find device ip address for the given interface, i.e. 'wlan0' borg systemproperties dhcp.wlan0.server ;# find access point address
dzach 2015-11-18: chw's creative frenzy continuously sprouts new functionality and tips. Here is his reply to a request for turning on|off the camera's LED:
[Camera's LED c]an be controlled with "borg camera" command but is device dependent. On my smartphone (HTC One V) this sequence works: borg camera open # LED on borg camera parameter flash-mode torch # LED off borg camera parameter flash-mode off
dzach 2015-12-26: chw mentions the source code of Android as a place to find more uses for content://.... Indeed, using the source code is the fastest way to get some guidance in the class hell of Android. Here is how to gain access to the contacts content, found in .../android-sdk-linux/sources/android-23/android/provider/ContactsContract.java:
set cursor [borg content query content://com.android.contacts/contacts] while {[$cursor move 1]} { puts [$cursor getrow] } $cursor close
or
content://com.android.contacts/data/phones
to get the contacts phones listed, or use
content://com.android.contacts/contacts/filter/<put filter data here> content://com.android.contacts/data/phones/filter/<put filter data here>
to get filtered contact results.
If, instead, you want to bring up the contact picker to select a contact from there, and return it to your app, then you can use the following:
borg activity android.intent.action.PICK {} "vnd.android.cursor.dir/contact" {} {} {} callback
or
borg activity android.intent.action.PICK content://contacts/people {} {} {} {} callback
and then, after having picked a contact, use the result returned by the callback in a borg content query content://... call to get the contact info needed.
2019-05-07 HaO:
The following code snipped gives the framework to create a pdf file using pdf4tcl and then open it. The file is created in the shared document folder.
# Get Android shared Document folder set documentFolder [borg osenvironment externalstoragepublicdir\ [dict get [borg queryfields android.os.Environment] DIRECTORY_DOCUMENTS]] # create folder, if it does not exist file mkdir $documentFolder # create pdf file set pdfFile [file join $documentFolder myfile.pdf] ::pdf4tcl::new pdf -file $pdfFile -unit mm # here are all pdf creation commands pdf destroy # Open pdf file for viewing borg activity android.intent.action.VIEW "file:$pdfFile" application/pdf
2019-05-07 HaO: This BWidget hack was introduced for Androwish. See on BWidget page.
2022-03-08HaO: Starting from Android 9, the device serial number is returned as "unknown":
% dict get [borg osbuildinfo] serial unknown
Programs should use the "ANDROID_ID " as a device identification.
To get the "ANDROID_ID, chw abstracted the following procedure from this thread :
proc get_droid_id {} { set cursor [borg content query content://settings/secure value name=? android_id] $cursor move 1 set droid_id [$cursor getrow] $cursor close return $droid_id }
2022-03-08HaO: The following trick (provided by author of Android easy phone app) sizes message boxes to vertical screen size:
option add *Dialog.msg.wrapLength [expr {int(0.6*[winfo screenwidth .])}]
2022-03-08HaO: AWDark is IMHO the best AndroWish theme:
Here is my own init which may use a custom font size:
package require awthemes set dFontSpec [font actual TkDefaultFont] # Set eventual custom font size here # dict set dFontSpec -size $Config(FontSize) set ScaleCur [expr { double([font metrics $dFontSpec -ascent]) / [font metrics TkDefaultFont -ascent]}] ::themeutils::setThemeColors awdark scale.factor $ScaleCur # >> Setup dot scrollbar for mobile skin ::themeutils::setThemeColors awdark\ style.progressbar rounded-line\ style.scale circle-rev\ style.scrollbar-grip none\ scrollbar.has.arrows false package require awdark ttk::style theme use awdark ::ttk::theme::awdark::setMenuColors -optiondb