Skip to content

Commit

Permalink
Merge branch 'release/1.10.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasrafael committed Feb 1, 2020
2 parents a4824cd + 3c97ea5 commit c49a68f
Show file tree
Hide file tree
Showing 26 changed files with 544 additions and 279 deletions.
31 changes: 14 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,18 @@

Native Android application responsible for OCARIoT platform data acquisition. The application acts as an external services access token manager. Currently, only Fitbit service is available.

**Main Features:**
- Fitbit access token management:
- The educator and the qualified professional can grant the OCARIoT platform permission to collect Fitbit data from children who have privileges to manage their data according to the consent of those responsible;
- Support to request collection of Fitbit data from the child at any time, automatically saving to the OCARIoT platform;
- Revocation of permission to collect Fitbit data;

- Display of data saved on the OCARIoT platform:
- Physical activity;
- Sleep;
- Weight.

- Display of heart rate data collected in real time. Supported devices:
- Polar OH;
- Polar H10.

**MAIN FEATURES:**
- **Fitbit access token management:**
    - The Educator and the Health Professional can grant the OCARIoT platform permission to collect Fitbit data from children who have privileges to manage their data according to the consent of those responsible;
    - Support to request collection of Fitbit data from the child at any time, automatically saving to the OCARIoT platform;
    - Revocation of permission to collect Fitbit data.
- **Display of data saved on the OCARIoT platform:**
    - Physical activity;
    - Sleep;
    - Weight.
- **Display of heart rate data collected in real time. Supported devices:**
   - Polar OH1;
   - H10.

## Prerequisites
- Android SDK v28
Expand All @@ -39,7 +36,7 @@ Native Android application responsible for OCARIoT platform data acquisition. Th
- Change the values of the variables you find necessary according to your development and production environment.
3. **Open project in Android Studio:**
- From the Android Studio menu, click File > Open.
- Alternatively, on the "Welcome" screen, click > Open an existing Android Studio project.
- Alternatively, on the "Welcome" screen, click > Open an existing Android Studio project.
- Select the project folder and click OK.

## Generating signed APK
Expand Down Expand Up @@ -88,7 +85,7 @@ From Android Studio:

#####

<img align="left" src="https://i.imgur.com/GITTjts.png" width="200" />
<img align="left" src="https://i.imgur.com/5j3YeNy.png" width="200" />
<img align="left" src="https://i.imgur.com/GugwblV.png" width="200" />
<img align="left" src="https://i.imgur.com/VSiuJNT.png" width="200" />
<img src="https://i.imgur.com/VzM9jQU.png" width="200" />
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "br.edu.uepb.nutes.ocariot"
minSdkVersion 21
targetSdkVersion 28
versionCode 11
versionName "1.9.5"
versionCode 12
versionName "1.10.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

manifestPlaceholders = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package br.edu.uepb.nutes.ocariot.data.model.ocariot;

import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

