Frink on Android

Frink Documentation * What's New * FAQ * Download * Frink Applet * Web Interface * Sample Programs * Frink Server Pages * Donate

Frink Documentation

This page only contains information about Android-specific features of Frink. For more information about Frink, please view the full Frink documentation.

Download Frink for Android

Frink for Android is available (for free!) in the Android Market from your Android device as "Frink Programming Language". (Search for "Frink" and you'll find it, or just scan the image to the right with an application like Barcode Scanner, or click that image if you're viewing this on your Android already. If you have installed it from here before, you will have to uninstall it before installing from the Market.

Note that the new Market application is severly broken! If you hit the "open" button after installing Frink, it will tell you it's not installed. But it installed just fine. Run it from the home screen as you normally would.

If you don't have access to the Android Market from your device, you can also download it here. (Note that this link may (rarely) contain experimental, unreleased versions.)

Features

Frink is available for the Android mobile phone platform, as well as for your other computers (Mac, Linux, Windows, etc.) The Android version provides a wonderful marriage between an easy-to-use programming language and a powerful, standardized platform with real-world sensors and other interesting features. It should work on all Android platforms version 1.5 and later. This is a full port of all of Frink's features, not a limited subset. (For a full list of Frink's features see the Features section of the main documentation.) The Android-specific features include:

Although great care has been made to use only functions that appear in Android 1.5, other functions are loaded by name to give access to sensors, GPS, and other later features.

Permissions

The Frink application currently requests permissions for the following:

Note that Frink doesn't use any of these unless a program you write or run uses one of the features listed.

In the future, versions of Frink might request almost all permissions for people who want to write programs that can access all of their phone's features. I may also maintain a limited version that doesn't request any permissions for the security-paranoid. (This will make features not work.) The internal Frink code will be exactly the same; it just differs in what I request in the AndroidManifest.xml file.

As you may know about packaging Android applications, if you want access to certain features of the phone, then you must request access to those features in the AndroidManifest.xml file when packaging. Even if you never use them, or don't use them now, if anyone wants to write programs that access these features, the package has to request access to them. There's no way to select just the features you want to enable, which is a failure of Google's security design and implementation.

