Using the Activity Starter Component

The activity starter component lets you combine applications by having one application start up other applications. Activity Starter is mostly for advanced developers, but it's a key way to extend the App Inventor, because it means lets you take advantage of applications written by others, and created with other development frameworks.

The apps you start can be App Inventor apps created by you or others; apps like Camera and Maps that are pre-installed on the device; or any app at all, created using App Inventor or not, as long as you have the necessary information to supply to the activity starter.

You can also start an application and get back a result from it to use in further processing, provided that the application is designed to a result. Presently, you can get back text results only.

To start another application, you must supply certain control information to the Android operating system. You do this by setting various properties of Activity Starter before calling the StartActivity method. This section gives some examples.

Starting Another App Inventor Application

You can start another app that was created with App Inventor if you know its package name and class name. If you have the source code of the app, you can find these names as follows:

  1. Download the source code to your computer.
  2. Using a file explorer or unzip utility, find the file youngandroidproject/project.properties.
  3. The first line will start with "main=". Everything after that is the package and class name.

For example, here is a first line you might see for an App named HelloPurr.:

main=com.gmail.Simpson.Homer.HelloPurr.Screen1

The gmail.Simpson.Homer part of the name comes from the App Inventor user account, such as, Homer.Simpson@gmail.com.

To start this app, you would use an activity starter component with these properties:

ActivityPackage: com.gmail.Simpson.Homer.HelloPurr
ActivityClass: com.gmail.Simpson.Homer.HelloPurr.Screen1

Invoking the activity starter's StartActivity method will start HelloPurr. When HelloPurr finishes (if it does), the original app's ActivityStarter.AfterActivity method will be invoked.

Note: If you are going to start another App Inventor app, make sure you use the correct package name. For example, if someone posts the source code (zip file) for an app, and you repackage that app, you'll end up with a different package name than he had. In cases of doubt, start the activity by hand and run "adb logcat" to view the Android system log and see what was actually started, as explained below in "Figuring out how to set the properties".

Starting a Builtin Phone Application

Apps that come with the phone can be invokd using package names and class names, as above. These apps can also launch response to an intent, which is the Android operating system's way of specifying something to do without necessarily designating a particular app. You can find information about intents (written for advanced developers) in the Android system documentation.

Some apps can take extra information when they are launched. For example, maps can take geographic information that specifies which map to display. Another example is launching a Web search with extra information that specifies the text to search for. You must consult documentation about the particular app to learn what this extra information is and how to specify it. Generally, you specify the information by setting the activity starter's properties just before the other app is launched.

Here are some examples:

Start the Camera

To launch the Android Camera app, use an activity starter with these properties:

Action: android.intent.action.MAIN
ActivityPackage: com.google.android.camera
ActivityClass: com.android.camera.Camera

This is pretty much what the App Inventor Camera component does, although it is much more convenient to use the Camera component.

Launch a Web search

To launch a Web search for a particular query, such as "Homer Simpson", use an activity starter with these properties:

Action: android.intent.action.WEB_SEARCH
ExtraKey: query
ExtraValue: Homer Simpson
ActivityPackage: com.google.android.providers.enhancedgooglesearch
ActivityClass: com.google.android.providers.enhancedgooglesearch.Launcher

Open the browser to a Web page

Use these activity starter properties to open a specific web page:

Action: android.intent.action.VIEW
DataUri: http://news.google.com

Start the mailer with pre-addressed message

To start the Android mailer application, use the action android.intent.action.VIEW. You can use Activity starter's DataUri property to specify the recipient, the message subject, and body of the message. In each case, starting the activity will bring up the Android mailer, and you can complete the message and then press "Send".

For example, if you specify:

Action: android.intent.action.VIEW
DataUri: mailto:santa@northpole.com

then starting the activity will bring up the mailer, with the addressee filed in.

If you specify:

Action: android.intent.action.VIEW
DataUri: mailto:santa@northpole.com?subject=Please Santa&Bring me a pony

then starting the activity will bring up the mailer, with the addressee, the subject, and the body filled in. You can use the mailer to edit these before sending the message, if you prefer.

You can find the complete rules for encoding messages in the DataURI at http://www.ianr.unl.edu/internet/mailto.html.

Show a map for a location

If you know the latitude and a longitude of a location, you can show a map using an activity starter with these properties to show a map of the area:

Action: android.intent.action.VIEW
DataUri: geo:37.8,-122.23?z=23

The format of the DataURI is specific to the app. In this example, the URI specifies a z (zoom) of 23, which is the largest zoom value. Zoom value is optional and ranges from 1 (the entire Earth) to 23.

If you know the zip code, you can set the activity starter properties as follows:

Action: android.intent.action.VIEW
DataUri: geo:0,0&q=94043

If you have a street address, you can use a DataUri that encodes the address with a scheme called URL encoding:

Action: android.intent.action.VIEW
DataUri: geo:0,0&q=5000% 20MacArthurBlvd%20Oakland%2CCA

Generally in URI encoding the only characters you have to replace are spaces (%20) and punctuation marks, such as comma (%2C) and period (%2E).

