diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index d166689..4837bb4 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/build.gradle b/app/build.gradle index 3102f28..7172d9e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ android { applicationId "com.tommasoberlose.anotherwidget" minSdkVersion 23 targetSdkVersion 29 - versionCode 85 + versionCode 86 versionName "2.0.8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/release/app-release.aab b/app/release/app-release.aab index 81cd6fe..5e31aba 100644 Binary files a/app/release/app-release.aab and b/app/release/app-release.aab differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 459555f..d44558b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -86,44 +86,16 @@ android:enabled="true" android:exported="true"> - + - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/DailyStepsHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/DailyStepsHelper.kt deleted file mode 100644 index 5cbc05c..0000000 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/DailyStepsHelper.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.tommasoberlose.anotherwidget.helpers - -import android.Manifest -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import android.os.Build -import com.google.android.gms.location.ActivityRecognition -import com.google.android.gms.location.ActivityTransition -import com.google.android.gms.location.ActivityTransitionRequest -import com.google.android.gms.location.DetectedActivity -import com.tommasoberlose.anotherwidget.global.Preferences -import com.tommasoberlose.anotherwidget.receivers.FenceReceiver -import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission - - -object DailyStepsHelper { - fun registerFence(context: Context) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION)) { - val transitions = mutableListOf() - - transitions += - ActivityTransition.Builder() - .setActivityType(DetectedActivity.WALKING) - .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) - .build() - - transitions += - ActivityTransition.Builder() - .setActivityType(DetectedActivity.WALKING) - .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) - .build() - - transitions += - ActivityTransition.Builder() - .setActivityType(DetectedActivity.RUNNING) - .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) - .build() - - transitions += - ActivityTransition.Builder() - .setActivityType(DetectedActivity.RUNNING) - .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) - .build() - - transitions += - ActivityTransition.Builder() - .setActivityType(DetectedActivity.STILL) - .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) - .build() - - val request = ActivityTransitionRequest(transitions) - - // myPendingIntent is the instance of PendingIntent where the app receives callbacks. - val task = ActivityRecognition.getClient(context) - .requestActivityTransitionUpdates( - request, - PendingIntent.getBroadcast( - context, - 2, - Intent(context, FenceReceiver::class.java), - 0 - ) - ) - - task.addOnFailureListener { e: Exception -> - e.printStackTrace() - Preferences.showDailySteps = false - } - - } - } - - fun unregisterFence(context: Context) { - val task = ActivityRecognition.getClient(context) - .removeActivityTransitionUpdates( - PendingIntent.getBroadcast( - context, - 2, - Intent(context, FenceReceiver::class.java), - 0 - ) - ) - - task.addOnCompleteListener { - if (it.isSuccessful) { - PendingIntent.getBroadcast( - context, - 2, - Intent(context, FenceReceiver::class.java), - 0 - ).cancel() - - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/ActivityDetectionReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/ActivityDetectionReceiver.kt new file mode 100644 index 0000000..ea5e764 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/ActivityDetectionReceiver.kt @@ -0,0 +1,171 @@ +package com.tommasoberlose.anotherwidget.receivers + +import android.Manifest +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +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.data.DataType +import com.google.android.gms.fitness.data.Field.FIELD_STEPS +import com.google.android.gms.fitness.request.DataReadRequest +import com.google.android.gms.location.* +import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget +import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission +import java.util.* +import java.util.concurrent.TimeUnit + + +class ActivityDetectionReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + if (ActivityTransitionResult.hasResult(intent)) { + val result = ActivityTransitionResult.extractResult(intent)!! + val lastEvent = result.transitionEvents.last() + + if (lastEvent.activityType == DetectedActivity.WALKING || lastEvent.activityType == DetectedActivity.RUNNING && lastEvent.transitionType == ActivityTransition.ACTIVITY_TRANSITION_EXIT) { + requestDailySteps(context) + setTimeout(context) + } else { + resetDailySteps() + } + } else { + if (intent.action == Intent.ACTION_BOOT_COMPLETED || intent.action == Intent.ACTION_MY_PACKAGE_REPLACED && Preferences.showDailySteps && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION)) { + registerFence(context) + } else { + resetDailySteps() + } + } + } + + private fun resetDailySteps() { + Preferences.googleFitSteps = -1 + } + + companion object { + val FITNESS_OPTIONS: FitnessOptions = FitnessOptions.builder() + .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) + .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) + .build() + + fun registerFence(context: Context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission( + Manifest.permission.ACTIVITY_RECOGNITION)) { + val transitions = mutableListOf() + + transitions += + ActivityTransition.Builder() + .setActivityType(DetectedActivity.WALKING) + .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) + .build() + + transitions += + ActivityTransition.Builder() + .setActivityType(DetectedActivity.RUNNING) + .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) + .build() + + val request = ActivityTransitionRequest(transitions) + + // myPendingIntent is the instance of PendingIntent where the app receives callbacks. + val task = ActivityRecognition.getClient(context) + .requestActivityTransitionUpdates( + request, + PendingIntent.getBroadcast( + context, + 2, + Intent(context, ActivityDetectionReceiver::class.java), + 0 + ) + ) + + task.addOnFailureListener { e: Exception -> + e.printStackTrace() + Preferences.showDailySteps = false + } + + } + } + + fun unregisterFence(context: Context) { + val task = ActivityRecognition.getClient(context) + .removeActivityTransitionUpdates( + PendingIntent.getBroadcast( + context, + 2, + Intent(context, ActivityDetectionReceiver::class.java), + 0 + ) + ) + + task.addOnCompleteListener { + if (it.isSuccessful) { + PendingIntent.getBroadcast( + context, + 2, + Intent(context, ActivityDetectionReceiver::class.java), + 0 + ).cancel() + } + } + } + + fun requestDailySteps(context: Context) { + + val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) + if (account != null && GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) { + + val cal: Calendar = Calendar.getInstance() + cal.set(Calendar.HOUR_OF_DAY, 0) + cal.set(Calendar.MINUTE, 0) + cal.set(Calendar.SECOND, 0) + cal.set(Calendar.MILLISECOND, 0) + val startTime: Long = cal.timeInMillis + + cal.add(Calendar.DAY_OF_YEAR, 1) + val endTime: Long = cal.timeInMillis + + val readRequest = DataReadRequest.Builder() + .aggregate( + DataType.TYPE_STEP_COUNT_DELTA, + DataType.AGGREGATE_STEP_COUNT_DELTA + ) + .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS) + .bucketByTime(1, TimeUnit.DAYS) + .build() + + Fitness.getHistoryClient(context, account) + .readData(readRequest) + .addOnSuccessListener { response -> + Preferences.googleFitSteps = response.buckets.sumBy { + it.getDataSet(DataType.AGGREGATE_STEP_COUNT_DELTA)?.dataPoints?.get(0)?.getValue(FIELD_STEPS)?.asInt() ?: 0 + }.toLong() + MainWidget.updateWidget(context) + } + } + } + + fun setTimeout(context: Context) { + with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) { + cancel(PendingIntent.getBroadcast(context, 0, Intent(context, ActivityDetectionReceiver::class.java), 0)) + setExactAndAllowWhileIdle( + AlarmManager.RTC, + Calendar.getInstance().timeInMillis + 15 * 60 * 1000, + PendingIntent.getBroadcast( + context, + 0, + Intent(context, ActivityDetectionReceiver::class.java), + 0 + ) + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/FenceReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/FenceReceiver.kt deleted file mode 100644 index 53e6dee..0000000 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/FenceReceiver.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.tommasoberlose.anotherwidget.receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log -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.data.DataSource -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.request.DataReadRequest -import com.google.android.gms.location.ActivityTransitionResult -import com.google.android.gms.location.DetectedActivity -import com.tommasoberlose.anotherwidget.global.Preferences -import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget -import java.util.* -import java.util.concurrent.TimeUnit - - -class FenceReceiver : BroadcastReceiver() { - - override fun onReceive(context: Context, intent: Intent) { - if (ActivityTransitionResult.hasResult(intent)) { - val result = ActivityTransitionResult.extractResult(intent)!! - val lastEvent = result.transitionEvents.last() - - if (lastEvent.activityType == DetectedActivity.WALKING || lastEvent.activityType == DetectedActivity.RUNNING) { - requestDailySteps(context) - } else { - resetDailySteps() - } - } - } - - private fun resetDailySteps() { - Preferences.googleFitSteps = -1 - } - - companion object { - val FITNESS_OPTIONS = FitnessOptions.builder() - .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) - .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) - .build() - - fun requestDailySteps(context: Context) { - - val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) - if (account != null && GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) { - - val cal: Calendar = Calendar.getInstance() - cal.set(Calendar.HOUR_OF_DAY, 0) - cal.set(Calendar.MINUTE, 0) - cal.set(Calendar.SECOND, 0) - cal.set(Calendar.MILLISECOND, 0) - val startTime: Long = cal.timeInMillis - - cal.add(Calendar.DAY_OF_YEAR, 1) - val endTime: Long = cal.timeInMillis - - val readRequest = DataReadRequest.Builder() - .aggregate( - DataType.TYPE_STEP_COUNT_DELTA, - DataType.AGGREGATE_STEP_COUNT_DELTA - ) - .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS) - .bucketByTime(1, TimeUnit.DAYS) - .build() - - Fitness.getHistoryClient(context, account) - .readData(readRequest) - .addOnSuccessListener { response -> - Preferences.googleFitSteps = response.buckets.sumBy { - it.getDataSet(DataType.AGGREGATE_STEP_COUNT_DELTA)?.dataPoints?.get(0)?.getValue(FIELD_STEPS)?.asInt() ?: 0 - }.toLong() - MainWidget.updateWidget(context) - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/PlayerReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/PlayerReceiver.kt deleted file mode 100644 index 2d74792..0000000 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/PlayerReceiver.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tommasoberlose.anotherwidget.receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log - - -class PlayerReceiver : BroadcastReceiver() { - - override fun onReceive(context: Context, intent: Intent) { - Log.d("ciao", "player ok") - -// val cmd = intent.getStringExtra("command") -// Log.v("tag ", "$action / $cmd") -// val artist = intent.getStringExtra("artist") -// val album = intent.getStringExtra("album") -// val track = intent.getStringExtra("track") -// Log.v("tag", "$artist:$album:$track") - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GeneralTabFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GeneralTabFragment.kt index 6c6141f..6f0441c 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GeneralTabFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GeneralTabFragment.kt @@ -176,7 +176,7 @@ class GeneralTabFragment : Fragment() { private fun setupListener() { action_main_text_size.setOnClickListener { val dialog = BottomSheetMenu(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue(Preferences.textMainSize) - (32 downTo 10).filter { it % 2 == 0 }.forEach { + (40 downTo 10).filter { it % 2 == 0 }.forEach { dialog.addItem("${it}sp", it.toFloat()) } dialog.addOnSelectItemListener { value -> @@ -186,7 +186,7 @@ class GeneralTabFragment : Fragment() { action_second_text_size.setOnClickListener { val dialog = BottomSheetMenu(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(Preferences.textSecondSize) - (28 downTo 10).filter { it % 2 == 0 }.forEach { + (40 downTo 10).filter { it % 2 == 0 }.forEach { dialog.addItem("${it}sp", it.toFloat()) } dialog.addOnSelectItemListener { value -> diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt index a487ad5..f84ec42 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt @@ -25,9 +25,6 @@ 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.GoogleSignInOptions import com.google.android.gms.common.api.ApiException -import com.google.android.gms.fitness.FitnessOptions -import com.google.android.gms.fitness.data.DataType -import com.google.android.gms.tasks.Task import com.karumi.dexter.Dexter import com.karumi.dexter.MultiplePermissionsReport import com.karumi.dexter.PermissionToken @@ -40,10 +37,9 @@ import com.tommasoberlose.anotherwidget.components.GlanceProviderSortMenu import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.AlarmHelper -import com.tommasoberlose.anotherwidget.helpers.DailyStepsHelper 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.receivers.ActivityDetectionReceiver +import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission @@ -198,8 +194,13 @@ class GlanceTabFragment : Fragment() { .addItem(getString(R.string.settings_not_visible), false) .addOnSelectItemListener { value -> if (value) { - val mGoogleSignInClient = GoogleSignIn.getClient(requireActivity(), GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(FITNESS_OPTIONS).build()) - startActivityForResult(mGoogleSignInClient.signInIntent, 2) + val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(requireContext()) + if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) { + val mGoogleSignInClient = GoogleSignIn.getClient(requireActivity(), GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(FITNESS_OPTIONS).build()) + startActivityForResult(mGoogleSignInClient.signInIntent, 2) + } else { + Preferences.showDailySteps = true + } } else { Preferences.showDailySteps = false } @@ -270,20 +271,20 @@ class GlanceTabFragment : Fragment() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) { fitness_permission_alert?.isVisible = false if (Preferences.showDailySteps) { - DailyStepsHelper.registerFence(requireContext()) + ActivityDetectionReceiver.registerFence(requireContext()) } else { - DailyStepsHelper.unregisterFence(requireContext()) + ActivityDetectionReceiver.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()) + ActivityDetectionReceiver.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()) + ActivityDetectionReceiver.unregisterFence(requireContext()) show_steps_label?.text = getString(R.string.settings_not_visible) fitness_permission_alert?.isVisible = false } @@ -297,7 +298,7 @@ class GlanceTabFragment : Fragment() { when (requestCode) { 1 -> { if (resultCode == Activity.RESULT_OK) { - DailyStepsHelper.registerFence(requireContext()) + checkFitnessPermission() } else { Preferences.showDailySteps = false } @@ -312,7 +313,7 @@ class GlanceTabFragment : Fragment() { account, FITNESS_OPTIONS) } else { - DailyStepsHelper.registerFence(requireContext()) + checkFitnessPermission() } } catch (e: ApiException) { e.printStackTrace()