I could create a crippled version of Frink that requests no permissions (but it won't be able to do lots of interesting things), and another version that requests all permissions so that power users can do whatever they want with their phone, without restrictions. It's likely, though, that if you're writing programs, you're some sort of programmer that understands the Android security model. And you hardly want me, or Google, or your wireless carrier, to tell you what you can or can't do with the phone you paid for. The point of Frink is to free you to do anything you can conceive, and not to hobble you arbitrarily.

By the way, I have no intention of creating a million distributions of Frink, each with a different permutation of requested permissions.

I wish that Android (and Java) had designed their security managers better; I'd always much prefer that a program only bother you with security requests when it actually uses them, so as not to create false scares. You could then choose something like "Allow this time only / Allow always / Don't allow this time / Never allow." And at that time, it could even give you usable information, like tell you what sites it's sending data to, what files it's opening, what phone information it's accessing, etc. That would give the user more flexible, fine-grained control over what their device is doing at any given time. It would also allow you to have better control over questionable apps. But that's nothing that anyone but Google can fix.

If I don't request permissions for features, programmers will never be able to access them. If there's a permission you need enabled to do your work, please let me know.

Android-Specific Functions

The following is a list of the additional functions that are available on the Android platform.

FunctionDescription
Text-to-Speech
speak[expression]Speaks the text aloud, using your device's default language settings.
speakln[expression]Speaks the text aloud, using your device's default language settings, and also performs a println of the same text.
speakSAMPA[string]Speaks the text aloud, treating the text as if it is specified phonetically using the Extended SAMPA alphabet. (Link opens in new window.) This allows you to specify the exact pronunciation of text. For example, to speak my name more or less correctly, you can try:

speakSAMPA["{lVn i:.\"li:VsVn"]

Note that the quote mark " in the middle of the string has to be escaped with a preceding backslash. You could eliminate the need for escaping by putting the text in triple quotes.

GPS / Location
getLastKnownGPSLocationJava[]Returns the last known location from the GPS provider as a Java object of type Location. Note that this does not start the GPS receiver and obtain a fix, but uses the last-known location from when the GPS receiver was previously enabled.
getLastKnownNetworkLocationJava[]Returns the last known location from the network-based location provider as a Java object of type Location.
startGPS[]Starts the GPS receiver.
getGPSLocationJava[]Returns the current-known GPS position as a Java object of type Location if one is available. Note that startGPS must be called before this will work. This function may return undef if a position has not yet been acquired. You will most likely not get useful data immediately. Typical usage is to poll this function every few seconds.
stopGPS[]Stops the GPS receiver. The GPS receiver will be automatically stopped when the program exits, but this should be called as soon as the GPS is no longer needed to preserve battery life.
getGeocoder[]Returns a Geocoder object which can be used to turn latitude/longitude information into a street address, or vice-versa.
getLocationManager[]Returns the Android platform's LocationManager as a Java object. This allows you to access location-specific services that are not available through the easier-to-use GPS functions listed above.
Sensors
getSensorService[sensorNum]Starts collecting data from the specified sensor and returns a SensorService object that can be used to get raw values from the sensor. The number should be one of the integer constants defined in SensorManager or Sensor (which are hopefully the same definitions, but the Android documentation doesn't seem to state this clearly.)
getSensorManager[]This function returns the Android device's SensorManager as a Java object. This allows you to access low-level sensor properties that are not available through the easier-to-use GPS functions listed above.
Programming
getActivity[]Returns the Android Activity of the current-running activity as a Java object. Note that an Activity is a Context, so in all the places you need a Context (say, to create GUI objects or get services,) you can use this object.
doUI[expression]Executes the specified expression on the Android's User Interface (UI) thread. Android requires that many methods, including anything to create views or user interface components, is executed on the UI thread. This allows you to create objects like Toast or access other user interface elements.

SensorService

A SensorService is an Android-specific object type that allows you to get raw values from and Android device's sensors. A SensorService object for the specified sensor is obtained from calling the getSensorService[sensorNum] function. The sensor number is an integer that corresponds to one of the constants defined in SensorManager or Sensor. It has the following methods:

MethodDescription
getSensorName[]Returns the name of the sensor.
getType[]Returns an integer representing the type of the sensor. The integer corresponds to one of the constants defined in SensorManager or Sensor (which are hopefully the same definitions, but the Android documentation doesn't seem to state this clearly.)
getRawValues[]Returns the latest raw values from the sensor as an array of floating-point values without dimensions.

Search Path

In programming mode, if a file has been saved, its directory will be added to the search path for use statements.

In interactive mode, or in programming mode where a file has not been saved yet, the search path will include the frink subdirectory on your removable media (SD card.) (The mount point as seen from your Android device is usually /sdcard/frink , or on later Android releases, /mnt/sdcard/frink).

Programming Tips

It can be cumbersome to write programs on a handheld device, so here are a few tips that might make the process easier:

Launching Files

Files with the extension .frink can be launched from applications like Astro, or launched with an Intent with the ACTION_VIEW action. (the data must be a Uri with a file: URL.) This allows you to, say, make a folder of Frink programs on your Android device that can be opened with a single click.

The following restrictions on launching files are for security reasons:

Memory Issues

Please keep in mind that Android devices have limited memory! While Frink tries hard to warn you of out-of-memory conditions, there's little or nothing reliable that you can do when no memory is available. Frink will try very hard to put up a warning if you run out of memory, but that is not always going to be reliable. If the Frink application simply silently disappears, that's an almost-certain indication that it ran out of memory. If this happens, make sure that the Frink application is stopped completely, and then try again.

You may need to make more RAM available to execute programs.

Note that RAM is not the same as free space on your slow SD card, but is the small, fast memory available to run programs (usually 256 MB or less,) which must be shared between all installed applications, running programs, and running services on your device.

(Your SD card may be large, but it can't be used for working memory in programs. It can only be written in large blocks, and takes thousands or millions of times longer to write than RAM, and can only handle a limited number of writes in its lifetime.)

The Android operating system will also limit the memory available to each process (usually to 16 MB or less, which is a fundamental limit for any Android program.) If you're hitting this limit, you may be unable to run your program on any Android device. (But you can still run Frink programs on your PC.) It's the nature of small, memory-constrained devices.

To free up memory, you may need to stop some running applications or background services, or uninstall unused applications to free up RAM.

In addition, stack size is very limited on Android devices. (By default, many platforms only allocate 8 kB of stack space.) In the programming mode for Frink on Android, the settings screen will allow you to request a larger stack space. Setting this value too high or too low may cause issues. An Android device is also not required to respect your request for more stack space. If you have problems running highly-recursive problems, you may be running out of stack space. Note that you must fully exit Frink and restart it for the new stack size to take effect!


Comments/questions to Alan Eliasen.

Back to Alan's Home Server