Skip to content

Commit

Permalink
Merge pull request #272 from BenediktBroich/openscale
Browse files Browse the repository at this point in the history
Feature: Add openScale Weight import
  • Loading branch information
brodeurlv authored Feb 18, 2024
2 parents c7007fd + 2dbf173 commit fdf96e9
Show file tree
Hide file tree
Showing 6 changed files with 690 additions and 450 deletions.
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.ACTION_HEADSET_PLUG" />
<uses-permission android:name="com.health.openscale.READ_WRITE_DATA" />
<uses-permission android:name="com.health.openscale.light.READ_WRITE_DATA" />
<uses-permission android:name="com.health.openscale.pro.READ_WRITE_DATA" />

<queries>
<package android:name="com.health.openscale" />
</queries>

<uses-feature
android:name="android.hardware.camera.any"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public void addBodyMeasure(SQLiteDatabase db, Date pDate, long pBodyPartId, Valu
ContentValues value = new ContentValues();

// Only one measure pr day, so if one already existing, updates it.
// Also filters duplicates when using openScale import.
BodyMeasure existingBodyMeasure = getBodyMeasuresFromDate(db, pBodyPartId, pDate, pProfileId);
if (existingBodyMeasure == null) {

Expand Down
174 changes: 174 additions & 0 deletions app/src/main/java/com/easyfitness/DAO/export/OpenScaleSync.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package com.easyfitness.DAO.export;

import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
import com.easyfitness.BuildConfig;
import com.easyfitness.DAO.DAOMachine;
import com.easyfitness.DAO.DAOProfile;
import com.easyfitness.DAO.DAOProfileWeight;
import com.easyfitness.DAO.Machine;
import com.easyfitness.DAO.Profile;
import com.easyfitness.DAO.ProfileWeight;
import com.easyfitness.DAO.ProgressImage;
import com.easyfitness.DAO.bodymeasures.BodyMeasure;
import com.easyfitness.DAO.bodymeasures.BodyPart;
import com.easyfitness.DAO.bodymeasures.BodyPartExtensions;
import com.easyfitness.DAO.bodymeasures.DAOBodyMeasure;
import com.easyfitness.DAO.bodymeasures.DAOBodyPart;
import com.easyfitness.DAO.cardio.DAOOldCardio;
import com.easyfitness.DAO.program.DAOProgram;
import com.easyfitness.DAO.program.Program;
import com.easyfitness.DAO.progressimages.DAOProgressImage;
import com.easyfitness.DAO.record.DAOCardio;
import com.easyfitness.DAO.record.DAORecord;
import com.easyfitness.DAO.record.Record;
import com.easyfitness.SettingsFragment;
import com.easyfitness.enums.DistanceUnit;
import com.easyfitness.enums.ExerciseType;
import com.easyfitness.enums.ProgramRecordStatus;
import com.easyfitness.enums.RecordType;
import com.easyfitness.enums.SizeUnit;
import com.easyfitness.enums.Unit;
import com.easyfitness.enums.WeightUnit;
import com.easyfitness.utils.DateConverter;
import com.easyfitness.utils.FileNameUtil;
import com.easyfitness.utils.ImageUtil;
import com.easyfitness.utils.UnitConverter;
import com.easyfitness.utils.Value;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;


// Uses http://javacsv.sourceforge.net/com/csvreader/CsvReader.html //
public class OpenScaleSync {
private Context mContext;
private Activity mActivity;
final String APP_ID = "com.health.openscale";
final String AUTHORITY = APP_ID + ".provider";
final String REQUIRED_PERMISSION = APP_ID + ".READ_DATA";

public OpenScaleSync(Context pContext, Activity pActivity) {
mContext = pContext;
mActivity = pActivity;
}

public boolean importDatabase() {
boolean ret = true;

// Uri metaUri = new Uri.Builder()
// .scheme(ContentResolver.SCHEME_CONTENT)
// .authority(AUTHORITY)
// .path("meta")
// .build();
Uri usersUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.path("users")
.build();
Uri measurementsUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.path("measurements")
.build();

try {
// Cursor cursor = mContext.getContentResolver().query(
// metaUri, null, null, null, null);

// try {
// while (cursor.moveToNext()) {
// Integer apiVersion = Integer.valueOf(cursor.getInt(cursor.getColumnIndex("apiVersion")));
// Integer versionCode = Integer.valueOf(cursor.getInt(cursor.getColumnIndex("versionCode")));
// }
// } finally {
// cursor.close();
// }

Cursor cursor = mContext.getContentResolver().query(
usersUri, null, null, null, null);

try {
while (cursor.moveToNext()) {
Integer id = cursor.getInt(cursor.getColumnIndex("_ID"));
String username = cursor.getString(cursor.getColumnIndex("username"));
// Date birthday = DateConverter.DBDateStrToDate(cursor.getString(cursor.getColumnIndex("birthday")));
// Integer gender = cursor.getInt(cursor.getColumnIndex("gender"));
// Integer activityLevel = cursor.getInt(cursor.getColumnIndex("activityLevel"));
// Double bodyHeight = cursor.getDouble(cursor.getColumnIndex("bodyHeight"));
// Double measureUnit = cursor.getDouble(cursor.getColumnIndex("measureUnit"));
Unit defaultWeightUnit = SettingsFragment.getDefaultWeightUnit(mActivity).toUnit();
// Unit defaultDiestanceUnit = SettingsFragment.getDefaultDistanceUnit(mActivity).toUnit();
// Unit defaulSizeUnit = SettingsFragment.getDefaultSizeUnit(mActivity);


Cursor m = mContext.getContentResolver().query(
ContentUris.withAppendedId(measurementsUri, id),
null, null, null, null);

DAOProfile mDbProfiles = new DAOProfile(mContext);
Profile profile = mDbProfiles.getProfile(username);
long userId = profile.getId();


try {
while (m.moveToNext()) {
DAOBodyMeasure dbcWeight = new DAOBodyMeasure(mContext);
dbcWeight.open();

// Integer measurement_id = m.getInt(m.getColumnIndex("_ID"));
Date datetime = new Date(m.getLong(m.getColumnIndex("datetime")));
Float weight = m.getFloat(m.getColumnIndex("weight"));
Float fat = m.getFloat(m.getColumnIndex("fat"));
Float water = m.getFloat(m.getColumnIndex("water"));
Float muscle = m.getFloat(m.getColumnIndex("muscle"));

dbcWeight.addBodyMeasure(datetime, BodyPartExtensions.WEIGHT, new Value(weight, defaultWeightUnit), userId);
dbcWeight.addBodyMeasure(datetime, BodyPartExtensions.FAT, new Value(fat, Unit.PERCENTAGE),userId);
dbcWeight.addBodyMeasure(datetime, BodyPartExtensions.WATER, new Value(water, Unit.PERCENTAGE),userId);
dbcWeight.addBodyMeasure(datetime, BodyPartExtensions.MUSCLES, new Value(muscle, Unit.PERCENTAGE),userId);
dbcWeight.close();
}
} finally {
m.close();
}
}
} finally {
cursor.close();
}
}
catch (Exception e) {
ret = false;
}
return ret;
}
}
47 changes: 47 additions & 0 deletions app/src/main/java/com/easyfitness/WeightFragment.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.easyfitness;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
Expand All @@ -17,10 +19,13 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.PreferenceManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.easyfitness.DAO.DAOProfile;
import com.easyfitness.DAO.DAOProfileWeight;
Expand All @@ -30,6 +35,7 @@
import com.easyfitness.DAO.bodymeasures.BodyPartExtensions;
import com.easyfitness.DAO.bodymeasures.DAOBodyMeasure;
import com.easyfitness.DAO.bodymeasures.DAOBodyPart;
import com.easyfitness.DAO.export.OpenScaleSync;
import com.easyfitness.bodymeasures.BodyPartDetailsFragment;
import com.easyfitness.enums.Unit;
import com.easyfitness.enums.UnitType;
Expand Down Expand Up @@ -137,6 +143,8 @@ public class WeightFragment extends Fragment {
};
double calorieMultiplier; //Daily calorie multiplier
MainActivity mActivity = null;

private SwipeRefreshLayout pullToRefresh = null;
private TextView weightEdit = null;
private TextView fatEdit = null;
private TextView musclesEdit = null;
Expand Down Expand Up @@ -362,6 +370,45 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.tab_weight, container, false);

// Disable pullToRefresh on default
pullToRefresh = view.findViewById(R.id.pullToRefresh);
pullToRefresh.setEnabled(false);
try{
// Check if openScale is installed
PackageManager pm = mActivity.getPackageManager();
pm.getPackageInfo("com.health.openscale", 0);

// If openScale is installed enable pull to refresh
pullToRefresh.setEnabled(true);

// Set listener for updateing
pullToRefresh.setOnRefreshListener(() -> {

// Check access permission to openScale
int OPENSCALE_REQUEST_CODE = 2;
int openHealthPermission = ContextCompat.checkSelfPermission(mActivity,"com.health.openscale.READ_WRITE_DATA");
if (openHealthPermission != PackageManager.PERMISSION_GRANTED) {

// Request access permisson
ActivityCompat.requestPermissions((Activity) mActivity,
new String[]{"com.health.openscale.READ_WRITE_DATA"},
OPENSCALE_REQUEST_CODE);
pullToRefresh.setRefreshing(false);
return;
}

// Import openScale data
OpenScaleSync openScaleSync = new OpenScaleSync(mActivity.getBaseContext(), getActivity());
if (openScaleSync.importDatabase()) {
// Refresh view after loading data
refreshData();
}
pullToRefresh.setRefreshing(false);
});
} catch (Exception ignored){

}

/* Views Initialisation */
weightEdit = view.findViewById(R.id.weightInput);
fatEdit = view.findViewById(R.id.fatInput);
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/easyfitness/utils/MusicController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.easyfitness.utils;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
Expand Down Expand Up @@ -33,6 +34,7 @@
import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile;

import com.easyfitness.DAO.export.OpenScaleSync;
import com.easyfitness.MainActivity;
import com.easyfitness.R;

Expand Down Expand Up @@ -457,6 +459,7 @@ private boolean isExternalStoragePermissionDenied() {

private void requestPermissionForReading() {
int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 103;

ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
Expand Down
Loading

0 comments on commit fdf96e9

Please sign in to comment.