Play a YouTube video

You'll need to know the URI of the YouTube video. Then set the Activity Starter properties as

Action: android.intent.action.VIEW
ActivityPackage: com.google.android.youtube
ActivityClass: com.google.android.youtube.PlayerActivity

and set the Data URI to the URI of the video to be played, for example:

DataUri: http://www.youtube.com/watch?v=8ADwPLSFeY8

Figuring out how to set the properties

If you can't find documentation for the activities you want to start, one way to figure out how to set the properties is to start up the activity manually and look at what appears in the Android System Log. For example, if you use YouTube to play a video, you'll see in the log:

I/ActivityManager( 86): Starting activity: Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.youtube.com/watch?v=8ADwPLSFeY8 flg=0x3800000 cmp=com.google.android.youtube/.PlayerActivity }

If you can find the "cmp=" string, then the ActivityPackage is the part before the slash, and the ActivityClass is is the entire "cmp=" part, without the slash character. As in the YouTube example, there may also be "dat=" information that can specify with the DataUri property.

Starting arbitrary apps

You can use the Activity Starter to start any activity at all if you know the package name and class name, or the appropriate intent. Some developers document these intents for the benefit of other Android developers. For hints on starting other apps using intents, see the Android API documentation and OpenIntent's list of Intents.

If you have an app on your phone and you don't have the source code, you might still be able figure out the package name and class name (and sometimes the intent) by launching the app and inspecting the Android system log, as indicated above.

Getting values back from the apps you start

Some apps are constructed to return a value to to access the result to access the result depends on the design of the activity being started. Currently, App Inventor can get back text results only.

Returning results from App Inventor Apps

You can create App Inventor activities that return a (text) result to their callers, so they can be used as subroutines. To return a result, invoke the command close screen with result (located in the Control drawer). Your subroutine will will terminate, and the argument of close screen with result will become available to the activity starter that started it, passed as an argument to the AfterActivity event.

More specifically, suppose there is a SubroutineApp designed to be started with an activity starter and return a value, and a CallerApp that uses an ActivityStarter to call SubroutineApp. To return the result, SubroutineApp executes close screen with result, giving it as argument the result that should be returned to the caller.

On the caller side, CallerApp sets up its Activity Starter with the correct package name and class name for starting SubroutineApp. It must also set the ActivityStarter.ResultName property to the special text string APP_INVENTOR_RESULT. Then CallerApp starts the SubroutineApp activity. When the subroutine finishes, the Activity Starter's AfterActivity event triggers, and the result argument to AfteActivity will be the result that was passed back from SubroutineApp. That same information is available as the ActivityStarter's Result property.

Passing values to App Inventor Apps

You can pass a text value to an App Inventor app that you start with the Activity Starter. To do this, set the ActivityStarter's ExtraKey property to APP_INVENTOR_START and the ExtraValue property to the text you want to pass. The second app can retrieve that value by using the get start text block from the Control drawer.

By passing and returning results, you can combine several App Inventor apps, both apps you write, as well as apps you share with others.

Returning results from arbitrary applications

Getting values back from other applications is like getting values back from App Inventor apps. In general, an app will return a result that is designated by a name, where the result is designated by a name, and the expected name is specified with the Activity Starter's ResultName property. The name to use for App Inventor apps is APP_INVENTOR_RESULT, as described above. Other applications, not created with App Inventor, will use other names, and you'll need to know those names in order get values back from those applications. Here you'll need documentation about the app you want to use as a subroutine. Some developers provide this information, or sometimes you'll have access to the source code.

Not all Android apps use the Result and ResultName mechanism. For example, some apps return information via the properties ResultType and ResultUri. Again, you'll need to have information from the app developer to know which of these to use.

For advanced developers: More specifically (with reference to the Android developer documentation) an app can be designed to return an intent. The Activity starter uses the specified ResultName to access intent.getStringExtra(resultName) to produce the result. The values for ResultType and ResultUri come from intent.getType() and intent.getType().

Example: Picking files from the SD Card

Here's an example that illustrates using a third-party application:

AndExplorer from Lysesoft is an application that lets you pick files for your SD card. You can call AndExplorer with an activity starter to add a file picking capability to your application. You'll need to have AndExplorer installed on your phone. You can get it from the Android Market.

To start AndExplorer to pick a file, use an ActivityStarter with:

Action: android.intent.action.PICK
dataType: vnd.android.cursor.dir/lysesoft.andexplorer.file
dataURI: file:///sdcard

When you start the activity and pick a file, the resulting file name will be available as ResultUri. Also, ResultType will give the type of the file, for example, image/jpeg or audio/mpeg. Using this, you can write an app that lets you pick a file from the SD card and either displays the image or plays the music track as appropriate.

Is the application available?

If your app calls other apps as activities, you'll want to check that those other apps are available on your user's phone before trying to start them. You can check this using the Activity Starter method ResolveActivity, which returns the name of the Activity that would be started, given the package or intent information you've provided. If this name is blank, then the required application is not present, and you can warn your user.