Remote Android Scripting with Python

In a previous post, Android Scripting was described. Once you have established the ability to use the Android Scripting Layer for Android (SL4A) on your device, you may be frustrated trying to type your scripts on your device, especially if you have a soft keyboard.

Fortunately, if you have installed the Android Software Development Kit (SDK) on your computer, there are several options. Below is my summary of some of the techniques described at http://code.google.com/p/android-scripting/wiki/RemoteControl. Being a big fan of Python, the interpreter I chose to use was python. This required this android.py file to be downloaded either into my current directory, or added to my PYTHONPATH.

1.  You can type up your scripts on your computer and then upload them, or push them to your device. The default directory to place SL4A scripts on your device is /sdcard/sl4a/scripts. If you place your scripts there, then they will show up in your device's SL4A app when you start it. An example of the command to upload a script is: adb push /bin/sl4a/speak.py /sdcard/sl4a/

2. You can connect to your device with USB, and start a private server on a port on your device. You can then forward a port from your computer to that port on your device. This allows you to connect from an interpreter running in an interactive shell on your computer to the SL4A server running on your device.
  • Connect the USB cable to your device
  • Enable USB debugging on your device (Menu, Settings, Application Settings, Development)
  •  Start the SL4A server
    • adb shell  'am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER -n com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher'
    • Make note of  the port number in the SL4A device notification. Unfortunately, the method of specifying USE_SERVICE_PORT to set the port failed to work for me and others
  • Forward a local open port to the port that was found. Assuming 9999 is an available port on your computer and port 43917 was displayed in the device notification, you would use: adb forward tcp:9999 tcp:43917
  • Set or export the AP_PORT variable to your computer port: export AP_PORT=9999
  • Start an interpreter compatible with one installed in the SL4A environment in your device like Python.
  • python
Python 2.7 (r27:82500, Aug 07 2010, 16:54:59) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import android
droid = android.Android()
name = droid.dialogGetInput('What is your name?')
print name.result
droid.makeToast('Hello ' + name.result + '!')

3. You can also connect your device to a network shared by your computer and start a public server on a port on your device. You can then forward a port from your computer over the network to that port on your device. This allows you to do something very similar to previous example.

  • Connect your device to a network shared by your computer. Assuming that it is a wireless network, use Menu, Settings, Wi-Fi Settings and enable Wi-Fi. Now, connect to one of the networks by tapping on it, and authenticating if necessary. After it has connected, tap on it again to check the IP address. This example assumes the address was found to be
  • Start the SL4A server and make note of  the port number in the SL4A device notification.:
    • If you are connected using adbWireless Tether or something similar run: adb shell 'am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER -n com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher --ez com.googlecode.android_scripting.extra.USE_PUBLIC_IP true'
    • If you are not connected, then on the device, type in a terminal or  execute a script which contains:
    • am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER -n com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher --ez com.googlecode.android_scripting.extra.USE_PUBLIC_IP true
  • Set or export the AP_PORT variable to the device port: export AP_PORT=52177
  • Set or export the AP_HOST variable to the device IP: export AP_HOST=
  • Start an interpreter compatible with one installed in the SL4A environment in your device like Python.
  • python
Python 2.7 (r27:82500, Aug 07 2010, 16:54:59) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import android
droid = android.Android()
# if AP_PORT and AP_HOST not set use "droid = android.Android(('', 52177))"
name = droid.dialogGetInput('What is your name?')
print name.result
droid.makeToast('Hello ' + name.result + '!')


Android Scripting

The Scripting Layer for Android (SL4A) Project is not in Google's Android Market but it can be downloaded to your Android device to allow you to use multiple scripting languages. Warning, a quote from the SL4A site: "SL4A is designed for developers and is alpha quality software." 

An impressive list of languages are available: LuaBeanShellPythonPerlJRubyTclJavaScriptRubyShell.

Whatever code you write can automatically be executed with TaskBomb using the SL4A Script Launcher.

For support, there's a google group for that: http://groups.google.com/group/android-scripting/.


MySQL Tidbits

After installing mysql-server on Fedora 15:

# chkconfig mysqld on
# service mysqld start
# mysql_secure_installation

For the firewall, secure port 3306.

After starting the database server mysqld, it's now time to create a database, table, add data, and a user with full permissions using the client, mysql:
# mysql -u root -p
mysql> CREATE DATABASE mydb;
mysql> USE mydb;
mysql> CREATE TABLE questions (
> question TEXT);
mysql> INSERT INTO questions VALUES (0,"Who created Linux?");
mysql> GRANT ALL ON mydb.* TO 'dbuser'@'localhost' IDENTIFIED BY 'password';

To backup a MySQL database, use the mysqldump command:

mysqldump -u root -p mydb > mydb.db

To restore a MySQL database, first drop the database, then create the database and use mysql to restore it:

mysql -u root -p

mysql> drop database mydb;
Query OK, 15 rows affected (1.85 sec)

mysql> create database mydb;
Query OK, 1 row affected (0.00 sec)

