App Inventor Tutorial 11 – QR Code Reader

Transcription

App Inventor Tutorial 11 – QR Code Reader
App Inventor Tutorial 11 – QR Code Reader
This is an app which will demonstrate the use of the phone’s built in camera as an
input device for a QR Code scanner. Note this app will not work on the emulator
because it is using the camera module as an input.
Please note: before this app will work it requires “XZing Barcode Scanner” to
be installed on the device also. This app is the quickest way to install
dependencies which App Inventor Barcode scanners need to function. A
compatible version of “XZing Barcode Scanner” can be found by searching
the Google Play Store.
If the Google Play Store version is not compatible with your device you can
install a depreciated version compatible with most phones, the app is available
here. This can be copied to the phones SD card and installed by opening the
file in the phones file manager app (if available) or through HTC Sync software.
What you will develop is a simple app which allows you to create a QR Code (with
your own text) and read a QR code with the phone’s built in camera. 
Step 1: Open App Inventor
Navigate to app inventor as before via http://beta.appinventor.mit.edu and login.
Like the previous tutorials, create a new project.
Give the project the name – QRCodeReader and click OK.
Step 2: Build the Interface of QR Code Reader
The QR Code Reader app needs many components. These include:

Text box

Buttons

Labels

Activity Starter

Barcode Scanner