Expand All @@ -16,7 +19,7 @@
* @author Copyright (c) 2018, NUTES/UEPB
*/
@Keep
public class Child extends User implements Comparable<Child> {
public class Child extends User implements Parcelable, Comparable<Child> {
@SerializedName("gender")
private String gender;

Expand All @@ -40,6 +43,26 @@ public Child(String username, String password) {
super(username, password);
}

protected Child(Parcel in) {
gender = in.readString();
age = in.readString();
lastSync = in.readString();
fitBitAccess = in.readParcelable(UserAccess.class.getClassLoader());
fitbitStatus = in.readString();
}

public static final Creator<Child> CREATOR = new Creator<Child>() {
@Override
public Child createFromParcel(Parcel in) {
return new Child(in);
}

@Override
public Child[] newArray(int size) {
return new Child[size];
}
};

public String getGender() {
return gender;
}
Expand Down Expand Up @@ -113,4 +136,18 @@ public String toString() {
public int compareTo(Child o) {
return super.getUsername().compareToIgnoreCase(o.getUsername());
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(gender);
dest.writeString(age);
dest.writeString(lastSync);
dest.writeParcelable(fitBitAccess, flags);
dest.writeString(fitbitStatus);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Single<List<Sleep>> listSleep(
@Query("limit") int limit
);

@GET("/v1/children/{child_id}/weights?sort=-timestamp")
@GET("/v1/children/{child_id}/weights")
Single<List<Weight>> listhWeights(
@Path("child_id") String childId,
@Query("timestamp") String startDate,
Expand Down
13 changes: 12 additions & 1 deletion app/src/main/java/br/edu/uepb/nutes/ocariot/utils/DateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
public final class DateUtils {
private static final String DATE_FORMAT_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ss";
private static final String DATE_FORMAT_DATE_TIME_UTC = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
private static final String DATE_FORMAT = "yyyy-MM-dd";

private DateUtils() {
Expand Down Expand Up @@ -146,11 +147,21 @@ public static String getCurrentDate() {
* @return String
*/
public static String getCurrentDatetimeUTC() {
SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT_DATE_TIME, Locale.getDefault());
SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT_DATE_TIME_UTC, Locale.getDefault());
format.setTimeZone(TimeZone.getTimeZone("UTC"));
return format.format(new Date());
}

/**
* Retrieve the current date according to timezone UTC.
*
* @return String
*/
public static String getCurrentDatetime() {
SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT_DATE_TIME, Locale.getDefault());
return format.format(new Date());
}

/**
* Add days in string datetime.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import androidx.recyclerview.widget.RecyclerView;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Locale;

Expand All @@ -27,6 +28,7 @@
*/
public class PhysicalActivityListAdapter extends BaseAdapter<PhysicalActivity> {
private final Context mContext;
private final DecimalFormat df = new DecimalFormat("#.##");

public PhysicalActivityListAdapter(Context context) {
this.mContext = context;
Expand All @@ -51,8 +53,11 @@ public void showData(RecyclerView.ViewHolder holder, int position, List<Physical
h.name.setText(activity.getName());
h.dateStart.setText(DateUtils.convertDateTimeUTCToLocale(activity.getStartTime(),
mContext.getResources().getString(R.string.date_time_abb1), null));
int duration = (int) (activity.getDuration() / (60 * 1000));
h.duration.setText(String.valueOf(duration));

double duration = activity.getDuration() / 60000D;
if (duration >= 1) h.duration.setText(String.valueOf((int) duration));
else h.duration.setText(df.format((duration)));

h.calories.setText(String.valueOf(activity.getCalories()));

populateImgByName(h.image, activity.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
public class ChildrenManagerActivity extends AppCompatActivity {
public static final String EXTRA_IS_FIRST_OPEN = "extra_is_first_open";
private static final String KEY_SORT_SELECTED = "key_sort_selected";
private static final int SELECTED_CHILD = 5;

private ChildListAdapter mAdapter;
private AppPreferencesHelper appPref;
Expand Down Expand Up @@ -97,10 +98,6 @@ protected void onCreate(Bundle savedInstanceState) {

mChildUsername.setVisibility(View.GONE);

mToolbar.setTitle(getResources().getString(R.string.title_children));
setSupportActionBar(mToolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);

appPref = AppPreferencesHelper.getInstance();
userAccess = appPref.getUserAccessOcariot();
mDisposable = new CompositeDisposable();
Expand Down Expand Up @@ -164,10 +161,17 @@ public boolean onPrepareOptionsMenu(Menu menu) {
* Initialize components
*/
private void initComponents() {
initToolbar();
initRecyclerView();
initDataSwipeRefresh();
}

private void initToolbar() {
mToolbar.setTitle(getResources().getString(R.string.title_children));
setSupportActionBar(mToolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
}

/**
* Initialize SwipeRefresh
*/
Expand Down Expand Up @@ -372,6 +376,8 @@ private void loading(final boolean enabled) {
mSkeletonScreen.hide();
itShouldLoadMore = true;
return;
} else {
mSkeletonScreen.show();
}
if (mAdapter.itemsIsEmpty()) mSkeletonScreen.show();
itShouldLoadMore = false;
Expand Down Expand Up @@ -408,19 +414,16 @@ private void redirectToLogin() {
* Show dialog confirm sign out in app.
*/
private void openDialogSignOut() {
runOnUiThread(() -> {
AlertDialog.Builder mDialog = new AlertDialog.Builder(this);
mDialog.setMessage(R.string.dialog_confirm_sign_out)
.setPositiveButton(R.string.title_yes, (dialog, which) -> {
if (appPref.removeSession()) {
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
runOnUiThread(() -> new AlertDialog.Builder(this)
.setMessage(R.string.dialog_confirm_sign_out)
.setPositiveButton(R.string.title_yes, (dialog, which) -> {
if (appPref.removeSession()) {
startActivity(new Intent(this, LoginActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK));
}
).setNegativeButton(R.string.title_no, null)
.create().show();
});
}
).setNegativeButton(R.string.title_no, null)
.create().show());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import butterknife.ButterKnife;
import io.reactivex.disposables.CompositeDisposable;
import retrofit2.HttpException;
import timber.log.Timber;

import static android.view.inputmethod.InputMethodManager.HIDE_NOT_ALWAYS;

Expand Down Expand Up @@ -227,7 +228,7 @@ private void getFitBitAppData() {
.doAfterTerminate(this::openMainActivity)
.subscribe(
fitBitAppData -> appPref.addFitbitAppData(fitBitAppData),
err -> alertMessage.handleError(err)
Timber::e
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
Expand Down Expand Up @@ -71,6 +72,7 @@ public class MainActivity extends AppCompatActivity implements
private int lastViewIndex;
private AlertMessage mAlertMessage;
private UserAccess mUserAccess;
private long backPressed;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -98,6 +100,18 @@ protected void onStart() {
EventBus.getDefault().register(this);
}

@Override
public void onBackPressed() {
if (backPressed + 2000 > System.currentTimeMillis()) {
super.onBackPressed();
this.finishAffinity();
} else {
Toast.makeText(getBaseContext(),
getString(R.string.alert_back_confirm), Toast.LENGTH_SHORT).show();
}
backPressed = System.currentTimeMillis();
}

@Override
protected void onResume() {
super.onResume();
Expand Down Expand Up @@ -270,7 +284,8 @@ private void redirectToLogin() {
}

/**
* Open children manager activity.
* Open children manager activity.
* @param isFirst boolean
*/
private void openChildrenManagerActivity(boolean isFirst) {
Intent it = new Intent(this, ChildrenManagerActivity.class);
Expand Down
Loading

0 comments on commit c49a68f

Please sign in to comment.