mysql> quit

mysql -u root -p mydb < mydb.db



The Computer - A poem I wrote in 1984

The Computer
Central is the processor,
core of the complexity.
Peripherals are the sectors,
basic to the entity.
A soft touch, a character is read,
it’s image echos on the monitor bright.
A disk drive scratches its head,
for the data to read or write.
The transfer of information,
bytes and bits passed in a pulse.
A bit of logic improves calculation,
but life is not true or false.
The law of imperfection states:
that output to input is inferior.
Our dull duties are done at quicker rates,
so we can proceed to business superior.
The computer is our world altering,
but we are the ones who posed it.
Shrink away those who fear the evolving,
or be of the ones who profit.
Keith Wright
January 22, 1984


Differences in Solaris compared to Linux

Differences in Solaris 10/11 compared to Linux


Oracle has a good listing of system administration tools for Solaris 10 and RHEL 5 side-by-side:

//cdrom/volume used as an automatic mount point instead of /media or /run/user/
/etc/shells - Man page exists in Solaris, but file is missing.

To install VirtualBox Guest Additions use: pkgadd -d /cdrom/vbox-guest-additions-cdrom/VboxSolarisAdditions.pkg. This installs the package SUNWvboxguest.

ping -I 1 sol10 64 5 - ping at one second intervals host sol10 with 64 byte packets 5 times

catman - Command to build the man page indexes (windex) instead of makewhatis.

Software Management
Another blogger made a great summary at http://sol10pkgmgmt.blogspot.com/

pkgadd -d virtualboxguestadditions.pkg to install a software package.
pkgadd -d . SUNWbash to install from a filesystem directory.
pkginfo -  view installed package information
pkginfo -d /cdrom/cdrom0/Solaris_10/Product/ -  view package information from a directory (cdrom)

sys-unconfig Unconfigures a system, removing it's name and IP address information. Upon the next boot, the system will prompt for the new configuration.  Starting with Solaris 11, the command has been replaced with sysconfig.

touch /reconfigure - have system re-detect devices such as additional hard drives
Then use the format command to make the fdisk partition, the partition slices, and the disk label.  Use the following commands from the format prompt to carry out these actions:
  • fdisk
  • partition
  • label

useradd -m username If you don't use the -m option with Solaris, then it won't create the user's home directory.
find The find command is aware of the file time stamps in days: -atime, -mtime and -ctime, but not in minutes: -amin, -mmin, and -cmin.


The default gateway or router entry is placed in /etc/defaultrouter in Solaris 10.
The hosts table is maintained in /etc/inet/hosts file in Solaris, instead of /etc/hosts in Linux.
Combined with the /etc/inet/netmasks file in Solaris, this determines the interface configuration.
The /etc/resolv.conf file is used for DNS resolution, but it does not exist by default.
Use ifconfig -a to view all interfaces.
ifconfig e1000g0 down to bring down that interface
ifconfig e1000g0 plumb up to bring up an interface
rup - will ping all hosts in the /etc/inet/hosts file

This Pocket Survival Guide to Solaris is very helpful for typical system administration tasks: http://www2.fiu.edu/~tho01/psg/sol.html

Listing services

Starting a service 

# svcadm enable svc:/network/login:rlogin

