Add google fit connection

This commit is contained in:
Tommaso Berlose 2020-05-10 20:29:35 +02:00
parent 1754b4045b
commit 842c0d764f
4 changed files with 153 additions and 123 deletions

View File

@ -15,23 +15,38 @@
}, },
"oauth_client": [ "oauth_client": [
{ {
"client_id": "791844924473-73dh46rorjq8vm97dgbn6can2dcpqlf0.apps.googleusercontent.com", "client_id": "791844924473-2lt64gf4jif7jb6s14igfql3ntosqj2s.apps.googleusercontent.com",
"client_type": 3 "client_type": 1,
"android_info": {
"package_name": "com.tommasoberlose.anotherwidget",
"certificate_hash": "8c2a10e4c0663437206d2356d8e0e4047da70fb2"
}
},
{
"client_id": "791844924473-7sq4es017gl6pldrpv0efv5avprgdfv2.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.tommasoberlose.anotherwidget",
"certificate_hash": "4a2735eca05bc73974f1bf80304bbee32b276196"
}
},
{
"client_id": "791844924473-tsfd6idva64t5adh2atcfflpr0k52hlg.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.tommasoberlose.anotherwidget",
"certificate_hash": "82a38974264dca740d0612c9f9d15f15574cf160"
}
} }
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyAeJRXstqnzebibxmm3FRM98nbwE_kC8tA" "current_key": "AIzaSyCT_v2Qw1zCWfmc_ywsovj_4poSXr7k5f0"
} }
], ],
"services": { "services": {
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [ "other_platform_oauth_client": []
{
"client_id": "791844924473-73dh46rorjq8vm97dgbn6can2dcpqlf0.apps.googleusercontent.com",
"client_type": 3
}
]
} }
} }
} }

View File

@ -10,6 +10,7 @@ import com.google.android.gms.fitness.Fitness
import com.google.android.gms.fitness.FitnessOptions import com.google.android.gms.fitness.FitnessOptions
import com.google.android.gms.fitness.data.DataSource import com.google.android.gms.fitness.data.DataSource
import com.google.android.gms.fitness.data.DataType import com.google.android.gms.fitness.data.DataType
import com.google.android.gms.fitness.data.Field
import com.google.android.gms.fitness.data.Field.FIELD_STEPS import com.google.android.gms.fitness.data.Field.FIELD_STEPS
import com.google.android.gms.fitness.request.DataReadRequest import com.google.android.gms.fitness.request.DataReadRequest
import com.google.android.gms.location.ActivityTransitionResult import com.google.android.gms.location.ActivityTransitionResult
@ -35,49 +36,49 @@ class FenceReceiver : BroadcastReceiver() {
} }
} }
private fun requestDailySteps(context: Context) { private fun resetDailySteps() {
val fitnessOptions = FitnessOptions.builder() Preferences.googleFitSteps = -1
}
companion object {
val FITNESS_OPTIONS = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.build() .build()
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) fun requestDailySteps(context: Context) {
Log.d("ciao", "hasPermission: ${GoogleSignIn.hasPermissions(account, fitnessOptions)}") val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
if (account != null && GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) {
if (GoogleSignIn.hasPermissions(account, fitnessOptions)) { val cal: Calendar = Calendar.getInstance()
val cal: Calendar = Calendar.getInstance() cal.set(Calendar.HOUR_OF_DAY, 0)
cal.time = Date() cal.set(Calendar.MINUTE, 0)
val endTime: Long = cal.timeInMillis cal.set(Calendar.SECOND, 0)
cal.add(Calendar.YEAR, -1) cal.set(Calendar.MILLISECOND, 0)
val startTime: Long = cal.timeInMillis val startTime: Long = cal.timeInMillis
val readRequest = DataReadRequest.Builder()
.aggregate( cal.add(Calendar.DAY_OF_YEAR, 1)
DataType.TYPE_STEP_COUNT_DELTA, val endTime: Long = cal.timeInMillis
DataType.AGGREGATE_STEP_COUNT_DELTA
) val readRequest = DataReadRequest.Builder()
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS) .aggregate(
.bucketByTime(1, TimeUnit.DAYS) DataType.TYPE_STEP_COUNT_DELTA,
.build() DataType.AGGREGATE_STEP_COUNT_DELTA
)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.bucketByTime(1, TimeUnit.DAYS)
.build()
if (account != null) {
Fitness.getHistoryClient(context, account) Fitness.getHistoryClient(context, account)
.readData(readRequest) .readData(readRequest)
.addOnSuccessListener { response -> .addOnSuccessListener { response ->
Preferences.googleFitSteps = Preferences.googleFitSteps = response.buckets.sumBy {
response.dataSets[0].dataPoints[0].getValue(FIELD_STEPS).asFloat() it.getDataSet(DataType.AGGREGATE_STEP_COUNT_DELTA)?.dataPoints?.get(0)?.getValue(FIELD_STEPS)?.asInt() ?: 0
.toLong() }.toLong()
Log.d("ciao",
"response: ${response.dataSets[0].dataPoints[0].getValue(FIELD_STEPS)
.asFloat().toLong()}"
)
MainWidget.updateWidget(context) MainWidget.updateWidget(context)
} }
} }
} }
} }
private fun resetDailySteps() {
Preferences.googleFitSteps = -1
}
} }

View File

@ -10,6 +10,7 @@ import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -22,8 +23,11 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.fitness.FitnessOptions import com.google.android.gms.fitness.FitnessOptions
import com.google.android.gms.fitness.data.DataType import com.google.android.gms.fitness.data.DataType
import com.google.android.gms.tasks.Task
import com.karumi.dexter.Dexter import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken import com.karumi.dexter.PermissionToken
@ -38,6 +42,8 @@ import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
import com.tommasoberlose.anotherwidget.helpers.DailyStepsHelper import com.tommasoberlose.anotherwidget.helpers.DailyStepsHelper
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.receivers.FenceReceiver
import com.tommasoberlose.anotherwidget.receivers.FenceReceiver.Companion.FITNESS_OPTIONS
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
@ -110,12 +116,12 @@ class GlanceTabFragment : Fragment() {
} }
}) })
// viewModel.showDailySteps.observe(viewLifecycleOwner, Observer { viewModel.showDailySteps.observe(viewLifecycleOwner, Observer {
// maintainScrollPosition { maintainScrollPosition {
// show_steps_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) show_steps_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
// } }
// checkFitnessPermission() checkFitnessPermission()
// }) })
viewModel.customInfo.observe(viewLifecycleOwner, Observer { viewModel.customInfo.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
@ -191,7 +197,12 @@ class GlanceTabFragment : Fragment() {
.addItem(getString(R.string.settings_visible), true) .addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false) .addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value -> .addOnSelectItemListener { value ->
Preferences.showDailySteps = value if (value) {
val mGoogleSignInClient = GoogleSignIn.getClient(requireActivity(), GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(FITNESS_OPTIONS).build())
startActivityForResult(mGoogleSignInClient.signInIntent, 2)
} else {
Preferences.showDailySteps = false
}
}.show() }.show()
} }
} }
@ -255,83 +266,87 @@ class GlanceTabFragment : Fragment() {
} }
} }
// private fun checkFitnessPermission() { private fun checkFitnessPermission() {
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) {
// fitness_permission_alert?.isVisible = false fitness_permission_alert?.isVisible = false
// if (Preferences.showDailySteps) { if (Preferences.showDailySteps) {
// val fitnessOptions = FitnessOptions.builder() DailyStepsHelper.registerFence(requireContext())
// .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) } else {
// .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) DailyStepsHelper.unregisterFence(requireContext())
// .build() }
// show_steps_label?.text = if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
// val account: GoogleSignInAccount = GoogleSignIn.getLastSignedInAccount(requireContext()) ?: GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions) } else if (Preferences.showDailySteps) {
// DailyStepsHelper.unregisterFence(requireContext())
// if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) { fitness_permission_alert?.isVisible = true
// GoogleSignIn.requestPermissions( show_steps_label?.text = getString(R.string.settings_request_fitness_access)
// requireActivity(), fitness_permission_alert?.setOnClickListener {
// 1, requireFitnessPermission()
// account, }
// fitnessOptions) } else {
// } else { DailyStepsHelper.unregisterFence(requireContext())
// DailyStepsHelper.registerFence(requireContext()) show_steps_label?.text = getString(R.string.settings_not_visible)
// } fitness_permission_alert?.isVisible = false
// } else { }
// DailyStepsHelper.unregisterFence(requireContext()) }
// }
// show_steps_label?.text = if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
// } else if (Preferences.showDailySteps) {
// DailyStepsHelper.unregisterFence(requireContext())
// fitness_permission_alert?.isVisible = true
// show_steps_label?.text = getString(R.string.settings_request_fitness_access)
// fitness_permission_alert?.setOnClickListener {
// requireFitnessPermission()
// }
// } else {
// DailyStepsHelper.unregisterFence(requireContext())
// show_steps_label?.text = getString(R.string.settings_not_visible)
// fitness_permission_alert?.isVisible = false
// }
// }
//
// override fun onActivityResult(
// requestCode: Int,
// resultCode: Int,
// data: Intent?
// ) {
// if (resultCode == Activity.RESULT_OK) {
// if (requestCode == 1) {
// DailyStepsHelper.registerFence(requireContext())
// } else {
// Preferences.showDailySteps = false
// }
// }
// }
// private fun requireFitnessPermission() { override fun onActivityResult(
// Dexter.withContext(requireContext()) requestCode: Int,
// .withPermissions( resultCode: Int,
// "com.google.android.gms.permission.ACTIVITY_RECOGNITION", data: Intent?
// "android.gms.permission.ACTIVITY_RECOGNITION", ) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION" when (requestCode) {
// ).withListener(object: MultiplePermissionsListener { 1 -> {
// override fun onPermissionsChecked(report: MultiplePermissionsReport?) { if (resultCode == Activity.RESULT_OK) {
// report?.let { DailyStepsHelper.registerFence(requireContext())
// if (report.areAllPermissionsGranted()){ } else {
// checkFitnessPermission() Preferences.showDailySteps = false
// } }
// } }
// } 2-> {
// override fun onPermissionRationaleShouldBeShown( try {
// permissions: MutableList<PermissionRequest>?, val account: GoogleSignInAccount? = GoogleSignIn.getSignedInAccountFromIntent(data).getResult(ApiException::class.java)
// token: PermissionToken? if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) {
// ) { GoogleSignIn.requestPermissions(
// // Remember to invoke this method when the custom rationale is closed requireActivity(),
// // or just by default if you don't want to use any custom rationale. 1,
// token?.continuePermissionRequest() account,
// } FITNESS_OPTIONS)
// }) } else {
// .check() DailyStepsHelper.registerFence(requireContext())
// } }
} catch (e: ApiException) {
e.printStackTrace()
Preferences.showDailySteps = false
}
}
}
}
private fun requireFitnessPermission() {
Dexter.withContext(requireContext())
.withPermissions(
"com.google.android.gms.permission.ACTIVITY_RECOGNITION",
"android.gms.permission.ACTIVITY_RECOGNITION",
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION"
).withListener(object: MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
report?.let {
if (report.areAllPermissionsGranted()){
checkFitnessPermission()
}
}
}
override fun onPermissionRationaleShouldBeShown(
permissions: MutableList<PermissionRequest>?,
token: PermissionToken?
) {
// Remember to invoke this method when the custom rationale is closed
// or just by default if you don't want to use any custom rationale.
token?.continuePermissionRequest()
}
})
.check()
}
private fun maintainScrollPosition(callback: () -> Unit) { private fun maintainScrollPosition(callback: () -> Unit) {
val scrollPosition = scrollView.scrollY val scrollPosition = scrollView.scrollY

View File

@ -194,7 +194,6 @@
android:paddingRight="8dp" android:paddingRight="8dp"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" android:gravity="center_vertical"
android:id="@+id/action_show_steps" android:id="@+id/action_show_steps"