mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-29 02:59:57 +02:00
Merge branch 'master' of git://github.com/funkwit/openScale into funkwit-master
This commit is contained in:
@@ -9,6 +9,15 @@
|
|||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
|
|
||||||
|
<!-- Permission to allow read of data from the database through a ContentProvider.
|
||||||
|
Marked "dangerous" so that explicit user approval is required to read this data, not
|
||||||
|
just the permission implied from installing the app from the Play Store. -->
|
||||||
|
<permission
|
||||||
|
android:name="com.health.openscale.READ_DATA"
|
||||||
|
android:description="@string/permission_read_data_description"
|
||||||
|
android:label="@string/permission_read_data_label"
|
||||||
|
android:protectionLevel="dangerous" />
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
|
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
@@ -59,6 +68,13 @@
|
|||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
android:resource="@xml/file_provider_paths" />
|
android:resource="@xml/file_provider_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
|
<provider
|
||||||
|
android:name=".core.export.OpenScaleContentProvider"
|
||||||
|
android:authorities="com.health.openscale.provider"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true"
|
||||||
|
android:readPermission="com.health.openscale.READ_DATA">
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@@ -606,4 +606,19 @@ public class OpenScale {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As getScaleUserList(), but as a Cursor for export via a Content Provider.
|
||||||
|
public Cursor getScaleUserListCursor() {
|
||||||
|
return userDAO.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// As getScaleUser(), but as a Cursor for export via a Content Provider.
|
||||||
|
public Cursor getScaleUserCursor(int userId) {
|
||||||
|
return userDAO.select(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// As getScaleMeasurementList(), but as a Cursor for export via a Content Provider.
|
||||||
|
public Cursor getScaleMeasurementListCursor(int userId) {
|
||||||
|
return measurementDAO.selectAll(userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import android.arch.persistence.room.Insert;
|
|||||||
import android.arch.persistence.room.OnConflictStrategy;
|
import android.arch.persistence.room.OnConflictStrategy;
|
||||||
import android.arch.persistence.room.Query;
|
import android.arch.persistence.room.Query;
|
||||||
import android.arch.persistence.room.Update;
|
import android.arch.persistence.room.Update;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
||||||
|
|
||||||
@@ -64,4 +65,8 @@ public interface ScaleMeasurementDAO {
|
|||||||
|
|
||||||
@Query("DELETE FROM scaleMeasurements WHERE userId = :userId")
|
@Query("DELETE FROM scaleMeasurements WHERE userId = :userId")
|
||||||
void deleteAll(int userId);
|
void deleteAll(int userId);
|
||||||
|
|
||||||
|
// selectAll() is equivalent to getAll(), but returns a Cursor, for exposing via a ContentProvider.
|
||||||
|
@Query("SELECT * FROM scaleMeasurements WHERE userId = :userId AND enabled = 1 ORDER BY datetime DESC")
|
||||||
|
Cursor selectAll(int userId);
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import android.arch.persistence.room.Delete;
|
|||||||
import android.arch.persistence.room.Insert;
|
import android.arch.persistence.room.Insert;
|
||||||
import android.arch.persistence.room.Query;
|
import android.arch.persistence.room.Query;
|
||||||
import android.arch.persistence.room.Update;
|
import android.arch.persistence.room.Update;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
import com.health.openscale.core.datatypes.ScaleUser;
|
import com.health.openscale.core.datatypes.ScaleUser;
|
||||||
|
|
||||||
@@ -45,4 +46,13 @@ public interface ScaleUserDAO {
|
|||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
void delete(ScaleUser user);
|
void delete(ScaleUser user);
|
||||||
|
|
||||||
|
// selectAll() and select() are equivalent to getall() and get(), but return a Cursor,
|
||||||
|
// for exposing via a ContentProvider.
|
||||||
|
@Query("SELECT * FROM scaleUsers")
|
||||||
|
Cursor selectAll();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM scaleUsers WHERE id = :id")
|
||||||
|
Cursor select(int id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,129 @@
|
|||||||
|
/* Copyright (C) 2018 Paul Cowan <paul@custardsource.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/package com.health.openscale.core.export;
|
||||||
|
|
||||||
|
import android.content.ContentProvider;
|
||||||
|
import android.content.ContentUris;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.UriMatcher;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.health.openscale.core.OpenScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes the user and measurement data from openScale via
|
||||||
|
* <a href="https://developer.android.com/guide/topics/providers/content-providers">Android
|
||||||
|
* Content Providers</a>. This allows other apps to access the openScale data for their own purposes
|
||||||
|
* (e.g. syncing to third-party services like Google Fit, Fitbit API, etc) without openScale itself
|
||||||
|
* needing to do so or request additional permissions. <br />
|
||||||
|
*
|
||||||
|
* This access is gated by the com.health.openscale.READ_DATA permission, which is defined in the
|
||||||
|
* manifest; it is not accessible to any other app without user confirmation.<br />
|
||||||
|
*
|
||||||
|
* The following URIs are supported:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>content://com.health.openscale.provider/user</code>: list all users.</li>
|
||||||
|
* <li><code>content://com.health.openscale.provider/user/$ID</code>: retrieve single user
|
||||||
|
* by ID.</li>
|
||||||
|
* <li><code>content://com.health.openscale.provider/user/$ID/measurements</code>:
|
||||||
|
* retrieve all measurements for the supplied user ID.</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class OpenScaleContentProvider extends ContentProvider {
|
||||||
|
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||||
|
|
||||||
|
private static final String AUTHORITY = "com.health.openscale.provider";
|
||||||
|
|
||||||
|
private static final int MATCH_TYPE_USER_LIST = 1;
|
||||||
|
private static final int MATCH_TYPE_USER_ENTRY = 2;
|
||||||
|
private static final int MATCH_TYPE_USER_MEASUREMENTS = 3;
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
uriMatcher.addURI(AUTHORITY, "user", MATCH_TYPE_USER_LIST);
|
||||||
|
uriMatcher.addURI(AUTHORITY, "user/#", MATCH_TYPE_USER_ENTRY);
|
||||||
|
uriMatcher.addURI(AUTHORITY, "user/#/measurements", MATCH_TYPE_USER_MEASUREMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType(Uri uri) {
|
||||||
|
switch (uriMatcher.match(uri)) {
|
||||||
|
case MATCH_TYPE_USER_LIST:
|
||||||
|
return "vnd.android.cursor.dir/vnd.com.health.openscale.provider.user";
|
||||||
|
|
||||||
|
case MATCH_TYPE_USER_ENTRY:
|
||||||
|
return "vnd.android.cursor.item/vnd.com.health.openscale.provider.user";
|
||||||
|
|
||||||
|
case MATCH_TYPE_USER_MEASUREMENTS:
|
||||||
|
return "vnd.android.cursor.item/vnd.com.health.openscale.provider.measurement";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(Uri uri, String[] projection, String selection,
|
||||||
|
String[] selectionArgs, String sortOrder) {
|
||||||
|
final Context context = getContext();
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
switch (uriMatcher.match(uri)) {
|
||||||
|
case MATCH_TYPE_USER_LIST:
|
||||||
|
cursor = OpenScale.getInstance().getScaleUserListCursor();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MATCH_TYPE_USER_ENTRY:
|
||||||
|
cursor = OpenScale.getInstance().getScaleUserCursor(Integer.valueOf(uri.getPathSegments().get(1)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MATCH_TYPE_USER_MEASUREMENTS:
|
||||||
|
cursor = OpenScale.getInstance().getScaleMeasurementListCursor(Integer.valueOf(uri.getPathSegments().get(1)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown URI: " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.setNotificationUri(context.getContentResolver(), uri);
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uri insert(Uri uri, ContentValues values) {
|
||||||
|
throw new UnsupportedOperationException("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int update(Uri uri, ContentValues values, String selection,
|
||||||
|
String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException("Not yet implemented");
|
||||||
|
}
|
||||||
|
}
|
@@ -190,6 +190,8 @@
|
|||||||
<string name="permission_not_granted">Permission not granted</string>
|
<string name="permission_not_granted">Permission not granted</string>
|
||||||
<string name="permission_bluetooth_info">Coarse location permission needed to search for Bluetooth devices. It can be revoked after the device is found.</string>
|
<string name="permission_bluetooth_info">Coarse location permission needed to search for Bluetooth devices. It can be revoked after the device is found.</string>
|
||||||
<string name="permission_bluetooth_info_title">Info</string>
|
<string name="permission_bluetooth_info_title">Info</string>
|
||||||
|
<string name="permission_read_data_description">read openScale data, including user information and all saved measurements</string>
|
||||||
|
<string name="permission_read_data_label">Read openScale Data</string>
|
||||||
<string name="label_next">Next</string>
|
<string name="label_next">Next</string>
|
||||||
<string name="label_long_press_drag_reorder">Long press and drag measurement to reorder</string>
|
<string name="label_long_press_drag_reorder">Long press and drag measurement to reorder</string>
|
||||||
<string name="label_click_measurement_configure">Click measurement to configure</string>
|
<string name="label_click_measurement_configure">Click measurement to configure</string>
|
||||||
|
Reference in New Issue
Block a user