Fusion Tables serves cloud-based table as data persistence, in this example data is collected from Android device.
I shall create a basic Android app in MIT App Inventor 2 for learning purpose. This basic app can then be used as part of a more complex Android app. 😇
Fusion Tables
Open Google Drive to create a new Fusion table.Click "New" button.
Click "More" then "Connect more apps".
Type "fusion tables" in the "Search Apps" box and hit the "Enter" key.
Click the "CONNECT" button, then click the "OK" button in the confirmation dialog box.
Back to Google Drive, click again on "New" button.
Click "More | Google Fusion Table".
In the "Import new table" dialog box, choose "Create empty table".
A new table will be created, with 4 columns:
Click on column name to edit,
- For Text, change to Email. With type=Text and check on Validate.
- For Number and Location, no change.
- For Date, change type=Text.
Now I have a table in Fusion Tables with 4 columns.
I shall keep user submission data in this cloud table. So when user submit a GPS (or other: wifi, cell) location in Android device, it will be saved in this table.
"Number" column can be used e.g. to save unique ID of user, or can also be an auto-increment unique ID.
"Date" will be collected automatically from Android device. Time can also be added in this column (Date/Time) or as a new column.
"Email" must be entered by user for identification.
"Location" is geolocation coordinates (retrieved from Android device's location), latitude and longitude. We can also add altitude if required.
Add a new dummy row. Run "Edit | Add row".
Fill in the form with any data. Example:
Number = 0
Date = Feb 19, 2017
Email = ghost@yggdrasil.8888
Location = -8.6631801,115.217053
Location value must be set to coordinate values, i.e. pair of latitude,longitude. Make sure latitude is the first, separate values with a comma.
Google Developers - Service Account
I need a service account for the Fusion Tables.(In case we already have Google Developers account, we can use existing project or creating another new project.)
Otherwise for a new user, create a new project.
Go to https://console.developers.google.com
Click "Project | Create project".
Give the project a name, don't use space in the name.
When the new project is set up, return to console.developers.google.com, now the project is listed at the top of the page.
Open API manager by clicking on menu (three horizontal lines) in the top left side, then choose API Manager.
Search for "Fusion Tables" in the list of API and click on Fusion Tables API.
Click on "Enable", then "Go to Credentials".
Click on "Service account",
The Credentials tab should be opened, otherwise just open it under the API Manager.
Click "Create credentials" button, choose "Service account key".
Create a service account,
Give it a service name and product name. Check on "Enable G Suite Domain-wide Delegation". Click "Create".
Back to console, from menu (three horizontal bar on the top left), choose "IAM and Admin".
Open "Service accounts" tab.
Note: In the above image, "nbgaeplus" is my project name, you may have another name of your choice.
In the service accounts page, copy the Service account ID (email) and Key ID. Save it into a text file for further reference. I shall need this email address in the app.
Now I need to save P12 key file to be used in the app. Back to API Manager, then open Credentials.
Again, click on the "Create credentials" button, then choose "Service account key".
Select the "fusiontables" service, then choose "P12" key type. Click Create.
A dialog box should be opened asking folder location to save a ".p12" file.
Save the file to be used later in my app.
Share the table
Back to our Fusion Tables page.
Click on "Share" button. A "Sharing settings" dialog should be opened.
Prepare the email address (Service account ID) I got from the above steps. That's something likes: "fusiontables@xxxxxxx.gserviceaccount.com".
Copy the email address.
In the "Invite people" do paste the email address.
Select "Can edit", uncheck "Notify people". Click OK, and Done.
In the Fusion Tables page, open "File | About this table" menu.
Copy the Id, save it in a text file for further reference.
I want to display a map based on the table's location data.
For the map to appear on a website, the Visibility of the table must be "public" or "unlisted", otherwise modify it through "Share" button.
Then, publish the map. In the Fusion Tables, open "Map of Location" tab.
Click "Tools | Publish" menu.
Copy the link, save it in a text file. I shall use the link in my app.
MIT App Inventor 2
In case no App Inventor account yet, create new one http://ai2.appinventor.mit.edu with Google account.
For readers, I assumed you already have a basic experience with App Inventor.
A fresh beginner, sorry you need to learn first the basic of App Inventor in the tutorial section, http://appinventor.mit.edu/explore/ai2/tutorials.html.
A fresh beginner, sorry you need to learn first the basic of App Inventor in the tutorial section, http://appinventor.mit.edu/explore/ai2/tutorials.html.
In the App Inventor's Designer, start a new project. Give it a name.
Choose screen's orientation either landscape or portrait. Here I choose landscape.
Add WebViewer from User Interface palette. Set "Width" property to "Fill parent".
Set "HomeUrl" property to the previous link we copied from the Fusion Tables page. It's the link that started with: "https://fusiontables.google.com/embedviz?..."
From "Storage" palette, add FusiontablesControl. It's non-visible component.
Remember in the previous step, we save a ".p12" key file.
Now in the "KeyFile" property, klik "Upload File...", select the ".p12" key file.
Also in the previous step, we copied and saved email
address (Service account ID), something likes "fusiontables@xxxxxxx.gserviceaccount.com".
In the "ServiceAccountEmail" property, do paste this email address.
I need a layout as container to some UI components. From Layout palette, add HorizontalScrollArrangement. Place it under the WebViewer.
Set its "Width" property to "Fill parent".
From User Interface palette, add a TextBox inside the HorizontalScrollArrangement.
Rename it to "TextBoxEmail".
Change its "Hint" property to "Enter your email address.."
Add a Button component inside the HorizontalScrollArrangement.
Rename it to "ButtonRegister".
Change its "Text" property to "Register".
Change its "Enabled" property to "false".
Add another Button component inside the HorizontalScrollArrangement.
Rename it to "ButtonRefresh".
Change its "Text" property to "Refresh".
I want to make TextBoxEmail to fill the space horizontally. Highlight the TextBoxEmail component, then change its "Width" property to "Fill parent".
Note: In this case I don't use "Number" column from the table. Usually the number is used as a unique auto-increment primary key, or can also be used for unique user ID. The number should be generated by the code, however we won't implement it as it depends on the requirement of real larger application to use this snippet.
I need some more non-visible components:
Sensors - LocationSensor
Sensors - Clock
User Interface - Notifier
Add them to the screen in Viewer.
For the LocationSensor, change "TimeInterval" property to 10000.
Finally I have our app in the Designer with following layout and components:
Event-driven Blocks
In the App Inventor, open Blocks tab.
Add a global variable rowValues, initialize to empty string.
For ButtonRefresh.Click, call WebViewer1.GoHome.
For LocationSensor1.LocationChanged, call Notifier1.ShowAlert, and set ButtonRegister.Enabled to "true".
The logic is, when location measured by device's GPS sensor is changed, then an alert is shown, and ButtonRegister is enabled for the user to be able to click it.
The alert message contains coordinates, latitude and longitude.
For ButtonRegister, it's a bit complicated. There are three procedures we need to call:
(1) First, set global variable rowValues to row text value, to be submitted to the Fusion Tables. The format of the table's row value is comma separated values, with each value in quotation.
Number,Date,Email,Location
Example: "0","Feb 19, 2017","ghost@yggdrasil.8888","-8.6631801,115.217053"
As explained previously, I shan't use Number, so we just set it to zero.
The date is retrieved from the Android device's date/time.
Email address is supplied by user, in the TextBoxEmail.
Location (latitude,longitude) is retreived from location sensor of Android device.
(2) Second, call notifier to show alert with global variable string value, rowValues.
(3) Third, send row data to Fusion Tables (insert row).
Set "tableId" with ID string we saved in the previous step, when I created table in the Fusion Tables.
Set "tableId" with ID string we saved in the previous step, when I created table in the Fusion Tables.
Finished building the app.
Test the app
Connect Android device (or emulator) to computer. In the App Inventor, run "Connect | USB" menu if device is connected via USB cable, or choose "Emulator" if emulator is used, or choose "AI Companion" if device is connected via Wi-fi.
Note: MIT App Inventor Tools should have been installed in the computer, then run aiStarter. In the Android device (or emulator) MIT AI2 Companion should have been installed.
Appearance of the screen:
Alert message is displayed by notifier:
Was the new row sent and saved in the Fusion Tables? Let's find out in the Fusion Tables page:
Yes it was, new row was successfully added into the table.
And now there are two markers in the map, because we have two rows in the Fusion Tables' table.
😜
Further reference:
Fusion Tables Layer Wizard