Sound
Let’s start by changing the title from Screen1 to QR Code Reader in the properties
box.
Now that the title has been changed we need to start adding content to the screen.
The first item we are adding is the button to initiate the Barcode scanning. Change
the default text in the button to “Scan” and adjust the ‘Width’ attribute of the button to
“Fill parent” in the properties section.
The properties section should look as such:
Select the Button (from the components section beside properties) and click Rename
below. Change the ‘New Name:’ text value to “scanButton” and click ok.
Next we will add a Label to the screen, to display the scan result. Drag a label
component from the Basic Palette and place it beneath the “Scan” button.
Delete the ‘Text’ value of the label as this should be blank prior to the scanning of
our Code.
Rename the label as shown before and change it to “resultLabel”.
Drag another button from the Palette section and place it below this label.
Following the same steps as before, edit the text for this button and change it to
“Result Action” in the properties section:
Then rename this button again as before and call it “resultActionButton”.
The final two components to be added to the screen are the BarcodeScanner and
ActivityStarter, both of which are found on the ‘Other stuff’ Palette.
Drag one of each to the screen and they will appear below the viewer as non-visible
components.
Your ‘Components’ section should look like this:
Now you have completed designing the interface, we need to start putting
some blocks in to give it the functionality required.
Step 3: Add the functionality to the Interface
Once the interface is ready we can set the functionality of the components. What we
want to happen can be described in the following steps:
1. The user clicks the “Scan” button and scans a barcode with the phone’s
camera.
2. The application then searches Google with the result or opens the URL in a
browser (if the QRCode is a URL).
For this application we are going to need 2 user defined variables: buttonAction
(value is 1 if URL has been scanned, and 0 otherwise), and barcodeResult (this will
be the resulting string from the barcode/QRCode scan).
Firstly drag 2 “variable” blocks onto the Blocks Editor screen from the ‘Built-In’ >
‘Definition’ menu. Rename the first “buttonAction” and the second “barcodeResult”. It
should look as such:
Now we will set the default values of these variables. In the menu drag a number
block from the ‘Built-In’ > ‘Math’ and a text block from the ‘Built-In’ > ‘Text’ menu.
Connect the ‘number’ block to the “buttonAction” block, and connect the ‘text’ block
to the “barcodeResult” block. Then change the value of the ‘number’ block to 0 and
delete the text from the ‘text’ block. The end result should look like this:
Now that we have the default values of our variables defined we must add
functionality to the buttons.
The first button we are going to add functionality to is the ‘scanButton’.
In the Blocks Editor, under the ‘My Blocks’ menu there is an item called ‘scanButton’,
open this menu item and drag a ‘scanButton.Click’ block onto the screen.
Under ‘My Blocks’ again, choose the ‘call…BarcodeScanner1.DoScan’ block from
within the ‘BarcodeScanner1’ menu item and connect this inside the
‘scanButton.Click’ block. The end result should look as such:
This means that when the ‘Scan’ button is clicked, the app will run the ‘DoScan’
method of the BarcodeScanner which is all built into App Inventor.
This will automatically perform a barcode scan from the phone’s camera and return
the result.
So our next step is to be able to handle the result.
From the same menu again, under ‘My Blocks’ > ‘BarcodeScanner1’ you will find a
block titled; ‘When…BarcodeScanner1.AfterScan…result…do’. Drag this onto the
screen.
Drag an ‘ifelse’ block from ‘Built-In’ under Control and insert this into the
‘When…BarcodeScanner1.AfterScan…result…do’ block.
In the test argument of the ‘ifelse’ block we are going to firstly check if the result is a
number by using the built in ‘call…is a number?...thing’ block. This block is found
under ‘Math’ in ‘Built-In’.
The value that we would like to test ‘is a number?’ is stored, as the result of the scan,
in the variable defined as “result”. So from the ‘My Blocks’ > ‘My Definitions’ menu
drag a ‘result’ block onto the Blocks Editor and attach it to the ‘call…is a
number?...thing’ block.
Now, if the result is a number (which it should be if the barcode/QRCode is
associated with a product) we want to carry out a series of actions.
Firstly we want to inform the user that we have found a barcode number from the
barcode. To do so we want to first change the text of the ‘resultLabel’.
Inside the ‘then-do’ section of the ‘ifelse’ block we need to modify the resultLabel. To
this block add a ‘set…resultLabel.Text…to’ block which can be found under ‘My
Blocks’ > ‘resultLabel’.
Now to make the information more user friendly, rather than just presenting the user
with a number we will make the resultLabel text value more reader friendly with a join
block. Drag a ‘join’ block from the ‘Built-in’ > ‘Text’ menu and connect it to the
‘set…resultLabel.Text…to’ block. From the same menu also drag a ‘text’ block to the
first half of the ‘join’ and to the second half, add a ‘result’ block from ‘My Blocks’ >
‘My Definitions’. Now edit the ‘text’ block and replace the default text with; “Found
barcode: “. The result should look like so:
Beneath the ‘set…resultLabel.Text…to” block we then want to modify the text of the
action button. This will inform the user of the action the button would execute if
pressed. To do so add a ‘set resultActionButton.Text…to’ block underneath and
connect to this a ‘text’ block found in ‘Built-In’ > ‘Text’. Like so:
Change the text in this ‘text’ block to “Search Google for product”. As seen in the
picture above.
Finally, we want to modify the global variable buttonAction and set it to 0. This is
because the value of the barcode/QRCode is not a URL.
To do so, underneath the ‘set resultActionButton.Text…to’ block add a ‘set
global…buttonAction…to’ block and connect to it a ‘number’ block with the value of
0.
Note: the ‘set global…buttonAction…to’ block is found under ‘My Blocks’ > ‘My
Definitions’ and the ‘number’ block is under ‘Built-in’ > ‘Math’.
The end result should look like this:
This is the first basic function of our scanner defined. If the app was put into
operation now and a normal linear barcode was scanned on a product, the app
would get the barcode number and change the resultActionbutton text to “Search
Google for product”.
Next we must define the operation if the scanned barcode/QRCode has a URL
stored in its data.
As we are carrying out much of the same steps, and given that you should now be
familiar with where the different blocks are, the next operation is a repetition of what
we have just done.
We want another copy of every block inside the red box. Somewhere else on the
Blocks editor page, construct a copy of everything within this red box before we
modify it. Like so:
Now as this time we are not looking for a barcode number but instead a URL we
must change some of the blocks and values, but the overall structure will stay the
same.
Firstly we are no longer testing if the result is a number; we are now testing if the
result is a web address. As all web addresses contain the prefix “http://” we can test
to see if this is in the information collected from the barcode/QRCode.
To do this remove the ‘is a number?’ block from the test area of the ’ifelse’ block like
so:
We will replace this with a block designed to test if text contains a sub-string. This
block is the ‘contains’ block, found under ‘Built-In’ > ‘Text’.
Connect this into where the ‘is a number?’ block used to be. To this block, connect to
the ‘text’ part the ‘result’ block we have on screen, and to the ‘piece’ part connect a
new ‘text’ block with the value “http://”. The end result should look like so:
Now we need to modify a few of the previous ‘text’ blocks to give information specific
to URL’s.
In the ‘text’ block attacted to ‘set…resultLabel.Text…to’ change the first ‘text’ block to
“Found URL: “. It will look like so:
In the ‘text’ block attached to ‘set…resultActionButton.Text…to’ change the text to
“Visit URL in browser”. It should look like this:
Finally change the ‘number’ block attached to ‘set global…buttonAction…to’ to 1.
The end result, after all these steps, should be a segment of blocks like so:
We want to slot this ‘ifelse’ block, into the first ‘ifelse’ block, within the ‘else-do’ part.
Drag your second ‘elseif’ block and put it inside your first, the result will look like this:
Now, if we ran the app it would be able to cope with a barcode containing a product
number and a QRCode containing a web address. The final function of a
barcode\QRCode we must prepare for is a simple value.
For this again we are just repeating steps that you have already done in this tutorial.
Within the original ‘ifelse’ statement we create a duplicate of blocks again, this time
everything inside the original ‘then-do’ part (as seen in red below).
Duplicate all of these blocks again, in a separate section of the blocks editor. If
should end up looking like this:
Now we want to modify these blocks to deal with simple values that can be stored in
barcodes/QRCodes.
Firstly change the ‘text’ block, in the first half of the ‘join’ block to “Found value: “ it
should end up looking like so:
Next we want to modify the ‘text’ block directly below this to read “Search Google for
result”. And finally change the number button directly below this again to “0” (as seen
below in red). The end result is this:
Now drag all of this into the empty slot of your second ‘ifelse’ block. The end result
should be as seen on the next page.
At this stage the barcode/QRCode reader is setup to handle linear barcodes,
QRCodes with URL’s (web addresses) imbedded in them and simple values.
The final thing that must be done inside this ‘BarcodeScanner1.AfterScan’ method is
to modify the barcodeResult global variable and set it to the result of the scan.
To do this inside ‘My Blocks’ > ‘My Definitions’ drag 2 blocks to the screen; a ‘set
global…barcodeResult…to’ block and, a ‘result’ block, attach these together (as
seen below) and place them inside ‘BarcodeScanner1.AfterScan’ below both ‘ifelse’
blocks.
The final form of this block is:
So at this point the app is capable of completely reading in the information in
barcodes or QRCodes and modifying components on the screen.
The last thing that has to be handled on the screen is what happens when the
‘resultActionButton’ is clicked.
From ‘My Blocks’ > ‘resultActionButton’, drag the
‘when…resultActionButton.Click…do’ block onto the screen. Inside this we will place
everything we want to happen when the resultActionButton is clicked.
This block will perform 2 different actions depending on the value (either 0 or 1) of
‘buttonAction’. These values represent whether the code scanned is either a web
address (1) or just a barcode/value (0).
Firstly we must use an ‘ifelse’ block to perform different operations depending on
‘buttonAction’’s value.
Get an ‘ifelse’ block from ‘Built-In’ > ‘Control’ and put it inside the
‘when…resultActionButton.Click…do’, it will look like this.
Now the test value will be whether ‘buttonAction’ is 0 or 1 first, so we will need 3
blocks here;

