{"action":"created","comment":{"url":"https://api.github.com/repos/oliexdev/openScale/pulls/comments/200821055","pull_request_review_id":135213199,"id":200821055,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMDgyMTA1NQ==","diff_hunk":"@@ -0,0 +1,129 @@\n+/* Copyright (C) 2018 Paul Cowan <paul@custardsource.com>\n+ *\n+ *    This program is free software: you can redistribute it and/or modify\n+ *    it under the terms of the GNU General Public License as published by\n+ *    the Free Software Foundation, either version 3 of the License, or\n+ *    (at your option) any later version.\n+ *\n+ *    This program is distributed in the hope that it will be useful,\n+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ *    GNU General Public License for more details.\n+ *\n+ *    You should have received a copy of the GNU General Public License\n+ *    along with this program.  If not, see <http://www.gnu.org/licenses/>\n+ */package com.health.openscale.core.export;\n+\n+import android.content.ContentProvider;\n+import android.content.ContentUris;\n+import android.content.ContentValues;\n+import android.content.Context;\n+import android.content.UriMatcher;\n+import android.database.Cursor;\n+import android.net.Uri;\n+import android.text.TextUtils;\n+import android.util.Log;\n+\n+import com.health.openscale.core.OpenScale;\n+\n+/**\n+ * Exposes the user and measurement data from openScale via\n+ * <a href=\"https://developer.android.com/guide/topics/providers/content-providers\">Android\n+ * Content Providers</a>. This allows other apps to access the openScale data for their own purposes\n+ * (e.g. syncing to third-party services like Google Fit, Fitbit API, etc) without openScale itself\n+ * needing to do so or request additional permissions. <br />\n+ *\n+ * This access is gated by the com.health.openscale.READ_DATA permission, which is defined in the\n+ * manifest; it is not accessible to any other app without user confirmation.<br />\n+ *\n+ * The following URIs are supported:\n+ * <ul>\n+ *     <li><code>content://com.health.openscale.provider/user</code>: list all users.</li>\n+ *     <li><code>content://com.health.openscale.provider/user/$ID</code>: retrieve single user\n+ *         by ID.</li>\n+ *     <li><code>content://com.health.openscale.provider/user/$ID/measurements</code>:\n+ *         retrieve all measurements for the supplied user ID.</li>\n+ * </ul>\n+ */\n+public class OpenScaleContentProvider extends ContentProvider {\n+    private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);\n+\n+    private static final String AUTHORITY = \"com.health.openscale.provider\";\n+\n+    private static final int MATCH_TYPE_USER_LIST = 1;\n+    private static final int MATCH_TYPE_USER_ENTRY = 2;\n+    private static final int MATCH_TYPE_USER_MEASUREMENTS = 3;\n+\n+\n+    static {\n+        uriMatcher.addURI(AUTHORITY, \"user\", MATCH_TYPE_USER_LIST);","path":"android_app/app/src/main/java/com/health/openscale/core/export/OpenScaleContentProvider.java","position":59,"original_position":59,"commit_id":"cfa86f738cf2959a64496dd97ff385dc8f42603f","original_commit_id":"cfa86f738cf2959a64496dd97ff385dc8f42603f","user":{"login":"erijo","id":470580,"node_id":"MDQ6VXNlcjQ3MDU4MA==","avatar_url":"https://avatars2.githubusercontent.com/u/470580?v=4","gravatar_id":"","url":"https://api.github.com/users/erijo","html_url":"https://github.com/erijo","followers_url":"https://api.github.com/users/erijo/followers","following_url":"https://api.github.com/users/erijo/following{/other_user}","gists_url":"https://api.github.com/users/erijo/gists{/gist_id}","starred_url":"https://api.github.com/users/erijo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erijo/subscriptions","organizations_url":"https://api.github.com/users/erijo/orgs","repos_url":"https://api.github.com/users/erijo/repos","events_url":"https://api.github.com/users/erijo/events{/privacy}","received_events_url":"https://api.github.com/users/erijo/received_events","type":"User","site_admin":false},"body":"I think this should be \"users\" instead of \"user\".","created_at":"2018-07-07T20:03:39Z","updated_at":"2018-07-07T20:08:04Z","html_url":"https://github.com/oliexdev/openScale/pull/304#discussion_r200821055","pull_request_url":"https://api.github.com/repos/oliexdev/openScale/pulls/304","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/comments/200821055"},"html":{"href":"https://github.com/oliexdev/openScale/pull/304#discussion_r200821055"},"pull_request":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/304"}}},"pull_request":{"url":"https://api.github.com/repos/oliexdev/openScale/pulls/304","id":199252899,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk5MjUyODk5","html_url":"https://github.com/oliexdev/openScale/pull/304","diff_url":"https://github.com/oliexdev/openScale/pull/304.diff","patch_url":"https://github.com/oliexdev/openScale/pull/304.patch","issue_url":"https://api.github.com/repos/oliexdev/openScale/issues/304","number":304,"state":"open","locked":false,"title":"Add a ContentProvider so other apps can access (with permission) the …","user":{"login":"funkwit","id":317030,"node_id":"MDQ6VXNlcjMxNzAzMA==","avatar_url":"https://avatars0.githubusercontent.com/u/317030?v=4","gravatar_id":"","url":"https://api.github.com/users/funkwit","html_url":"https://github.com/funkwit","followers_url":"https://api.github.com/users/funkwit/followers","following_url":"https://api.github.com/users/funkwit/following{/other_user}","gists_url":"https://api.github.com/users/funkwit/gists{/gist_id}","starred_url":"https://api.github.com/users/funkwit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/funkwit/subscriptions","organizations_url":"https://api.github.com/users/funkwit/orgs","repos_url":"https://api.github.com/users/funkwit/repos","events_url":"https://api.github.com/users/funkwit/events{/privacy}","received_events_url":"https://api.github.com/users/funkwit/received_events","type":"User","site_admin":false},"body":"…openScale data.\r\n\r\nThis could be used for e.g. syncing weight logs to a third-party service such as Google Fit,\r\nwithout the openScale app having to do so; with this, a 'connector' app could be written that\r\nreads this data and does the push to a third-party service (or, indeed, an HTTP RPC connector,\r\nan MQTT connector, SMS notifications, or anything else) without openScale needing this\r\nfunctionality (or additional permissions).\r\n\r\nThis is a straw-man implementation; happy to discuss how you think this should work, if this is a dumb idea altogether and I should abandon it, etc. Really a proof-of-concept as much as anything else. This is, though, basically the approach suggested by oliexdev at https://github.com/oliexdev/openScale/issues/82 - \"Another solution is to write for e.g. lets call it \"openScale Connector\" app which listen and access the internal sql database of openScale and send any new data via MQTT or to any company clouds (GARMIN,Google Fit and so on)\", and I think a ContentProvider is the most \"Androidy\" way to do this (and allows locking down this sensitive data behind permissions to prevent malicious apps doing so without user knowledge).\r\n\r\nHere's how the flow looks from a dummy third-party app I hacked together which just dumps the data as text:\r\n![screenshot_1530710525](https://user-images.githubusercontent.com/317030/42279913-96a79d00-7fe2-11e8-9cda-78716e112bc2.png)\r\n![screenshot_1530710530](https://user-images.githubusercontent.com/317030/42279952-b3978e7a-7fe2-11e8-9c1b-f27ef6404162.png)\r\n![screenshot_1530710576](https://user-images.githubusercontent.com/317030/42279976-c424322a-7fe2-11e8-9cc1-5756142ec0ee.png)\r\n","created_at":"2018-07-04T13:39:25Z","updated_at":"2018-07-07T20:08:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ff977ad5355b8dda8a3981db12468f3baf904c7d","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/oliexdev/openScale/pulls/304/commits","review_comments_url":"https://api.github.com/repos/oliexdev/openScale/pulls/304/comments","review_comment_url":"https://api.github.com/repos/oliexdev/openScale/pulls/comments{/number}","comments_url":"https://api.github.com/repos/oliexdev/openScale/issues/304/comments","statuses_url":"https://api.github.com/repos/oliexdev/openScale/statuses/cfa86f738cf2959a64496dd97ff385dc8f42603f","head":{"label":"funkwit:master","ref":"master","sha":"cfa86f738cf2959a64496dd97ff385dc8f42603f","user":{"login":"funkwit","id":317030,"node_id":"MDQ6VXNlcjMxNzAzMA==","avatar_url":"https://avatars0.githubusercontent.com/u/317030?v=4","gravatar_id":"","url":"https://api.github.com/users/funkwit","html_url":"https://github.com/funkwit","followers_url":"https://api.github.com/users/funkwit/followers","following_url":"https://api.github.com/users/funkwit/following{/other_user}","gists_url":"https://api.github.com/users/funkwit/gists{/gist_id}","starred_url":"https://api.github.com/users/funkwit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/funkwit/subscriptions","organizations_url":"https://api.github.com/users/funkwit/orgs","repos_url":"https://api.github.com/users/funkwit/repos","events_url":"https://api.github.com/users/funkwit/events{/privacy}","received_events_url":"https://api.github.com/users/funkwit/received_events","type":"User","site_admin":false},"repo":{"id":139370440,"node_id":"MDEwOlJlcG9zaXRvcnkxMzkzNzA0NDA=","name":"openScale","full_name":"funkwit/openScale","owner":{"login":"funkwit","id":317030,"node_id":"MDQ6VXNlcjMxNzAzMA==","avatar_url":"https://avatars0.githubusercontent.com/u/317030?v=4","gravatar_id":"","url":"https://api.github.com/users/funkwit","html_url":"https://github.com/funkwit","followers_url":"https://api.github.com/users/funkwit/followers","following_url":"https://api.github.com/users/funkwit/following{/other_user}","gists_url":"https://api.github.com/users/funkwit/gists{/gist_id}","starred_url":"https://api.github.com/users/funkwit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/funkwit/subscriptions","organizations_url":"https://api.github.com/users/funkwit/orgs","repos_url":"https://api.github.com/users/funkwit/repos","events_url":"https://api.github.com/users/funkwit/events{/privacy}","received_events_url":"https://api.github.com/users/funkwit/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/funkwit/openScale","description":"openScale is an open source app which support various Bluetooth scales to keep log of your body metrics.","fork":true,"url":"https://api.github.com/repos/funkwit/openScale","forks_url":"https://api.github.com/repos/funkwit/openScale/forks","keys_url":"https://api.github.com/repos/funkwit/openScale/keys{/key_id}","collaborators_url":"https://api.github.com/repos/funkwit/openScale/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/funkwit/openScale/teams","hooks_url":"https://api.github.com/repos/funkwit/openScale/hooks","issue_events_url":"https://api.github.com/repos/funkwit/openScale/issues/events{/number}","events_url":"https://api.github.com/repos/funkwit/openScale/events","assignees_url":"https://api.github.com/repos/funkwit/openScale/assignees{/user}","branches_url":"https://api.github.com/repos/funkwit/openScale/branches{/branch}","tags_url":"https://api.github.com/repos/funkwit/openScale/tags","blobs_url":"https://api.github.com/repos/funkwit/openScale/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/funkwit/openScale/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/funkwit/openScale/git/refs{/sha}","trees_url":"https://api.github.com/repos/funkwit/openScale/git/trees{/sha}","statuses_url":"https://api.github.com/repos/funkwit/openScale/statuses/{sha}","languages_url":"https://api.github.com/repos/funkwit/openScale/languages","stargazers_url":"https://api.github.com/repos/funkwit/openScale/stargazers","contributors_url":"https://api.github.com/repos/funkwit/openScale/contributors","subscribers_url":"https://api.github.com/repos/funkwit/openScale/subscribers","subscription_url":"https://api.github.com/repos/funkwit/openScale/subscription","commits_url":"https://api.github.com/repos/funkwit/openScale/commits{/sha}","git_commits_url":"https://api.github.com/repos/funkwit/openScale/git/commits{/sha}","comments_url":"https://api.github.com/repos/funkwit/openScale/comments{/number}","issue_comment_url":"https://api.github.com/repos/funkwit/openScale/issues/comments{/number}","contents_url":"https://api.github.com/repos/funkwit/openScale/contents/{+path}","compare_url":"https://api.github.com/repos/funkwit/openScale/compare/{base}...{head}","merges_url":"https://api.github.com/repos/funkwit/openScale/merges","archive_url":"https://api.github.com/repos/funkwit/openScale/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/funkwit/openScale/downloads","issues_url":"https://api.github.com/repos/funkwit/openScale/issues{/number}","pulls_url":"https://api.github.com/repos/funkwit/openScale/pulls{/number}","milestones_url":"https://api.github.com/repos/funkwit/openScale/milestones{/number}","notifications_url":"https://api.github.com/repos/funkwit/openScale/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/funkwit/openScale/labels{/name}","releases_url":"https://api.github.com/repos/funkwit/openScale/releases{/id}","deployments_url":"https://api.github.com/repos/funkwit/openScale/deployments","created_at":"2018-07-01T23:39:54Z","updated_at":"2018-07-04T13:32:04Z","pushed_at":"2018-07-04T13:32:02Z","git_url":"git://github.com/funkwit/openScale.git","ssh_url":"git@github.com:funkwit/openScale.git","clone_url":"https://github.com/funkwit/openScale.git","svn_url":"https://github.com/funkwit/openScale","homepage":"","size":137802,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"oliexdev:master","ref":"master","sha":"69312b83ad4ee107fa55a1768e45d7ddbce8bb70","user":{"login":"oliexdev","id":10166185,"node_id":"MDQ6VXNlcjEwMTY2MTg1","avatar_url":"https://avatars1.githubusercontent.com/u/10166185?v=4","gravatar_id":"","url":"https://api.github.com/users/oliexdev","html_url":"https://github.com/oliexdev","followers_url":"https://api.github.com/users/oliexdev/followers","following_url":"https://api.github.com/users/oliexdev/following{/other_user}","gists_url":"https://api.github.com/users/oliexdev/gists{/gist_id}","starred_url":"https://api.github.com/users/oliexdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oliexdev/subscriptions","organizations_url":"https://api.github.com/users/oliexdev/orgs","repos_url":"https://api.github.com/users/oliexdev/repos","events_url":"https://api.github.com/users/oliexdev/events{/privacy}","received_events_url":"https://api.github.com/users/oliexdev/received_events","type":"User","site_admin":false},"repo":{"id":27954737,"node_id":"MDEwOlJlcG9zaXRvcnkyNzk1NDczNw==","name":"openScale","full_name":"oliexdev/openScale","owner":{"login":"oliexdev","id":10166185,"node_id":"MDQ6VXNlcjEwMTY2MTg1","avatar_url":"https://avatars1.githubusercontent.com/u/10166185?v=4","gravatar_id":"","url":"https://api.github.com/users/oliexdev","html_url":"https://github.com/oliexdev","followers_url":"https://api.github.com/users/oliexdev/followers","following_url":"https://api.github.com/users/oliexdev/following{/other_user}","gists_url":"https://api.github.com/users/oliexdev/gists{/gist_id}","starred_url":"https://api.github.com/users/oliexdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oliexdev/subscriptions","organizations_url":"https://api.github.com/users/oliexdev/orgs","repos_url":"https://api.github.com/users/oliexdev/repos","events_url":"https://api.github.com/users/oliexdev/events{/privacy}","received_events_url":"https://api.github.com/users/oliexdev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/oliexdev/openScale","description":"openScale is an open source app which support various Bluetooth scales to keep log of your body metrics.","fork":false,"url":"https://api.github.com/repos/oliexdev/openScale","forks_url":"https://api.github.com/repos/oliexdev/openScale/forks","keys_url":"https://api.github.com/repos/oliexdev/openScale/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oliexdev/openScale/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oliexdev/openScale/teams","hooks_url":"https://api.github.com/repos/oliexdev/openScale/hooks","issue_events_url":"https://api.github.com/repos/oliexdev/openScale/issues/events{/number}","events_url":"https://api.github.com/repos/oliexdev/openScale/events","assignees_url":"https://api.github.com/repos/oliexdev/openScale/assignees{/user}","branches_url":"https://api.github.com/repos/oliexdev/openScale/branches{/branch}","tags_url":"https://api.github.com/repos/oliexdev/openScale/tags","blobs_url":"https://api.github.com/repos/oliexdev/openScale/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oliexdev/openScale/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oliexdev/openScale/git/refs{/sha}","trees_url":"https://api.github.com/repos/oliexdev/openScale/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oliexdev/openScale/statuses/{sha}","languages_url":"https://api.github.com/repos/oliexdev/openScale/languages","stargazers_url":"https://api.github.com/repos/oliexdev/openScale/stargazers","contributors_url":"https://api.github.com/repos/oliexdev/openScale/contributors","subscribers_url":"https://api.github.com/repos/oliexdev/openScale/subscribers","subscription_url":"https://api.github.com/repos/oliexdev/openScale/subscription","commits_url":"https://api.github.com/repos/oliexdev/openScale/commits{/sha}","git_commits_url":"https://api.github.com/repos/oliexdev/openScale/git/commits{/sha}","comments_url":"https://api.github.com/repos/oliexdev/openScale/comments{/number}","issue_comment_url":"https://api.github.com/repos/oliexdev/openScale/issues/comments{/number}","contents_url":"https://api.github.com/repos/oliexdev/openScale/contents/{+path}","compare_url":"https://api.github.com/repos/oliexdev/openScale/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oliexdev/openScale/merges","archive_url":"https://api.github.com/repos/oliexdev/openScale/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oliexdev/openScale/downloads","issues_url":"https://api.github.com/repos/oliexdev/openScale/issues{/number}","pulls_url":"https://api.github.com/repos/oliexdev/openScale/pulls{/number}","milestones_url":"https://api.github.com/repos/oliexdev/openScale/milestones{/number}","notifications_url":"https://api.github.com/repos/oliexdev/openScale/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oliexdev/openScale/labels{/name}","releases_url":"https://api.github.com/repos/oliexdev/openScale/releases{/id}","deployments_url":"https://api.github.com/repos/oliexdev/openScale/deployments","created_at":"2014-12-13T08:36:53Z","updated_at":"2018-07-07T16:48:41Z","pushed_at":"2018-07-06T21:17:45Z","git_url":"git://github.com/oliexdev/openScale.git","ssh_url":"git@github.com:oliexdev/openScale.git","clone_url":"https://github.com/oliexdev/openScale.git","svn_url":"https://github.com/oliexdev/openScale","homepage":"","size":137943,"stargazers_count":247,"watchers_count":247,"language":"Java","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":74,"mirror_url":null,"archived":false,"open_issues_count":14,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":74,"open_issues":14,"watchers":247,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/304"},"html":{"href":"https://github.com/oliexdev/openScale/pull/304"},"issue":{"href":"https://api.github.com/repos/oliexdev/openScale/issues/304"},"comments":{"href":"https://api.github.com/repos/oliexdev/openScale/issues/304/comments"},"review_comments":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/304/comments"},"review_comment":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/oliexdev/openScale/pulls/304/commits"},"statuses":{"href":"https://api.github.com/repos/oliexdev/openScale/statuses/cfa86f738cf2959a64496dd97ff385dc8f42603f"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"erijo"}}