{"id":1668,"date":"2015-03-19T02:51:18","date_gmt":"2015-03-19T00:51:18","guid":{"rendered":"http:\/\/www.awareframework.com\/?p=1668"},"modified":"2025-01-14T03:32:02","modified_gmt":"2025-01-14T03:32:02","slug":"how-do-i-read-data","status":"publish","type":"post","link":"https:\/\/awareframework.com\/how-do-i-read-data\/","title":{"rendered":"How do I read data?"},"content":{"rendered":"<div id=\"top\">\n<p><button style=\"width: 25%; margin: 10px;\">Read data &#8211; passive context<\/button><button style=\"width: 25%; margin: 10px;\">Listen to data changes<\/button><button style=\"width: 25%; margin: 10px;\">Listen for new values<\/button><\/p>\n<div id=\"read\">\n<p>Depending on the <em>way<\/em> you want to access the data, you have three basic methods for reading it in an AWARE plugin or an application that uses AWARE as a library.<\/p>\n<ul>\n<li><a href=\"#read1\">Passive context &#8211; access the data from the database when you need it<\/a><\/li>\n<li>Active context\n<ul>\n<li><a href=\"#read2\">Listening to data changes &#8211; read new data from the database when it gets inserted<\/a><\/li>\n<li><a href=\"#read3\">Listening to new values\u00a0&#8211; read the new data as it gets broadcasted by a sensor or a plugin<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<\/div>\n<div id=\"read1\">\n<h2><strong>Passive context<\/strong><\/h2>\n<p>Reading the data directly from the database can be used using simple SQL queries (since the data is stored in an SQLite database). In this example, if you replace the tableColumns, whereCondition,\u00a0and whereArguments with null, you get all the accelerometer records into memory. Please note that, depending on your device and available RAM, you may have to impose a whereCondition\u00a0when loading all the records on your database. For example, to read the accelerometer data table, you will need a line like this:<\/p>\n<pre>Cursor accelerometer_data = getContentResolver().query(Accelerometer_Data.CONTENT_URI, tableColumns, whereCondition, whereArguments, orderBy);<\/pre>\n<p>This line returns a cursor object containing data from the defined URI, in this case the URI for the accelerometer&#8217;s database. The other parameters for the query() method are the conditions for your SQL query. Here is an example to retrieve all the good records from the database (with good accuracy) in an ascendent orderly fashion:<\/p>\n<pre>Cursor accelerometer_data = getContentResolver().query(Accelerometer_Data.CONTENT_URI, null, \"accuracy &gt; 1\", null, \"timestamp ASC\");<\/pre>\n<p>This query would return the data for all the table columns where the accuracy value is greater than 1 (low accuracy) and order the results chronologically (in an ascending order). The SQL query that is run is as follows.<\/p>\n<pre>SELECT * FROM accelerometer_data WHERE accuracy &gt; 1 ORDER BY timestamp ASC<\/pre>\n<p>The data that was fetched will then be stored in the cursor object and can be read by moving the position within the cursor (moveToNext() method for example) and then reading the value for a field with the get methods (such as getString() which returns a string).<\/p>\n<pre>accelerometer_data.moveToFirst();\ndo {\n   double x = accelerometer_data.getDouble(accelerometer_data.getColumnIndex(Accelerometer_Data.VALUES_0));\n   double y = accelerometer_data.getDouble(accelerometer_data.getColumnIndex(Accelerometer_Data.VALUES_1));\n   double z = accelerometer_data.getDouble(accelerometer_data.getColumnIndex(Accelerometer_Data.VALUES_2));\n   \/\/do what you need with x,y,z variables\n} while (accelerometer_data.moveToNext());<\/pre>\n<p>This will iterate through all the fetched results, since the moveToNext() method returns False if is already in the last result and tries to move to the next (non-existing) result,\u00a0resulting in the while-loop ending.<\/p>\n<p>This method of reading data is best for analyzing past datapoints or reading data at certain intervals. If you want to access data directly when it is stored, you can use the other two methods explained below.<\/p>\n<hr \/>\n<\/div>\n<div id=\"read2\">\n<p><button style=\"width: 20%;\">Back to top<\/button><\/p>\n<h2><strong>Active context method #1 &#8211; listening to changes in the data<\/strong><\/h2>\n<p>In addition to passively reading data when the plugin finds it applicable, there are methods to also read the data in real time as it changes. The first method is to listen to the database for changes and then read the latest values.<\/p>\n<p>The way to implement this functionality is to create a custom <em>ContentObserver<\/em> class.<\/p>\n<pre>public class ScreenObserver extends ContentObserver {\n    public ScreenObserver(Handler handler) {\n         super(handler);\n    }<\/pre>\n<p>The ContentObserver class has an onChange() method\u00a0that gets triggered everytime the database (&#8220;content&#8221;) it is listening to experiences changes (e.g. when new values get inserted). Inside the onChange() method you can include the functionality that you want to happen when the database changes, such as reading the new values.<\/p>\n<pre>public void onChange(boolean selfChange) {\n    super(selfChange);\n    \/\/ Get the latest recorded value\n    Cursor screen = getContentResolver().query(Screen_Data.CONTENT_URI, null, null, null,\n        Screen_Data.TIMESTAMP + \u201d DESC LIMIT 1\u201d);\n    if (screen != null &amp;&amp; screen.moveToFirst()) {\n        \/\/ Here we read the value\n        int screen_status = screen.getInt(screen.getColumnIndex(Screen_Data.SCREEN_STATUS);\n    }\n}<\/pre>\n<p>Finally, you need to register your newly created ScreenObserver to your plugin and define to what URI it is listening to inside your Plugin.java file.<\/p>\n<pre>ScreenObserver so = new ScreenObserver(new Handler());\ngetContentResolver().registerContentObserver(Screen_Data.CONTENT_URI, true, so);<\/pre>\n<p>Also, its important that you <em>unregister<\/em>\u00a0the observer in the onDestroy() method of your plugin so that your plugin does not cause memory leaks (the observers get left on even if your plugin crashes or is closed by Android).<\/p>\n<pre>getContentResolver().unregisterContentObserver(so);<\/pre>\n<p>Using this method you can always get the latest value from the database as the values change.<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<\/div>\n<div id=\"read3\">\n<p><button style=\"width: 20%;\">Back to top<\/button><\/p>\n<h2><strong>Active context method #2 &#8211; l<\/strong><strong>istening to new\u00a0broadcasts<\/strong><\/h2>\n<p>The new values from sensors and plugins are also broadcasted across\u00a0Android by using <em>broadcast<\/em> services. Broadcasts are ways for different processes to communicate with each other. Basically each application can register to listen to different broadcasts or send broadcasts and will be notified every time a new broadcast is sent system-wide.<\/p>\n<p>What you need to do is to create a new custom <em>BroadcastReceiver<\/em> class. The class will inherit a method onReceive() that gets called everytime the listener receives new broadcasts.<\/p>\n<pre>public class ScreenStatusListener extends BroadcastReceiver {\n    public void onReceive(Context c, Intent intent) {\n        Log.d(TAG, \u201dYay the screen was unlocked!\u201d);\n    }\n}<\/pre>\n<p>The information of the broadcast (such as new data values) is inside the Intent object that the onReceive() method receives. Specifically inside any <em>broadcast extras<\/em>\u00a0in the intent. The data can be then accessed by looking at the specific sensor&#8217;s information for what broadcasts and extras it sends.<\/p>\n<pre>public void onReceive(Context c, Intent intent) {\n    Object o = intent.getExtras().get(\"name of the extra\");\n}<\/pre>\n<p>Finally, you need to create the listener and register it inside your Plugin.java class. Its preferred to create the listeners as static class variables.<\/p>\n<pre>private static ScreenStatusListener ssl = new ScreenStatusListener();<\/pre>\n<p>The rest of the code can go inside the onCreate() or onResume() method.<\/p>\n<pre>IntentFilter broadcastFilter = new IntentFilter();\nbroadcastFilter.addAction(Screen.ACTION_AWARE_SCREEN_UNLOCKED);\nregisterReceiver(ssl, broadcastFilter);<\/pre>\n<p>The action you are adding to the filter is the type of broadcast the listener is triggered on.<\/p>\n<p>Again, its important to <em>unregister<\/em>\u00a0the receiver in the onDestroy() method to prevent memory leaks.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Read data &#8211; passive contextListen to data changesListen for new values Depending on the way you want to access the data, you have three basic methods for reading it in an AWARE plugin or an application that uses AWARE as<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1668","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/posts\/1668","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/comments?post=1668"}],"version-history":[{"count":1,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/posts\/1668\/revisions"}],"predecessor-version":[{"id":3396,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/posts\/1668\/revisions\/3396"}],"wp:attachment":[{"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/media?parent=1668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/categories?post=1668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/awareframework.com\/wp-json\/wp\/v2\/tags?post=1668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}