Usage: svcadm [-v] [cmd [args ... ]]

        svcadm enable [-rst] ...      - enable and online service(s)
        svcadm disable [-st] ...      - disable and offline service(s)
        svcadm restart ...            - restart specified service(s)
        svcadm refresh ...            - re-read service configuration
        svcadm mark [-It] ... - set maintenance state
        svcadm clear ...              - clear maintenance state
        svcadm milestone [-d]       - advance to a service milestone

        Services can be specified using an FMRI, abbreviation, or fnmatch(5)
        pattern, as shown in these examples for svc:/network/smtp:sendmail

        svcadm svc:/network/smtp:sendmail
        svcadm network/smtp:sendmail
        svcadm network/*mail
        svcadm network/smtp
        svcadm smtp:sendmail
        svcadm smtp
        svcadm sendmail

Shutting Down Solaris 10 

init 5 - to power off the system in Solaris. This would put most Linux distros into a graphical mode.
init 0 - to put the system in a state where it is safe to power off (PROM prompt on SPARC)

Sections of the Manual are Different

Basic user commands
System Admin commands
OS Calls
Library functions
Configuration files
Miscellaneous topics
Games and demos
Hardware and device driver files
DDI (Device Driver Interface) and DKI (Driver/Kernel Interface)
To view a manual section, you use the -s option in Solaris
man -s 4 passwd
Instead of the Linux method
man 5 passwd

Disk Management

du -k - show in kilobytes instead of 512byte sectors.  There is also a -h option.
df -k - show in kilobytes instead of 512byte sectors.  There is also a -h option.
quot -a - show all users usage of the filesystem

fdisk /dev/rdsk/c0t3d0p0 - create an initial partition before being able to use as a volume
metadb -a -f c0t3d0s2 - force creating a replica database
metainit d21 1 1 c0t3d0s2 - create a RAID 0 device
fdisk /dev/rdsk/c0t4d0p0 - create an initial partition before being able to use as a volume
metadb -a -f c0t4d0s2 - force creating a replica database
metainit d22 1 1 c0t4d0s2 - create a RAID 0 device
metainit d25 -m d21 - create a RAID1 device
metattach d25 d22 - attach the second mirror
newfs /dev/md/rdsk/d25 - create the file system
mount /dev/md/dsk/d25 /testing - mount the new file system

newfs /dev/md/dsk/d25

Single User Mode

In Linux, you can get to single user mode on an init-based system by appending an "S" to the kernel line in the bootloader.  If the Linux system uses systemd instead of init, then you can append the kernel line with "systemd.unit=rescue.target".

In Solaris, you can get to single user mode by appending "-s" to the kernel line in the bootloader.

     The following command restricts the running services to sin-
     gle user mode:

       # svcadm milestone milestone/single-user

     The following command restores the running services:

       # svcadm milestone all

On a standard keyboard use CTRL+PAUSE+A

SUSE Enterprise Linux Server 11

Since the early 90's most of my Linux experience has been with Redhat or Redhat-derived distributions like RHEL, Fedora, and Centos. As the company I work for is no longer partnered with Redhat to provide training, I am not having to teach as much Redhat system administration. Instead, I'm branching out into other distributions, like Ubuntu, and the subject of my post today: SUSE.
Over the weekend, I signed up for the free trial and downloaded the SUSE Enterprise Linux Server (SLES) 11. This morning, I had the joy of installing SLES. I was very pleased with it's installer. I had issues at first with getting the video resolution to work on the old computer I was attempting to install it on. No problem, the installer has a function key to change video resolution. The installer wanted to partition the internal hard drive, but I wanted to install on to an USB key. Again, no problem, there was a very intuitive and powerful graphical partitioning tool. I'm not sure why it took a couple of hours to complete, I would have thought that installing to a USB Flash drive would have been faster, but that may have been caused by the slow DVD drive.
Now, that the system is up and running, I want to start blogging some of the key differences between SUSE and RH:

RH uses the Gnome Desktop Environment by default and SUSE uses KDE, but both desktops are available in both distributions. The SUSE desktop only uses a bottom panel with a single menu at the left side of the panel that allows the user to access applications, documents, places, devices and their settings easily. It has obviously been customized with a professional appearance. In contrast, the RH systems seem to ship with the standard Gnome desktop.

Both systems distribute software as rpm files, and low level software information can be obtained with the rpm command. SUSE uses zypper as it's front end, instead of RH which uses yum. SUSE is configured by default to allow you to install additonal software from the DVD, unlike RH where that would need to be manually configured. Most of the yum configuration is done in /etc/yum.conf and /etc/yum.repos.d/ directory, which zypper is configured with /etc/zypp/zypper.conf and /etc/zypp/repos.d/.

For installing debug-info rpm packages, RH derived use debuginfo-install and SUSE derived use pk-debuginfo-install. Where RH uses yum provides \*/command to locate the package to install for a specific command, SUSE uses cnf command, or you can zypper search command.

While RH has gone from SysVInit, to upstart, and even is experimenting with systemd in Fedora, SUSE still uses SysVInit. So, for RH you must be aware of either upstart scripts in /etc/init, or whatever systemd uses, and learn a new way to configure services to start. With SUSE, it is still the traditional /etc/inittab, /etc/rc#.d, and the scripts in /etc/init.d/. Both support using chkconfig for easily managing which services will start at which runlevels. They both also have support for the service command to start, stop, reload, and check the status of services. Interestingly, in SUSE, every script in /etc/init.d is linked to a file in /usr/sbin/. For example, /etc/init.d/sshd can be run with /usr/sbin/rcsshd.

RH has moved up to ext4 file system for it's default, and SUSE doesn't have default support for it yet in 11.2, but it is the default in OpenSUSE. For SUSE, the package ext4dev-kmp-default is available as a Technical Preview. I tried to install the ext4dev-kmp-default, but I was still unable to mount an ext4 file system with SUSE.

RH uses SELinux to protect the system against mis-behaved processes, while SUSE still uses AppArmor. I thought that I had heard that SUSE was going to be using SELinux, but there does not seem to be any trace of it. From what I understand, SELinux provides better protection, but is more difficult to configure. Whereas, AppArmor can be fooled with linked files, it is designed to be much easier to use.

Now, with RH you get a notification if you have SELinux Troubleshooter installed, however if have not found an equivalent for AppArmor.

The locate command is not available by default in SUSE, so install the findutils-locate package to be able to use the locate command.


Motorola Droid Bionic 4G Issue and SD Card path

