diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d6dd3fee..fa60cefe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,10 +43,6 @@ - - diff --git a/app/src/main/java/at/shockbytes/corey/dagger/BodyModule.kt b/app/src/main/java/at/shockbytes/corey/dagger/BodyModule.kt index 1bdb09c5..b0a86d0b 100644 --- a/app/src/main/java/at/shockbytes/corey/dagger/BodyModule.kt +++ b/app/src/main/java/at/shockbytes/corey/dagger/BodyModule.kt @@ -10,7 +10,7 @@ import at.shockbytes.corey.data.body.bmr.RevisedHarrisBenedictBmrComputation import at.shockbytes.corey.data.firebase.FirebaseDatabaseAccess import at.shockbytes.corey.data.goal.FirebaseGoalsRepository import at.shockbytes.corey.data.goal.GoalsRepository -import at.shockbytes.corey.data.google.CoreyGoogleApiClient +import at.shockbytes.corey.data.google.CoreyGoogleApi import at.shockbytes.corey.ui.fragment.body.weight.filter.RawWeightLineFilter import at.shockbytes.corey.ui.fragment.body.weight.filter.RunningAverageWeightLineFilter import at.shockbytes.corey.ui.fragment.body.weight.filter.WeightLineFilter @@ -23,8 +23,8 @@ class BodyModule(private val app: Application) { @Provides @Singleton - fun provideCoreyGoogleApiClient(): CoreyGoogleApiClient { - return CoreyGoogleApiClient(app.applicationContext) + fun provideCoreyGoogleApiClient(): CoreyGoogleApi { + return CoreyGoogleApi(app.applicationContext) } @Provides @@ -35,12 +35,12 @@ class BodyModule(private val app: Application) { @Provides @Singleton fun provideBodyRepository( - coreyGoogleApiClient: CoreyGoogleApiClient, + coreyGoogleApi: CoreyGoogleApi, preferences: SharedPreferences, firebase: FirebaseDatabaseAccess, userSettings: UserSettings ): BodyRepository { - return GoogleFitBodyRepository(coreyGoogleApiClient, preferences, firebase, userSettings) + return GoogleFitBodyRepository(coreyGoogleApi, preferences, firebase, userSettings) } @Provides diff --git a/app/src/main/java/at/shockbytes/corey/dagger/WorkoutModule.kt b/app/src/main/java/at/shockbytes/corey/dagger/WorkoutModule.kt index b49e7910..9a6da0f0 100644 --- a/app/src/main/java/at/shockbytes/corey/dagger/WorkoutModule.kt +++ b/app/src/main/java/at/shockbytes/corey/dagger/WorkoutModule.kt @@ -6,7 +6,7 @@ import at.shockbytes.corey.common.core.location.LocationRepository import at.shockbytes.corey.common.core.running.DefaultRunningManager import at.shockbytes.corey.common.core.running.RunningManager import at.shockbytes.corey.data.firebase.FirebaseDatabaseAccess -import at.shockbytes.corey.data.google.CoreyGoogleApiClient +import at.shockbytes.corey.data.google.CoreyGoogleApi import at.shockbytes.corey.data.workout.FirebaseWorkoutRepository import at.shockbytes.corey.data.workout.WorkoutRepository import at.shockbytes.corey.data.workout.external.DummyExternalWorkoutRepository @@ -53,7 +53,7 @@ class WorkoutModule(private val app: Application) { @Provides fun provideExternalWorkoutRepository( - coreyGoogleApiClient: CoreyGoogleApiClient + coreyGoogleApi: CoreyGoogleApi ): ExternalWorkoutRepository { return DummyExternalWorkoutRepository() } diff --git a/app/src/main/java/at/shockbytes/corey/data/body/GoogleFitBodyRepository.kt b/app/src/main/java/at/shockbytes/corey/data/body/GoogleFitBodyRepository.kt index b426f76d..4fd514ee 100644 --- a/app/src/main/java/at/shockbytes/corey/data/body/GoogleFitBodyRepository.kt +++ b/app/src/main/java/at/shockbytes/corey/data/body/GoogleFitBodyRepository.kt @@ -7,8 +7,10 @@ import at.shockbytes.corey.common.core.Gender import at.shockbytes.corey.common.core.util.UserSettings import at.shockbytes.corey.common.core.CoreyDate import at.shockbytes.corey.data.body.model.User +import at.shockbytes.corey.data.body.model.WeightDataPoint import at.shockbytes.corey.data.firebase.FirebaseDatabaseAccess -import at.shockbytes.corey.data.google.CoreyGoogleApiClient +import at.shockbytes.corey.data.google.CoreyGoogleApi +import at.shockbytes.corey.data.google.GoogleFitUserData import at.shockbytes.corey.util.fromFirebase import at.shockbytes.corey.util.updateValue import io.reactivex.Observable @@ -21,7 +23,7 @@ import timber.log.Timber * Date: 04.08.2016 */ class GoogleFitBodyRepository( - private val coreyGoogleApiClient: CoreyGoogleApiClient, + private val coreyGoogleApi: CoreyGoogleApi, private val preferences: SharedPreferences, private val firebase: FirebaseDatabaseAccess, private val userSettings: UserSettings @@ -34,9 +36,20 @@ class GoogleFitBodyRepository( private val desiredWeightSubject: BehaviorSubject = BehaviorSubject .createDefault(preferences.getInt(PREF_DREAM_WEIGHT, 0)) + // TODO Remove this once the OAuth screen is cleared + private val defaultValue = GoogleFitUserData( + height = 182, + weightHistory = listOf( + WeightDataPoint( + timeStamp = System.currentTimeMillis(), + weight = 77.1 + ) + ) + ) + init { setupFirebase() - setupApiClientCallback() + loadFitnessData() } private fun setupFirebase() { @@ -72,10 +85,8 @@ class GoogleFitBodyRepository( val activityLevel: ActivityLevel ) - private fun setupApiClientCallback() { - coreyGoogleApiClient.onConnectionEvent() - .filter { isConnected -> isConnected } - .flatMap { loadUserFromGoogleFit() } + private fun loadFitnessData() { + loadUserFromGoogleFit() .subscribe(userBodySubject::onNext, Timber::e) .addTo(compositeDisposable) } @@ -83,7 +94,7 @@ class GoogleFitBodyRepository( private fun loadUserFromGoogleFit(): Observable { return Observable .combineLatest( - coreyGoogleApiClient.loadGoogleFitUserData(), + coreyGoogleApi.loadGoogleFitUserData(defaultValue), gatherUserMetadata(), { weightHeightPair, userMetadata -> val (weightDataPoints, height) = weightHeightPair diff --git a/app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApiClient.kt b/app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApi.kt similarity index 65% rename from app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApiClient.kt rename to app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApi.kt index d1d5b6b6..3532f57d 100644 --- a/app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApiClient.kt +++ b/app/src/main/java/at/shockbytes/corey/data/google/CoreyGoogleApi.kt @@ -1,21 +1,19 @@ package at.shockbytes.corey.data.google import android.content.Context -import android.os.Bundle -import android.widget.Toast import at.shockbytes.corey.common.roundDouble import at.shockbytes.corey.data.body.model.WeightDataPoint -import com.google.android.gms.common.ConnectionResult -import com.google.android.gms.common.Scopes -import com.google.android.gms.common.api.GoogleApiClient -import com.google.android.gms.common.api.Scope +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.fitness.Fitness +import com.google.android.gms.fitness.FitnessOptions +import com.google.android.gms.fitness.HistoryClient import com.google.android.gms.fitness.data.DataSet import com.google.android.gms.fitness.data.DataType +import com.google.android.gms.fitness.data.HealthDataTypes import com.google.android.gms.fitness.request.DataReadRequest -import com.google.android.gms.fitness.result.DataReadResult +import com.google.android.gms.fitness.result.DataReadResponse import io.reactivex.Observable -import io.reactivex.subjects.BehaviorSubject import org.joda.time.DateTime import java.util.concurrent.TimeUnit @@ -23,26 +21,25 @@ import java.util.concurrent.TimeUnit * Author: Martin Macheiner * Date: 30.09.2020 */ -class CoreyGoogleApiClient( - private val context: Context -) : GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { - - private val connectionSubject = BehaviorSubject.createDefault(false) - fun onConnectionEvent(): Observable = connectionSubject - - private val apiClient: GoogleApiClient = GoogleApiClient.Builder(context) - .addApi(Fitness.HISTORY_API) - .addApi(Fitness.RECORDING_API) - .addScope(Scope(Scopes.FITNESS_BODY_READ_WRITE)) - .addScope(Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) - .addConnectionCallbacks(this) - .build() - - init { - apiClient.connect() +class CoreyGoogleApi(private val context: Context) { + + private val signInAccount: GoogleSignInAccount by lazy { + GoogleSignIn.getAccountForExtension( + context, + FitnessOptions.builder() + .addDataType(DataType.TYPE_CALORIES_EXPENDED) + .addDataType(DataType.TYPE_WEIGHT) + .addDataType(DataType.TYPE_HEIGHT) + .addDataType(HealthDataTypes.TYPE_BLOOD_PRESSURE) + .build() + ) } - private data class A( + private val fitnessHistoryClient: HistoryClient by lazy { + Fitness.getHistoryClient(context, signInAccount) + } + + private data class IntermediateCalories( val timestamp: Long, val calories: Float ) @@ -55,7 +52,7 @@ class CoreyGoogleApiClient( .map { dp -> val timeStamp = dp.getStartTime(TimeUnit.MILLISECONDS) val calories = dp.getValue(dp.dataType.fields[0]).asFloat() - A(timeStamp, calories) + IntermediateCalories(timeStamp, calories) } .groupBy { a -> DateTime(a.timestamp).withTimeAtStartOfDay() @@ -85,26 +82,31 @@ class CoreyGoogleApiClient( .build() } - fun loadGoogleFitUserData(): Observable { + fun loadGoogleFitUserData( + defaultValue: GoogleFitUserData = GoogleFitUserData(listOf(), 0) + ): Observable { return fitnessHistoryToObservable(buildGoogleFitRequest()) { result -> val weightHistory = retrieveWeightHistory(result.getDataSet(DataType.TYPE_WEIGHT)) val height = retrieveHeight(result.getDataSet(DataType.TYPE_HEIGHT)) GoogleFitUserData(weightHistory, height) - } + }.onErrorReturnItem(defaultValue) } private fun fitnessHistoryToObservable( readRequest: DataReadRequest, - mapper: (DataReadResult) -> T + mapper: (DataReadResponse) -> T ): Observable { return Observable.create { emitter -> - Fitness.HistoryApi.readData(apiClient, readRequest) - .setResultCallback { result -> - val transformed = mapper(result) + fitnessHistoryClient.readData(readRequest) + .addOnSuccessListener { response -> + val transformed = mapper(response) emitter.onNext(transformed) } + .addOnFailureListener { exception -> + emitter.tryOnError(exception) + } } } @@ -143,19 +145,4 @@ class CoreyGoogleApiClient( .toInt() } else 0 } - - override fun onConnected(bundle: Bundle?) { - connectionSubject.onNext(true) - } - - override fun onConnectionSuspended(i: Int) { - Toast.makeText(context, "Connection suspended: $i", Toast.LENGTH_LONG).show() - } - - override fun onConnectionFailed(connectionResult: ConnectionResult) { - connectionSubject.onNext(false) - Toast.makeText(context, - "Exception while connecting to Google Play Services: ${connectionResult.errorMessage}", - Toast.LENGTH_LONG).show() - } } \ No newline at end of file diff --git a/app/src/main/java/at/shockbytes/corey/data/workout/external/GoogleFitExternalWorkoutRepository.kt b/app/src/main/java/at/shockbytes/corey/data/workout/external/GoogleFitExternalWorkoutRepository.kt index 83fee2fd..1f50b0ac 100644 --- a/app/src/main/java/at/shockbytes/corey/data/workout/external/GoogleFitExternalWorkoutRepository.kt +++ b/app/src/main/java/at/shockbytes/corey/data/workout/external/GoogleFitExternalWorkoutRepository.kt @@ -1,18 +1,16 @@ package at.shockbytes.corey.data.workout.external -import at.shockbytes.corey.data.google.CoreyGoogleApiClient +import at.shockbytes.corey.data.google.CoreyGoogleApi import at.shockbytes.corey.util.WorkInProgress import io.reactivex.Observable @WorkInProgress class GoogleFitExternalWorkoutRepository( - private val coreyGoogleApiClient: CoreyGoogleApiClient + private val coreyGoogleApi: CoreyGoogleApi ) : ExternalWorkoutRepository { override fun loadExternalWorkouts(): Observable> { - return coreyGoogleApiClient.onConnectionEvent() - .filter { isConnected -> isConnected } - .flatMap { coreyGoogleApiClient.loadGoogleFitWorkouts() } + return coreyGoogleApi.loadGoogleFitWorkouts() .map { googleFitWorkouts -> listOf() } diff --git a/app/src/main/res/values/google_maps_api.xml b/app/src/main/res/values/google_maps_api.xml deleted file mode 100644 index 97c82142..00000000 --- a/app/src/main/res/values/google_maps_api.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - AIzaSyBwxJ3--7j7a9qwgyUb9c6Lxy9uvpv02WI - - \ No newline at end of file