‘buttonAction’ (from ‘My Blocks’ > ‘My Definitions’)

‘Equals’ block (from ‘Built-in’ > ‘Math’)

‘number’ block (from ‘Built-in’ > ‘Math’) change its value to 0
Once all three of these are on screen attach them as shown in the picture below to
test the value of ‘buttonAction’ within the if statement.
Within the ‘then-do’ part of the ‘ifelse’ block we will define everything that we want to
happen when ‘buttonAction’ does equal 0 (i.e. when the data from the barcode is
either a product barcode number or a value).
We need to define a new activity on the phone (this is how we launch external
applications from within our app, such as; browser, texts or emails. Before we start
this activity we have to pass it all the information it will need on startup.
The information it will need on startup is that it will be a new view on the screen
(think of it like a new window opening up) which will be our browser, and the web
address this browser is going to open.
Pull onto the Blocks Editor screen these 7 blocks

‘set…ActivityStarter1.Action…to’ (from ‘My Blocks’ > ‘ActivityStarter1’)

‘set…ActivityStarter1.DataUri…to’ (from ‘My Blocks’ > ‘ActivityStarter1’)

2 x ‘text’ blocks (from ‘Built-in’ > ‘Text’)

‘join’ block (from ‘Built-in’ > ‘Text’)

‘ActivityStarter1.StartActivity’ (from ‘My Blocks’ > ‘ActivityStarter1’)

‘barcodeResult’ (from ‘My Blocks’ > ‘My Definitions’)
First take the ‘set…ActivityStarter1.Action…to’ and attach it inside our ‘ifelse’ block
from before. Then attach one of the ‘text’ blocks to the open part of the
‘set…ActivityStarter1.Action…to’ block.
It will look like this:
Now change the text in the ‘text’ block you just connected and type:
“android.intent.action.VIEW” be very careful of your spelling and case here. It should
look as such:
This means that every time ‘resultActionButton’ is clicked and ‘buttonAction’ equals 0
a new activity will start to be created and that this activity will be a VIEW (like a new
window in the browser).
Below the ‘set…ActivityStarter1.Action…to’ block we now need to define the
webpage that we will be visiting, this is where we will connect the
‘set…ActivityStarter1.DataUri…to’ block.
It will then look like this:
To this block we will firstly connect the ‘join’ block. We need this join block because
the DataUri we are defining here is what will be put into the address bar of the
browser. So we need to form it properly to do a Google search.
In the first half of the ‘join’ block we put the pre-cursor to every Google search which
is “http://www.google.com/m?q=”. You will notice no matter what you search for on
Google this will be the start of the address in the address bar of your browser,
followed by the words you are actually searching for.
Thus we need to join this to the ‘barcodeResult’ from our scan. So our
‘barcodeResult’ will go in the other half of the ‘join’ block.
After these steps your block should look like this:
Now we have defined all the parameters we need to start a new browser window all
that is left is to start the browser and show it on screen, this is done by the
‘ActivityStarter1.StartActivity’ block and it is placed under the
‘set…ActivityStarter1.DataUri…to’ block. Like so:
The final section we have to do is the ‘else-do’ part of the ‘ifelse’ block, which defines
what happens when the buttonAction’ variable does not equal 0 (i.e. equals 1 – is
already a web address).
This is again a repeat of all of the previous steps so create a copy of all of the blocks
seen below in the red box somewhere else on the Blocks Editor:
It should look like so:
Now as this is still a webpage we are going to be going to the ‘ActivityStart1.Action’
is still set to the same text, edit the ‘text’ block attached to it and again enter
“android.intent.action.VIEW”.
Now the DataUri value that is being passed to the activity is not as unorganised this
time. As the data from the QRCode is already a web address we don’t need to
construct one by adding the Google pre-cursor. So within the
‘ActivityStarter1.DataUri’ block we can just attach the ‘barcodeResult’ block and
delete the ‘text’ and ‘join’ blocks. The end result will look like this:
This group of blocks is now completely capable of handling a QRCode that already
contains a web address. Drag this group and place it inside the ‘else-do’ part of the
‘ifelse’ block, inside the ‘resultActionButton.Click’.
The final form will look like so:
And that is your barcode/QRCode application complete .
Well Done! That’s it, the app is now ready for you to test it.
Step 4: Try it out – Connect to the device and test the program
Now connect your device (phone or tablet) to the PC, deploy the application to your
device, and test the app as you have done in the other tutorials.
You should be familiar with deploying apps to your device by this stage but if you
have any complications, refer back to the previous tutorials, details can be found at
the end of tutorials 1-8.
~ Have fun ~