The very day after my previous post on the Droid Bionic, where I had said I had heard of people having 4G issues, then I began to experience those issues myself. If I turned the phone off, and started it back up again, it would come back to using 4G, but only for a minute or two. The same thing would occur if I toggled airplane mode. After tolerating the situation for several days, I decided I wanted to take the phone in to see if I could get it replaced.
As I planned to reset the phone completely, to also assure myself that it wasn't some kind of software glitch, I wanted to back up all my photos, videos, and music. So, I plugged my phone into my computer, and switched the USB connection to USB Mass Storage. I'm using CentOS 6, so the devices mounted under /media, but both as /media/MOT. I think I should backup, relabel and restore my external SD card, so it can mount under a different path.
Unless, you know what directories and files you have stored where, then it would be difficult to tell which is the internal and which is the external memory. Unfortunately, the way Motorola has the paths internally defined, the internal SD card path is /mnt/sdcard/ (or /sdcard) and the external SD card path is /mnt/sdcard-ext (or /sdcard-ext). Knowing the paths can me the confidence that I had copied everything from the internal /sdcard to the external /sdcard-ext.
Of course, I have the Android SDK installed, so I can start up a shell on my phone with:
adb shell
Next, I could look for the directories or folders to backup from the internal card with:
ls /sdcard
Then, for each folder to backup, I executed something like:
cp -r /sdcard/dcim/ /sdcard-ext/
With the backups all done, and resetting the phone to factory complete not fixing the problem, I headed off to the Verizon store to spend two hours watching the guy try to get my phone to work for more than a minute. I was amazed in one minute where my phone was downloading at a rate of 27,000 kbps! At my house, the best I can normally do is around 18,000 kbps. He reset the phone to factory again, he pulled and reset my SIM card, he exchanged my SIM card, he made sure there were no problems with my account, and with the 4G network. It was obvious after all the testing and troubleshooting, when he could set his phone down and have full bars of 4G, and mine would drop 4G and go to 3G that there was a problem with my device. Yet, he would not admit to it, and I started to get irate.
When they were refusing to agree that there was a problem with my phone, that first they needed to escalate the issue to a "real" technician before they could be sure that there was actually a problem with my device, I threatened to simply return my phone. This got a manager's attention, and he offered me free data service while I was waiting for a "real" technician to contact me. As that would not add up to two dollars, I counter-offered that I wanted to get a free cover, and showed him the $14.99 silicone cover that I had been considering. He agreed, and credited me with a free cover, and I agreed to wait for the "real" technician to contact me within 24-48 hours.
My visit to the store was on a Saturday, so I felt it fair to wait until Tuesday before they contacted me. Wednesday morning, I got a call from an unidentified caller and ignored it, waiting to see what the voicemail was about, but none was left. I called 611 with the feeling that perhaps it was Verizon, and sure enough it had been. I don't know if they were planning on sending me a new phone or not, as the woman started to say, "the resolution is that because you live in an area that is known to have problems...", I interrupted her.
I told her, "Stop right there, that is not a resolution. I paid for a phone to have 4G, and I want to have it. My phone did have 4G for the first couple of weeks, and then it stopped working correctly. I spent two hours in the store on Saturday, and everyone else could keep 4G, but me. I want it replaced, or I will return it". She very nicely said, "I will help you with that." Two days later, and I got my new phone. I don't want to jinx myself, but for at least the last three days it has been working well with 4G.


Motorola Droid Bionic Rules

I've had my Droid Bionic now for just under a month, and overall, I am very impressed by it. Some technical specifications that make it special right now on Verizon:
  • Dual Core 1 Ghz Processors
  • 4.3 inch qHD (960 x 540) PenTile Display with Gorilla Glass
  • 4G LTE
  • Android 2.3.4 (Gingerbread)
It took more than two weeks of running the phone before I was even able to lock it up and did my first battery pull. That was because I had threads out of control on the application I was developing and was trying to power off. The second time I pulled the battery because I was listening to Amazon on my device, and started NFL Mobile. Everything was working fine, NFL Mobile was playing, but refused to stop!

The other weird thing that I noticed about the device was that it would go to sleep while you were on a phone call. If I was using either the speaker or bluetooth, and let the display timeout, then it would not wake up to the touch. If I touched the power button, then the call was terminated. I found two solutions to this problem. At first, I would just plug the device in, and it would wake up to the lock screen. Then, I found an app called Screeble that would wake the phone up for me by properly detecting my proximity.

While Motorola has been careful to use things like the more energy efficient and brighter qHD RGBW PenTile display, the device still consumes the battery heavily while downloading data over 4G LTE. Fortunately, there is a Preference for disabling 4G and using 3G only. This can be especially helpful if you are just on the fringe of 4G coverage. If the device keeps switching back and forth from 4G to 3G, and you are using data, I have seen it go from 100% to 40% battery in just about an hour.

