Editing AppInventor zipped files

AppInventor

AppInventor (http://www.appinventor.org/) is a simple-to-use, graphic, android app builder. It can be easily learned by novices, but has the flexibility and power to be used in developing complex mobile apps.

The graphic interfaces for both the display layout and the programming make AppInventor an easy tool for prototyping and developing apps. This interface, however, can make it difficult to maintain and expand existing code or combine features from different apps. This limitation is most apparent in the lack of system tools to import subroutine libraries or name-search for routines or variables.

There is, however, one method that I have found helpful in accomplishing these tasks. The method uses the facility to export the program in zipped text files to one’s local computer. Program modifications can be made by downloading the zip file, editing one or more of the zipped files, rezipping the archive, and uploading it to AppInventor.

I am not aware of any documentation on the formats of the files and I do not know whether this file structure will be continued as AppInventor evolves (see http://www.appinventor.org/appInventor2). However, I have found that I can take advantage of some basic structures to successfully edit files for updating apps in AppInventor, even though the description below is far from a complete exposition of the file structure.

Block structure

The block-generated code is contained in ‘screen1.blk’, which is an archived file several levels deep within the ‘src’ subdirectory of the zip file. The file is in xml format. The building blocking of the functions, data, and event-drivers are delineated within the start- and end-tags <Block …> and </Block>. Each of these elements defines a block as it appears in the program editor in AppInventor.

Each start-tag, <Block…> contains attribute information which allows it be be linked to other blocks and tells the compiler the role of the block. Subsequent elements in the block locate its place on the programming screen and specify the contents and linkages to other blocks. A typical block appears as follows:

<Block id=”1683″ genus-name=”text” >
<Location><X>870</X><Y>636</Y></Location>
<Label>Hello World </Label>
<Plug><BlockConnector connector-kind=”plug” connector-type=”poly” init-type=”poly” label=”” position-type=”single” con-block-id=”2310″ ></BlockConnector></Plug>
</Block>

start-tag identifies the block as number 1683 which contains a text message:

<Block id=”1683″ genus-name=”text” >

The is displayed at coordinates 870 and 636 on the programming desktop:

<Location><X>870</X><Y>636</Y></Location>

Since this is a text block, its value, “Hello World” is in the <Label> attribute:

<Label>Hello World </Label>

This text block is an input to block 2310:

<Plug><BlockConnector connector-kind=”plug” connector-type=”poly” init-type=”poly” label=”” position-type=”single” con-block-id=”2310″ ></BlockConnector></Plug>

The receiver, Block 2310, appears in the file as:

<Block id=”2310″ genus-name=”make-list” >
<Location><X>821</X><Y>582</Y></Location>
<Label>make a list</Label>
<Plug><BlockConnector connector-kind=”plug” connector-type=”poly” init-type=”poly” label=”” position-type=”single” con-block-id=”1495″ ></BlockConnector></Plug>
<Sockets num-sockets=”2″ >
<BlockConnector connector-kind=”socket” connector-type=”poly” init-type=”poly” label=”item” is-expandable=”yes” is-indented=”yes” position-type=”single” con-block-id=”1683″ ></BlockConnector>
<BlockConnector connector-kind=”socket” connector-type=”poly” init-type=”poly” label=”item” is-expandable=”yes” is-indented=”yes” position-type=”single” con-block-id=”1677″ ></BlockConnector>
</Sockets>
</Block>

Here the genus-name element indicates that the block makes a list and the  <BlockConnector…> attributes indicate that the two strings in blocks 1683 and 1677 are concatenated and passed to block 1495.

Function structure

When a block defines a sequence of steps, the block needs a function name and must specify the order in which the blocks are executed. This information is provided by the <StubParentName>, </BeforeBlockId>, and <AfterBlockId> elements as in the following example:

<BlockStub><StubParentName>newNumberSelected</StubParentName><StubParentGenus>def</StubParentGenus><Block id=”1965″ genus-name=”setterGlobal” >
<Location><X>66</X><Y>47</Y></Location>
<Label>newNumberSelected</Label>
<BeforeBlockId>1951</BeforeBlockId>
<AfterBlockId>1969</AfterBlockId>
<Sockets num-sockets=”1″ >
<BlockConnector connector-kind=”socket” connector-type=”poly” init-type=”poly” label=”to” position-type=”single” con-block-id=”2117″ ></BlockConnector>
</Sockets>
</Block>

Here the <StubParentName> element provides the function name, ‘newNumberSelected’ and the </BeforeBlockId> and <AfterBlockId> tags specify that block 1965 is preceded by block 1951 and followed by block 1969. Here, block 2117 is the sole input.

Links to the screen layout

The <YoungAndroidMaps><YoungAndroidUuidMap> attributes link the layout constituents with the blocks.

<YoungAndroidMaps><YoungAndroidUuidMap>
<YoungAndroidUuidEntry uuid=”-1931107125″ component-id=

Uh”ChangeMyInstructions” component-genus=”Label” component-version=”2″ ></YoungAndroidUuidEntry>
<YoungAndroidUuidEntry uuid=”1803799009″ component-id=”MyButton” component-genus=”Button” component-version=”5″ ></YoungAndroidUuidEntry>
</YoungAndroidUuidMap>
</YoungAndroidMaps>

In this case, a label and a button on the screen are linked to blocks for events processed by  ‘ChangeMyInstructions’ and ‘MyButton’.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: