{"id":520,"date":"2015-01-23T13:30:05","date_gmt":"2015-01-23T21:30:05","guid":{"rendered":"http:\/\/appinventor.pevest.com\/?p=520"},"modified":"2015-01-23T13:30:05","modified_gmt":"2015-01-23T21:30:05","slug":"part-1-basic-bluetooth-communications-using-app-inventor","status":"publish","type":"post","link":"https:\/\/coldstreams.com\/appinventor\/2015\/01\/23\/part-1-basic-bluetooth-communications-using-app-inventor\/","title":{"rendered":"Part 1: Basic Bluetooth communications using App Inventor"},"content":{"rendered":"<p><em>(Some very minor updates were made to this in November 2019).<\/em><\/p>\n<p>This tutorial covers basic App Inventor Bluetooth communications\u00a0 code. \u00a0 Subsequent tutorials will add additional features. <em><strong>To implement and test this sample code, you need access to two Android devices &#8211; one to act as a Bluetooth &#8220;server&#8221; and the other to act as a &#8220;Bluetooth&#8221; client.<\/strong><\/em><\/p>\n<p>I tested this code using an old LG smart phone running Android 2.2 and a new Nexus 5 running Android 5.0.1. \u00a0I also tested this code using the Nexus 5 paired with a Nexus 7 tablet. (Update I have since also run this on an Honor 8 phone and a Pixel 2, with much newer versions of Android.)<\/p>\n<blockquote><p>This tutorial is lengthy &#8211; it introduces Bluetooth communications, then presents the user interface and blocks code for both the server and client programs, and then discusses how to set up the Bluetooth Communications link using &#8220;pairing&#8221;.<\/p>\n<p>Downloadable App Inventor source code for the client and server is at the end of this post.<\/p>\n<p>This is the first of several\u00a0 posts on Bluetooth. This first post covers basic connections and the sending and receiving of text between two Bluetooth devices. The two halves of the link &#8211; client and server &#8211; are kept in separate apps to keep this simple,\u00a0 however, it is possible for a single app to act as both a client and a server. A subsequent post will show how to send other types of data, such as numbers, and introduce additional features for using Bluetooth communications.<\/p><\/blockquote>\n<p>Related:<\/p>\n<ul>\n<li><a href=\"http:\/\/appinventor.pevest.com\/?p=569\">Part 2: Sending Numeric Data using Bluetooth<\/a><\/li>\n<li><a href=\"http:\/\/appinventor.pevest.com\/?p=718\">How to connect App Inventor apps to Arduino using Bluetooth<\/a><\/li>\n<\/ul>\n<p><strong>Introduction to Bluetooth<\/strong><\/p>\n<p>Bluetooth is the communications technology with a funny name.[1] Bluetooth is actually named for a long ago Danish king who worked to unite groups of people, which is similar to Bluetooth&#8217;s goal of interconnecting different devices. \u00a0The King&#8217;s real name was &#8220;Harald&#8221; but he had a nickname that translates as &#8220;Bluetooth&#8221; &#8211; no one knows for sure why he had this nickname but one thought is he had one dark tooth that may have appeared black or blue. And that is certainly an obscure way to choose a name for new technologies!<\/p>\n<p>Bluetooth establishes a very low power, short range (up to 10 meters) communications link between two devices. Bluetooth uses the same frequency band (2.4 Ghz) as Wi-Fi, but uses different technology. Both Bluetooth and Wi-Fi use forms of spread spectrum radio links that result in signals moving around within a wide band in ways that enable sharing of the spectrum by multiple devices. But the two technologies serve different purposes, are\u00a0 not identical, and cannot communicate with one another.<\/p>\n<p>Bluetooth applications include common wireless headsets for wired and cellular phones, and in-ear cordless adapters for phones. Bluetooth is also used by cordless headphones and to exchange address cards between devices, and for industrial applications where sensors collect and send data into a network.<\/p>\n<p>There are two forms of Bluetooth &#8211; classic Bluetooth, which\u00a0 we use in the sample applications, and a newer version known as Bluetooth low energy, Bluetooth BLE, Bluetooth LE or Bluetooth Smart &#8211; all referring to the same new technology. \u00a0The newest Android devices running Android 4.3 or newer, usually support the newest Bluetooth Smart technology. Regardless, we use classic Bluetooth which is backwards compatible to older phones, and is the technology supported by App Inventor.<\/p>\n<p>Setting up a Bluetooth devices involves &#8220;pairing&#8221; the two devices and establishing a connection. This will be covered later in this tutorial.<\/p>\n<p>Footnote:<\/p>\n<p>[1] Actually there is another communications technology with a funny name called TWAIN, which is an acronym for &#8220;Technology without and interesting name&#8221; (really!)<\/p>\n<h2><strong>The Designer View<\/strong><\/h2>\n<p><!--more--><\/p>\n<p>There are two separate apps for Bluetooth communications &#8211; one is a &#8220;server&#8221; app that runs on one device, and the other is a &#8220;client&#8221; app that runs on a second device.<\/p>\n<p>Bluetooth must be enabled on both devices, and the devices need to be paired before running these apps. (How to do this is explained near the end of this tutorial.)<\/p>\n<p>The server must be run first on one device and then the client app on the 2nd device connects to the server before data can be sent between the two devices. More on this later in this tutorial.<\/p>\n<p><strong>The server user interface is shown here:<\/strong><\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerDesigner.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-523 aligncenter\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerDesigner.png\" alt=\"BTServerDesigner\" width=\"311\" height=\"498\" \/><\/a><\/p>\n<p>The main components of the server interface design are:<\/p>\n<ul>\n<li><strong>Accept Connection Button<\/strong> &#8211; press this to set the server to accept a connection from another device. Connections are not possible until the <em>AcceptConnection<\/em> service is started.<\/li>\n<li><strong>Send the following text Button<\/strong> &#8211; the text is the following text box is sent to the other Bluetooth device.<\/li>\n<li><strong>Disconnect Button<\/strong><\/li>\n<li><strong>Status messages<\/strong> &#8211; Status about the communications link, and any messages received from the other device are shown on the display<\/li>\n<li><strong>Non-visible components<\/strong> &#8211; The apps use a clock to cause activities to occur at a preset interval. The <em>Notifier1<\/em> component is used to display error messages (see <a href=\"http:\/\/appinventor.pevest.com\/?p=81\">tutorial on the use of Notifier<\/a>), and <em><span style=\"text-decoration: underline;\">BluetoothServer1<\/span> <\/em>provides the Bluetooth support. The <em>BluetoothClient1<\/em> and <em>BluetoothServer1<\/em> components are located in the Connectivity section of the Designer palette.<\/li>\n<\/ul>\n<p>How each of the buttons and components are used to run the program are explained later, in a section on setting up Bluetooth on your devices and running the apps.<\/p>\n<p><strong>The client user interface is shown here:<\/strong><\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientDesigner.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-522 aligncenter\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientDesigner.png\" alt=\"BTClientDesigner\" width=\"306\" height=\"491\" \/><\/a>The user interface is similar to the server except instead of\u00a0 <em>AcceptConnection<\/em> there is a <em>Connect to device<\/em> button, and instead of a <em>BluetoothServer1<\/em> component, the <em>BluetoothClient1<\/em> components is used.<\/p>\n<p>The Connect to device button is actually a <em>ListPicker<\/em> component and not a standard button.<\/p>\n<p>For both the client and server apps, the <em>TimerInterval<\/em> of the <em>Clock<\/em> properties is set to 1000 milliseconds or 1 second. Other small values may be used. This value determines how frequently to check the Bluetooth link for incoming data from the other device. As shown, each app will check the link once per second.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClockProperties.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-524 aligncenter\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClockProperties.png\" alt=\"BTClockProperties\" width=\"135\" height=\"176\" \/><\/a><\/p>\n<h2><strong>Blocks Code<\/strong><\/h2>\n<p><strong>Bluetooth Server app<\/strong><\/p>\n<p>We start with the server app implementation. \u00a0The client app is presented after the server app.<\/p>\n<p>The first step is to check that Bluetooth is activated or switched on.\u00a0 If not, an error message is displayed reminding the user to open Android&#8217;s Settings and then switch Bluetooth to on.<\/p>\n<p>The <em>Initialize<\/em> event occurs\u00a0 when the app is launched &#8211; and this is a good place to check whether or not Bluetooth is enabled on the device.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerInit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-531\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerInit.png\" alt=\"BTServerInit\" width=\"618\" height=\"140\" \/><\/a><\/p>\n<p>Assuming that Bluetooth on the device is currently &#8220;on&#8221;,\u00a0\u00a0\u00a0 the next step is to accept a connection from another device when the <em>btnAcceptConnection<\/em> button has been pressed. This causes Bluetooth to begin listening for an incoming connection.<\/p>\n<p>Once a connection request has been received and processed, a <em>ConnectionAccepted<\/em> event occurs. In our basic app, we update the status message on the app screen.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerAcceptConnect.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-532\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerAcceptConnect.png\" alt=\"BTServerAcceptConnect\" width=\"460\" height=\"202\" \/><\/a><\/p>\n<p><strong>The Timer Event Handles Receiving of Data<\/strong><\/p>\n<p>Receiving data sent over Bluetooth takes\u00a0 place in the <em>Clock1.Timer<\/em> event handler. Remember, the clock is\u00a0 set so that the <em>Timer<\/em> event happens once per second. Every\u00a0 second, the app will check if any data has been received.<\/p>\n<p>To prevent reading data\u00a0 when Bluetooth is not connected (this would cause an error), an<em> if-then<\/em> statement checks the <em>IsConnected<\/em> property of <em>BluetoothServer1<\/em>. This value is set to true when the devices are connected\u00a0 and false if the connection is not currently available.<\/p>\n<p><em>IsConnected<\/em> should be\u00a0 true if a connection has been accepted. But because this is a wireless connection, a device might go out of range or be turned off,\u00a0 breaking the connection. It is good programming practice to check that the connection is working before trying to send or receive data.<\/p>\n<p>The property <em>BytesAvailableToReceive<\/em> tells us how much data is available (one text character is equal to one &#8220;byte&#8221; of data). If this value is zero, then no data is available. But if the value is greater than zero, then our app may read the incoming data and update the status and messages to the app display.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerTimer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-533\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerTimer.png\" alt=\"BTServerTimer\" width=\"943\" height=\"202\" \/><\/a><\/p>\n<p>The\u00a0Send Text button event handler is\u00a0similar to the receive code located inside the <em>Timer<\/em> event except that data is sent\u00a0 using the <em>SendText<\/em> method to transmit the data\u00a0to the other device.<\/p>\n<p>The Disconnect button handler is self explanatory!<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerSendDisc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-534\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerSendDisc.png\" alt=\"BTServerSendDisc\" width=\"514\" height=\"265\" \/><\/a><\/p>\n<p><strong>Error \u00a0Handling<\/strong><\/p>\n<p>One thing to know about wireless communications is that errors happen. For most of our App Inventor apps, we ignore potential errors &#8211; if errors occur, the app stops running and Android displays an\u00a0 error message.<\/p>\n<p>Rather than letting that occur, our app can intercept the error condition by adding an error event handler to the main screen, <em>Screen1<\/em>. The ErrorOccurred event has four parameter values (local variables) that contain information about the error. The error handler displays the\u00a0 error values on the screen, rather than shutting down the app.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerErrorHandler.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-543\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTServerErrorHandler.png\" alt=\"BTServerErrorHandler\" width=\"469\" height=\"261\" \/><\/a><\/p>\n<h2>Bluetooth Client App<\/h2>\n<p>Now that the server app is complete, we present the client app that runs on the other device. In many ways, the client app is a mirror image of the server, but refers to the <em>BlutoothClient1<\/em> component instead of the <em>BluetoothServer1<\/em> component.<\/p>\n<p><strong>App Initialization<\/strong><\/p>\n<p>Same as the server, except it\u00a0 uses\u00a0 <em>BluetoothClient1<\/em>.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientInit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-538\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientInit.png\" alt=\"BTClientInit\" width=\"704\" height=\"151\" \/><\/a><\/p>\n<p><strong>Connecting<\/strong><\/p>\n<p>When the two devices are running, the server app is set up first to accept connections. Then, on the client side, the user selects the Connect <em>ListPicker<\/em> button and selects the device name from a list of available Bluetooth devices. \u00a0Because the list of devices is in the form of a list, the <em>ListPicker<\/em> is a great interface component to display the device list and handle the selection. (See <a href=\"http:\/\/appinventor.pevest.com\/?p=107\">my earlier tutorial on <em>ListPicker<\/em><\/a>.)<\/p>\n<p>Before the list is displayed, the list is filled with the list of Bluetooth devices (<em>AddressesAndNames<\/em>). The <em>set lblStatus.Text<\/em> block may be deleted as it was used during my testing and is not needed in the final version of the client.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientSend.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-539\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientSend.png\" alt=\"BTClientSend\" width=\"669\" height=\"308\" \/><\/a><\/p>\n<p>After the device has been selected with the <em>ListPicker<\/em> user interface, the <em>Connect<\/em> method of <em>BluetoothClient1\u00a0<\/em>establishes the connection. The method returns a value of <em>true<\/em> if the connection was successful; in which case a message is sent to the server app.<\/p>\n<p>Disconnect is self explanatory.<\/p>\n<p><strong><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientDisconnect.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-540\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientDisconnect.png\" alt=\"BTClientDisconnect\" width=\"436\" height=\"110\" \/><\/a><\/strong><\/p>\n<p><strong>Receiving Data<\/strong><\/p>\n<p>Like with the server, the reception of data is implemented using a timer. Once per second, the client checks to see if data is available, and if it is, reads and displays the data on the app display.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientTimer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-541\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientTimer.png\" alt=\"BTClientTimer\" width=\"921\" height=\"204\" \/><\/a><\/p>\n<p>While the server must be running prior to the client making a connection, once the two devices are connected, either app can send data to the other app, at any time.<\/p>\n<p><strong>Error Handling<\/strong><\/p>\n<p>The client&#8217;s error handling is identical to the server&#8217;s error handling.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientErrorHandler.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-542\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/BTClientErrorHandler.png\" alt=\"BTClientErrorHandler\" width=\"467\" height=\"263\" \/><\/a><\/p>\n<p><strong>Setting Up A Bluetooth Connection<\/strong><\/p>\n<p>Before you use the Bluetooth communications apps, do the following:<\/p>\n<ol>\n<li>Use Build .apk or other method to obtain the server app, download and install on your first Android device.<\/li>\n<li>Use Build .apk or other method to obtain the client app, download and install on your second Android device.<\/li>\n<li>Go in to the Android Settings and turn on the Bluetooth feature. \u00a0 The user interface for the Bluetooth configuration varies slightly depending on which version of Android you have. \u00a0On 2.2, for example, you need to select Wireless &amp; Networks, and then choose Bluetooth, while on Android 5.0, Bluetooth appears in the topmost Settings menu.<\/li>\n<li>In newer versions of Android, when the Bluetooth Settings menu is active, your device is broadcasting its availability to other nearby devices. On older versions, you may need to click an option to make your device &#8220;discoverable&#8221;. (Note &#8211; my Nexus 5 is not visible on my very old LG 2.2 device &#8211; however, the Nexus 5 sees the LG and the two can be connected from the Nexus 5 side).<\/li>\n<li>Once your two devices see each other over Bluetooth, you may be prompted to &#8220;pair&#8221; the devices, or (depending on Android version), you may have to manually choose the device and then choose pairing. Follow the on screen instructions.<\/li>\n<li>Once the two devices are &#8220;paired&#8221;, launch the Server app and select Accept Connection.<\/li>\n<li>On the other device, launch the Client app and select Connect. If all goes well, you should see a &#8220;client connected&#8221; message on the Server app.<\/li>\n<\/ol>\n<p><strong>Key Features Shown<\/strong><\/p>\n<ul>\n<li>Introduction to Bluetooth wireless<\/li>\n<li>User interface for a Bluetooth server and client app<\/li>\n<li>Use of the Bluetooth Server and Client components to set up a link<\/li>\n<li>Use of error handling<\/li>\n<li>Setting up devices for Bluetooth communications<\/li>\n<li>More features in future tutorials!<\/li>\n<\/ul>\n<p><strong>Downloads<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/appinventor.pevest.com\/source\/tutorials\/BTClient1.aia\">BTClient1.aia<\/a> App Inventor <a href=\"http:\/\/appinventor.pevest.com\/source\/tutorials\/ButtonChangeColor.aia\">\u00a0source file <\/a>\u00a0(App Inventor source code files have the filename extension .aia)<\/li>\n<li><a href=\"http:\/\/appinventor.pevest.com\/source\/tutorials\/BTServer1.aia\">BTServer1.aia<\/a> App Inventor source file<\/li>\n<li>Download the source code to your computer. Then, in App Inventor, go to the Projects menu and select \u201cImport project (.aia) from my computer\u2026\u201d<\/li>\n<\/ul>\n<h2>E-Books and Printed Books<\/h2>\n<p>If you find these tutorials helpful (I hope you do!) please take a look at my books on App Inventor. To learn more about the books and where to get them (they are inexpensive) please see my <a href=\"http:\/\/appinventor.pevest.com\/?page_id=33\">App Inventor Books page<\/a>.<\/p>\n<ul>\n<li><strong>App Inventor 2 Introduction (Volume 1 e-book)<\/strong><br \/>\nStep-by-step guide to easy Android programming<\/li>\n<li><strong>App Inventor 2 Advanced Concepts\u00a0(Volume\u00a02 e-book)<\/strong><br \/>\nStep-by-step guide\u00a0to\u00a0Advanced features including TinyDB<\/li>\n<li><strong>App Inventor 2 Databases and Files<\/strong>\u00a0<strong>(Volume 3 e-book)<\/strong><br \/>\nStep-by-step TinyDB, TinyWebDB, Fusion Tables and Files<\/li>\n<li><strong>App Inventor 2 Graphics, Animation and Charts (Volume 4 e-book <em>and printed book<\/em>)<\/strong><br \/>\nStep-by-step guide to graphics, animation and charts<\/li>\n<\/ul>\n<p>Thank you for visiting! &#8212; Ed<\/p>\n<p><strong>Please Share on Social Media<\/strong><\/p>\n<p>Please click on the buttons below this post to share with your friends on Facebook or other social media.<\/p>\n<p>If you are not already following this blog, click on the following links to like on Facebook, add to your Google+ circles or follow on Twitter or in your RSS news reader. Thank you for visiting!<\/p>\n<p><a href=\"https:\/\/www.facebook.com\/appinventor2\"><img decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/10\/facebook-like.png\" alt=\"\" width=\"150\" \/><\/a><a href=\"https:\/\/plus.google.com\/107302082825289724871\/posts\"><img decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/coldstreams.com\/images\/plus-badge.png\" alt=\"\" width=\"48\" \/><\/a><a href=\"http:\/\/twitter.com\/appinventorplus\"><img decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/coldstreams.com\/images\/twitter-follow.png\" alt=\"\" width=\"100\" \/><\/a><a href=\"http:\/\/appinventor.pevest.com\/?feed=rss2\"><img decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/coldstreams.com\/images\/rss.png\" alt=\"\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Some very minor updates were made to this in November 2019). This tutorial covers basic App Inventor Bluetooth communications\u00a0 code. \u00a0 Subsequent tutorials will add additional features. To implement and test this sample code, you need access to two Android devices &#8211; one to act as a Bluetooth &#8220;server&#8221; and the other to act as &hellip; <a href=\"https:\/\/coldstreams.com\/appinventor\/2015\/01\/23\/part-1-basic-bluetooth-communications-using-app-inventor\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Part 1: Basic Bluetooth communications using App Inventor<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[19,22,28,32,46,54,85,106,130,166,178,179,204],"class_list":["post-520","post","type-post","status-publish","format-standard","hentry","category-components","tag-android","tag-app-inventor","tag-appinventor","tag-arduino","tag-bluetooth","tag-client","tag-example","tag-instructions","tag-mit-app-inventor","tag-server","tag-source","tag-source-code","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts\/520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/comments?post=520"}],"version-history":[{"count":0,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts\/520\/revisions"}],"wp:attachment":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/media?parent=520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/categories?post=520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/tags?post=520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}