Finally, let me say some things about 4G. It can be great! While waiting for luggage, I watched NFL Mobile without any problems at the Denver International Airport. I noticed that the clarity is better on 4G than on 3G. That's the good part. The bad part is that 4G is available in limited areas, and as mentioned before, if you are on the fringe it can be better to just turn off 4G, or else your battery will get wasted. Some Bionics are apparently having trouble keeping a 4G connection. At first, this did not seem to affect me. Though lately, I've noticed the phone dropping to 3G while I am in a 4G area. Sometimes toggling airplane mode will get it to go 4G, other times, I have to reboot to get 4G working.

For a long list of other Motorola Droid Bionic bugs, check this website: Bionic Bug Fix Update Coming in November. Just stumbled upon an unadvertised feature of the Bionic. It has a FM Radio tuner like the Droid 3. You can read more about and install the apk from this site: Droid Bionic FM Radio. I personally tested it and it works.


GPS Map Honeycomb Android 3.0

Last weekend, I finally got around to updating GPS Map and GPS Map Pro to be compatible with Honeycomb (Android 3.0). I got tired of waiting for a stable build of Honeycomb for my Samsung Galaxy Tab. I tried out a build from XDA Developer Spacemoose1 a while ago, but it wasn't stable enough for daily use. I'm still looking forward to the build, but I went ahead and created a Honeycomb emulator with the Android SDK on my computer for testing. It was painfully slow, but it helped me to get the job done.

Updating my apps to be compatible with Honeycomb was much easier than I thought. There were two things that were causing problems: startManagingCursor(someCursor) and someCursor.close(). Once these were commented out, then my apps ran fine. I guess Android will just have to clean up the garbage left behind by those open cursors until I make a separate version to use CursorLoader...


Send MMS to a phone

I was reading the forums.xda-developers.com and ran across an interesting solution for the CM7 ROM on the Samsung Fascinate which cannot send or receive MMS. You can send an MMS by sending an email with attachments to the following major US carriers using the recipients phone number instead of xxxxxxxxxx:

Alltel – xxxxxxxxxx@message.alltel.com
AT&T – xxxxxxxxxx@mms.att.net
Boost Mobile – xxxxxxxxxx@myboostmobile.com
Einstein PCS – xxxxxxxxxx@einsteinmms.com
Sprint – xxxxxxxxxx@pm.sprint.com
T-Mobile – xxxxxxxxxx@tmomail.net
US Cellular – xxxxxxxxxx@mms.uscc.net
Verizon Wireless – xxxxxxxxxx@vzwpix.com
Virgin Mobile – xxxxxxxxxx@vmobl.com
Nextel – xxxxxxxxxx@messaging.nextel.com


Compiling packages under /usr/local

Trying to compile packages, sometimes I build a package, and the next package I try to compile is unable to see the newly built package. The problem lies with how Fedora is configured with pkg-config, which by default does not find libraries under /usr/local/lib.

Adding a file like local.conf to /etc/ld.so.conf.d containing:

Then, executing:

Solves the problem!

Another solution is to set the PKG_CONFIG_PATH environment variable:

export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig


Samsung Galaxy Android Devices

I'm the proud owner of a Samsung Fascinate and Samsung Galaxy Tab (7").
I'm impressed by the ease by which firmware can be loaded directly without having to use a recovery program, although the familiar ClockWorkMod recovery and others are available for both devices. For Windows users there are two programs that let you load firmware directly, heimdall and odin. For Linux users there is just the one, heimdall. Unfortunately, some rom developers only package their roms in just one of these file extension formats: .zip for the recovery programs, .tar.md5 for odin, and individual files such as:
for heimdall. Fortunately, you can just unzip, or tar -xf the packaged archives to install most archive packages directly. Beware, some .zip files may also have script files that have to be run by the recovery program to work correctly, and may be specific to certain versions of recovery programs.
To be able to flash these files using heimdall, the device has to be put into download mode:
adb reboot download
Or, by holding home+volume down+power at boot time, or just volume down if the battery is removed and the phone is connected to the computer via usb.
Once the device is in download mode, to load a custom recovery then execute:
heimdall flash --recovery recovery.bin


Android Networking Interface Information or What is my IP address?

If you want to know what your IP address is while on your Android phone, and you have terminal, then you might try as I did tonight. I opened up a terminal application and tried:



ifconfig -a

Nothing again! Searching I found that I needed to specify the name of the network interface, or else it would not work. I also discovered that I could find all the names of interfaces by doing:

ls /sys/class/net/

So, for most phones the name to use from this list is eth0. To find out my IP address on my phone, I finally ran in my terminal application:

ifconfig eth0

I even tried this without root access, and it works!


Lessons Learned Maintaining Multiple Versions of an Android App

Since I've been trying to maintain both my GPSMap Pro and GPSMap Android applications, I've had to either refactor GPSMap Pro to be based upon updated code developed for GPSMap, or refactor GPSMap to be based upon code developed for GPSMap Pro. Tonight, I will be attempting the latter.

The first thing I do is back up and verify my backup of both applications. I've not had to restore from the backup yet, but this is just something that would be foolish to not do. A mistake or two and possibly either one or both of my applications could be damaged or gone, and should this occur, I can simply restore my backup(s). I use the Eclipse editor to do my development. It is easy to create a backup with the following choice from the menu:

File -> Export -> General -> Archive File -> Next -> Select Project -> Select To Archive File Path -> Finish.

To restore, you can delete the damaged project, and then import the archived file.

Second, I delete the project that is to be based upon the other project. In this case, I right clicked on the GPSMap project in Eclipse and choose Delete. Since, this only removes the project from Eclipse, and I want to keep all my projects in the same workspace, I then rename the directory for the project.

Third, I create a new project of the name that I want to be based upon the other project. Tonight, this is again the GPSMap project.

File -> New -> Android Project
Project Name: GPSMap
Selected Create New Project in Workspace
Either use default location, or use the Browse button to locate where to put the project
Select the Build target to match what API the applications use.
Enter the Package Name: com.appspot.wrightrocket.GPSMap
Unselect Create Activity
Click Finish

Fourth, I begin copying and pasting the various source files from the base project to the derived project. If someone knows an easier way, then I would gladly embrace it. I've tried importing, and creating a new project based upon an existing project. It seems what stops me from doing this is that I already have a project of that name in my workspace.

Shift click all in this directory, copy and then paste into this directory:
src/com.appspot.wrightrocket.GPSMapPro/* -> src/com.appspot.wrightrocket.GPSMap
src/com.android.vending.licensing -> src/ (Package doesn't exist so whole package pastes)
src/com.android.vending.licensing.util -> (Package doesn't exist so whole package pastes)
res/drawable -> res/ (The drawable directory doesn't exist so the whole directory pastes)
res/layout/* -> res/layout/ (Overwrite existing files)
res/values/* -> res/values/ (Overwrite existing files)
res/xml -> res/ (The xml directory doesn't exist so the whole directory pastes)
lib/* -> lib/ (Create lib directory with File -> New -> Folder)

Right Click GPSMap -> Build Path -> Add Jars -> GPSMap -> lib/GoogleAdView.jar -> OK

Fifth, I clean up any errors that might exist in the code. With the remaining source files that had errors, all that I had to do was delete some of the imports that referenced non-anonymous listeners in the code, and still referred to the base project (GPSMapPro instead of GPSMap).

This step went a lot smoother this time, since I have taken the following actions:

No class has public variables that are referenced by another class. Instead variables that need to be shared, are set or get using a SharedPreferences object. This was something that I had to refactor. It was a problem especially when the default activity for the application was the class that other classes referenced the public variables.

The class that is the default activity for the application is not named based upon the application name.

I'm thinking I should try to get rid of all non-anonymous listeners, and this step could be eliminated. For some reason, I can't seem to make an anonymous listener for the spinners...

Sixth, the res/values/strings.xml file needs to be edited so the app_name string is set correctly. Tonight, I just had to delete the word Pro. It was easy to search and manually replace GPSMapPro with just GPSMap.

Seventh, the PRO preference has to be changed to false. I set this in my main activity, but other activities can get this preference. This is how I can determine in my code whether the user is using the PRO version and alter the presentation of the application.

Eighth, I uncomment the code that displays the ads in the non-Pro version. Ouch! I just got my first glitch. The layout of the PRO version main activity does not have a R.id.adview, so I've got to either remember where I want to put that in the xml file, or I could restore the layout for that activity from the backup... In the future, this won't be necessary, as I set the layout now based upon the PRO variable.

Ninth, the AndroidManifest.xml file had to be updated. The package name in this case needed to be modified to remove the word Pro off the end. Also the permission for checking the license is not allowed in the free version.


Setting up 389 Directory Server for LDAP

I needed to install a LDAP server on Fedora 14, so I chose 389-ds. It is very similar to the Red Hat Directory Server, so the documentation at http://docs.redhat.com/docs/en-US/Red_Hat_Directory_Server/8.2/html/Installation_Guide/index.html was very helpful.

After doing:
yum install 389-ds.noarch 389-ds-console.noarch 389-admin-console-doc.noarch 389-ds-console-doc.noarch389-admin-console.noarch 389-admin.x86_64


I got to this point:
389 Directory Server system tuning analysis version 10-AUGUST-2007.

NOTICE : System is x86_64-unknown-linux2.6.35.6-45.fc14.x86_64 (2 processors).

NOTICE : The net.ipv4.tcp_keepalive_time is set to 7200000 milliseconds
(120 minutes). This may cause temporary server congestion from lost
client connections.

I remembered I needed to do a little tuning. I added the following to get rid of:
NOTICE : The net.ipv4.tcp_keepalive_time is set to 7200000 milliseconds
(120 minutes). This may cause temporary server congestion from lost
client connections.
echo 'net.ipv4.tcp_keepalive_time = 600' >> /etc/sysctl.conf
sysctl -p

Then, I had to deal with this:
WARNING: There are only 1024 file descriptors (hard limit) available, which
limit the number of simultaneous connections.

WARNING: There are only 1024 file descriptors (soft limit) available, which
limit the number of simultaneous connections.

To gid rid of these messages, I added this to /etc/security/limits.conf

* soft nofile 8192
* hard nofile 8192

I also had to execute: su -
Once the new shell was started, then all the warnings were gone. You can just check for necessary tuning by running: dsktune

[root@ldap init.d]# /usr/sbin/setup-ds-admin.pl

This program will set up the 389 Directory and Administration Servers.

It is recommended that you have "root" privilege to set up the software.
Tips for using this program:
- Press "Enter" to choose the default and go to the next screen
- Type "Control-B" then "Enter" to go back to the previous screen
- Type "Control-C" to cancel the setup program

Would you like to continue with set up? [yes]:


Do you agree to the license terms? [no]: yes

Your system has been scanned for potential problems, missing patches,
etc. The following output is a report of the items found that need to
be addressed before running this software in a production

389 Directory Server system tuning analysis version 10-AUGUST-2007.

NOTICE : System is x86_64-unknown-linux2.6.35.6-45.fc14.x86_64 (2 processors).

Would you like to continue? [no]: yes

Choose a setup type:

1. Express
Allows you to quickly set up the servers using the most
common options and pre-defined defaults. Useful for quick
evaluation of the products.

2. Typical
Allows you to specify common defaults and options.

3. Custom
Allows you to specify more advanced options. This is
recommended for experienced server administrators only.

To accept the default shown in brackets, press the Enter key.

Choose a setup type [2]:

Enter the fully qualified domain name of the computer
on which you're setting up server software. Using the form
Example: eros.example.com.

To accept the default shown in brackets, press the Enter key.

Computer name [ldap.domain.test]:

The servers must run as a specific user in a specific group.
It is strongly recommended that this user should have no privileges
on the computer (i.e. a non-root user). The setup procedure
will give this user/group some permissions in specific paths/files
to perform server-specific operations.

If you have not yet created a user and group for the servers,
create this user and group using your native operating
system utilities.

System User [nobody]:
System Group [nobody]:

Server information is stored in the configuration directory server.
This information is used by the console and administration server to
configure and manage your servers. If you have already set up a
configuration directory server, you should register any servers you
set up or create with the configuration server. To do so, the
following information about the configuration server is required: the
fully qualified host name of the form
.(e.g. hostname.example.com), the port number
(default 389), the suffix, the DN and password of a user having
permission to write the configuration information, usually the
configuration directory administrator, and if you are using security
(TLS/SSL). If you are using TLS/SSL, specify the TLS/SSL (LDAPS) port
number (default 636) instead of the regular LDAP port number, and
provide the CA certificate (in PEM/ASCII format).

If you do not yet have a configuration directory server, enter 'No' to
be prompted to set up one.

Do you want to register this software with an existing
configuration directory server? [no]:

Please enter the administrator ID for the configuration directory
server. This is the ID typically used to log in to the console. You
will also be prompted for the password.

Configuration directory server
administrator ID [admin]:

Password (confirm):

The information stored in the configuration directory server can be
separated into different Administration Domains. If you are managing
multiple software releases at the same time, or managing information
about multiple domains, you may use the Administration Domain to keep
them separate.

If you are not using administrative domains, press Enter to select the
default. Otherwise, enter some descriptive, unique name for the
administration domain, such as the name of the organization
responsible for managing the domain.

Administration Domain [domain.test]:

The standard directory server network port number is 389. However, if
you are not logged as the superuser, or port 389 is in use, the
default value will be a random unused port number greater than 1024.
If you want to use port 389, make sure that you are logged in as the
superuser, that port 389 is not in use.

Directory server network port [389]:

Each instance of a directory server requires a unique identifier.
This identifier is used to name the various
instance specific files and directories in the file system,
as well as for other uses as a server instance identifier.

Directory server identifier [ldap]:

The suffix is the root of your directory tree. The suffix must be a valid DN.
It is recommended that you use the dc=domaincomponent suffix convention.
For example, if your domain is example.com,
you should use dc=example,dc=com for your suffix.
Setup will create this initial suffix for you,
but you may have more than one suffix.
Use the directory server utilities to create additional suffixes.

Suffix [dc=domain, dc=test]:

Certain directory server operations require an administrative user.
This user is referred to as the Directory Manager and typically has a
bind Distinguished Name (DN) of cn=Directory Manager.
You will also be prompted for the password for this user. The password must
be at least 8 characters long, and contain no spaces.
Press Control-B or type the word "back", then Enter to back up and start over.

Directory Manager DN [cn=Directory Manager]:

Password (confirm):

The Administration Server is separate from any of your web or application
servers since it listens to a different port and access to it is

Pick a port number between 1024 and 65535 to run your Administration
Server on. You should NOT use a port number which you plan to
run a web or application server on, rather, select a number which you
will remember and which will not be used for anything else.

Administration port [9830]:

The interactive phase is complete. The script will now set up your
servers. Enter No or go Back if you want to change something.

Are you ready to set up your servers? [yes]:
Creating directory server . . .
Your new DS instance 'ldap' was successfully created.
Creating the configuration directory server . . .
Beginning Admin Server creation . . .
Creating Admin Server files and directories . . .
Updating adm.conf . . .
Updating admpw . . .
Registering admin server with the configuration directory server . . .
Updating adm.conf with information from configuration directory server . . .
Updating the configuration for the httpd engine . . .
Starting admin server . . .
The admin server was successfully started.
Admin server was successfully created, configured, and started.
Exiting . . .
Log file is '/tmp/setupxvcTZ3.log'

If you were just following the Installation Guide, now you are stuck!
Next step, run:

Login with 'cn=Directory Manager'
The password you set.


Adobe Acrobat Reader 64 bit for Red Hat Enterprise Linux 6

I just got Adobe Acrobat Reader 64 bit for Red Hat Enterprise Linux 6 working, and it wasn't too easy. First, I downloaded a binary from http://get.adobe.com/reader/. I made it executable and ran it, but the program wouldn't launch.

Using 'strace -e open acroread', I could see it was trying to open a libxml2.so.2, but it wasn't seeing the one on my system under /usr/lib64. Doing a 'yum list libxml2\*', I could see there was also a libxml2.i686 that wasn't installed yet. After doing 'yum install libxml2.i686', the program started up a little further, but then complained about another missing library. More searching led me to do 'yum install gtk2-2.18.9-4.el6.i686'. At last, the Adobe Acrobat Reader 9.4 ran successfully.

Adobe Flash Player 10.1 64 bit for Red Hat Enterprise LInux 6 / Fedora 14

Recently I've upgraded both my laptop and desktop to 64 bit. I wanted to share how I got Fedora 14 working on my laptop and Red Hat Enterprise Linux 6 working on my desktop with Adobe Flash Player 10.1.

On both distributions, I found the same solution for how to get Adobe Flash Player worked. It was not installing an rpm file or setting up a yum repositority. Instead, I downloaded http://download.macromedia.com/pub/labs/flashplayer10/flashplayer10_2_p3_64bit_linux_111710.tar.gz from the http://labs.adobe.com/downloads/flashplayer10_square.html page. Adobe's download links lead me in circles when I first tried to get this working, but I finally searched their site and found this page to download the plugin.

To get Firefox to work, I extracted the downloaded file libflashplayer.so to each user's home: ~/.mozilla/plugins directory. For Google Chrome 64 bit to work with Adobe Flash, I had to create a /opt/google/plugins directory and then copy the extracted libflashplayer.so file into it. Remember to close all browser windows, and restart the browser for the plugin to take effect.

I resisted going to 64 bit Linux up until recently for this very reason: support for getting common things to work in 64 bit Linux lags, at least as of the end of January 2011.


Using Linux Kernel SysReq

The SysReq feature of the Linux kernel allows for special system requests to be sent to the kernel. This can be useful to get the kernel to do things that it wouldn't normally do for testing purposes. As I write this, I am trying to test the kdump feature of the kernel, which dumps the kernel memory when the kernel crashes. Using this feature I am able to cause a kernel crash by doing the following:

echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger

You can press Alt + SysRq + c (or whatever the character is that is listed below) to do the same thing, but on two out of the three systems I just tried this on it failed to work. It definitely does not work from within the GUI, as it triggers a Print Screen instead.

Besides just getting the kernel to crash, there are the following other system requests:

m: memory allocation information
t: thread information
p: CPU register and flag informationo
s: sync mounted filesystems
u: unmount all filesystems
b: reboot immediately
o: poweroff immediately

When the request is to do something to display information, then this data is typically dumped to /var/log/messages.

To permanently enable system requests, add to /etc/sysctl.conf the following:
kernel.sysrq = 1
To make system requests immediately available, run 'sysctl -p' as root or reboot.


Dad Died Day

After enjoying two weeks of vacation, the new year seemed to be off to a good start. At least January 1, 2011 was a good day. I got to talk to both of my parents, wish them a Happy New Year, and let them know that the Oklahoma Sooners (my Dad's favorite team) were on ESPN.
By the time they got to watching the game that night, it was already past half-time. My Mom said that Dad got to watch the first half of the game in the morning. As I watched it that night, I was enjoying it so much knowing that my Dad was watching it and enjoying it, too.
January 2, 2011 Dad died. I'm struggling to pull my head out of such a funk. I'm missing how much my Dad had shaped me throughout my life, and reflecting on what life will be like for my family without him.
It's just been a couple of days since this happened, so I feel like I'm just beginning the grieving process, and tomorrow, as I go to be with my family, I'm going to be diving into it deep. Next week, back to work, and a rapid track course to keep me busy. The usual routine might be what I'll be doing in less than a week, but it won't be the same after Dad Died Day.

About Me - WrightRocket

My photo

I've worked with computers for over 30 years, programming, administering, using and building them from scratch.

I'm an instructor for technical computer courses, an editor and developer of training manuals, and an Android developer.