Add google fit integration

This commit is contained in:
Tommaso Berlose 2020-05-10 14:08:40 +02:00
parent 9a63b9bde2
commit 1754b4045b
28 changed files with 713 additions and 335 deletions

Binary file not shown.

2
.idea/gradle.xml generated
View File

@ -11,8 +11,6 @@
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/googlefit" />
<option value="$PROJECT_DIR$/tasksintegration" />
</set> </set>
</option> </option>
<option name="resolveModulePerSourceSet" value="false" /> <option name="resolveModulePerSourceSet" value="false" />

2
.idea/modules.xml generated
View File

@ -4,8 +4,6 @@
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" /> <module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" /> <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" />
<module fileurl="file://$PROJECT_DIR$/googlefit/googlefit.iml" filepath="$PROJECT_DIR$/googlefit/googlefit.iml" group="Another Widget/googlefit" />
<module fileurl="file://$PROJECT_DIR$/tasksintegration/tasksintegration.iml" filepath="$PROJECT_DIR$/tasksintegration/tasksintegration.iml" group="Another Widget/tasksintegration" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -10,6 +10,10 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android' apply plugin: 'realm-android'
def apiKeyPropertiesFile = rootProject.file("apikey.properties")
def apiKeyProperties = new Properties()
apiKeyProperties.load(new FileInputStream(apiKeyPropertiesFile))
android { android {
compileSdkVersion 29 compileSdkVersion 29
buildToolsVersion "29.0.3" buildToolsVersion "29.0.3"
@ -18,10 +22,12 @@ android {
applicationId "com.tommasoberlose.anotherwidget" applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 29
versionCode 83 versionCode 84
versionName "2.0.6" versionName "2.0.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [ "AWARENESS_API_KEY": apiKeyProperties['AWARENESS_API_KEY']]
} }
buildTypes { buildTypes {
@ -52,10 +58,6 @@ android {
} }
viewBinding.enabled = true viewBinding.enabled = true
dynamicFeatures = [":tasksintegration", ":googlefit"]
} }
dependencies { dependencies {
@ -98,6 +100,10 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0' kapt 'com.github.bumptech.glide:compiler:4.11.0'
// Fitness
implementation 'com.google.android.gms:play-services-fitness:18.0.0'
implementation 'com.google.android.gms:play-services-auth:18.0.0'
//Weather //Weather
implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2' implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2'
implementation 'com.google.android.gms:play-services-location:17.0.0' implementation 'com.google.android.gms:play-services-location:17.0.0'

Binary file not shown.

View File

@ -10,6 +10,10 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -157,6 +161,18 @@
<action android:name="android.intent.action.BATTERY_OKAY"/> <action android:name="android.intent.action.BATTERY_OKAY"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.FenceReceiver"
android:exported="false"
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
<intent-filter>
<action android:name="com.mypackage.ACTION_PROCESS_ACTIVITY_TRANSITIONS" />
</intent-filter>
</receiver>
<meta-data
android:name="com.google.android.awareness.API_KEY"
android:value="${AWARENESS_API_KEY}"/>
</application> </application>
</manifest> </manifest>

View File

@ -1,6 +1,7 @@
package com.tommasoberlose.anotherwidget package com.tommasoberlose.anotherwidget
import android.app.Application import android.app.Application
import android.util.Log
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import com.chibatching.kotpref.Kotpref import com.chibatching.kotpref.Kotpref
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics

View File

@ -18,8 +18,8 @@ object Constants {
enum class GlanceProviderId(val id: String) { enum class GlanceProviderId(val id: String) {
PLAYING_SONG("PLAYING_SONG"), PLAYING_SONG("PLAYING_SONG"),
NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"), NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"),
// BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"), BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"),
CUSTOM_INFO("CUSTOM_INFO"), CUSTOM_INFO("CUSTOM_INFO"),
// GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS") GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS")
} }
} }

View File

@ -83,6 +83,7 @@ object Preferences : KotprefModel() {
var showBatteryCharging by booleanPref(default = false) var showBatteryCharging by booleanPref(default = false)
var isBatteryLevelLow by booleanPref(default = false) var isBatteryLevelLow by booleanPref(default = false)
var googleFitSteps by longPref(default = -1) var googleFitSteps by longPref(default = -1)
var showDailySteps by booleanPref(default = false)
var showMusic by booleanPref(default = false) var showMusic by booleanPref(default = false)
var mediaInfoFormat by stringPref(default = "") var mediaInfoFormat by stringPref(default = "")

View File

@ -0,0 +1,97 @@
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<ActivityTransition>()
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()
}
}
}
}

View File

@ -53,18 +53,18 @@ object GlanceProviderHelper {
R.drawable.round_notes R.drawable.round_notes
) )
} }
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
// GlanceProvider(providerId.id, GlanceProvider(providerId.id,
// context.getString(R.string.settings_low_battery_level_title), context.getString(R.string.settings_low_battery_level_title),
// R.drawable.round_battery_charging_full R.drawable.round_battery_charging_full
// ) )
// } }
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
// GlanceProvider(providerId.id, GlanceProvider(providerId.id,
// context.getString(R.string.settings_daily_steps_title), context.getString(R.string.settings_daily_steps_title),
// R.drawable.round_directions_walk R.drawable.round_directions_walk
// ) )
// } }
} }
} }
@ -72,13 +72,13 @@ object GlanceProviderHelper {
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",") Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
} }
fun showSpecialWeather(context: Context): Boolean { fun showGlanceProviders(context: Context): Boolean {
return EventRepository(context).getEventsCount() == 0 && ( return Preferences.showGlance && EventRepository(context).getEventsCount() == 0 && (
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") || (Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
(MediaPlayerHelper.isSomeonePlaying(context)) || (MediaPlayerHelper.isSomeonePlaying(context)) ||
(Preferences.isBatteryLevelLow) || (Preferences.isBatteryLevelLow) ||
(Preferences.customNotes.isNotEmpty()) || (Preferences.customNotes.isNotEmpty()) ||
(Preferences.googleFitSteps > 0) (Preferences.showDailySteps && Preferences.googleFitSteps > 0)
) )
} }
} }

View File

@ -0,0 +1,83 @@
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.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 requestDailySteps(context: Context) {
val fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.build()
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
Log.d("ciao", "hasPermission: ${GoogleSignIn.hasPermissions(account, fitnessOptions)}")
if (GoogleSignIn.hasPermissions(account, fitnessOptions)) {
val cal: Calendar = Calendar.getInstance()
cal.time = Date()
val endTime: Long = cal.timeInMillis
cal.add(Calendar.YEAR, -1)
val startTime: 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()
if (account != null) {
Fitness.getHistoryClient(context, account)
.readData(readRequest)
.addOnSuccessListener { response ->
Preferences.googleFitSteps =
response.dataSets[0].dataPoints[0].getValue(FIELD_STEPS).asFloat()
.toLong()
Log.d("ciao",
"response: ${response.dataSets[0].dataPoints[0].getValue(FIELD_STEPS)
.asFloat().toLong()}"
)
MainWidget.updateWidget(context)
}
}
}
}
private fun resetDailySteps() {
Preferences.googleFitSteps = -1
}
}

View File

@ -26,6 +26,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.chibatching.kotpref.Kotpref
import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.karumi.dexter.Dexter import com.karumi.dexter.Dexter

View File

@ -135,12 +135,6 @@ class CalendarTabFragment : Fragment() {
} }
}) })
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
date_format_label?.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
}
})
viewModel.calendarAppName.observe(viewLifecycleOwner, Observer { viewModel.calendarAppName.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
calendar_app_label?.text = if (it != "") it else getString(R.string.default_calendar_app) calendar_app_label?.text = if (it != "") it else getString(R.string.default_calendar_app)
@ -290,27 +284,6 @@ class CalendarTabFragment : Fragment() {
} }
} }
action_date_format.setOnClickListener {
if (Preferences.showEvents) {
val now = Calendar.getInstance()
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
dialog.addItem(DateHelper.getDefaultDateText(requireContext(), now), "")
if (Preferences.dateFormat != "") {
dialog.addItem(DateHelper.getDateText(requireContext(), now), Preferences.dateFormat)
}
dialog.addItem(getString(R.string.custom_date_format), "-")
dialog.addOnSelectItemListener { value ->
if (value == "-") {
startActivity(Intent(requireContext(), CustomDateActivity::class.java))
} else {
Preferences.dateFormat = value
}
}.show()
}
}
action_open_event_details.setOnClickListener { action_open_event_details.setOnClickListener {
if (Preferences.showEvents) { if (Preferences.showEvents) {
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_event_app_title)).setSelectedValue(Preferences.openEventDetails) BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_event_app_title)).setSelectedValue(Preferences.openEventDetails)

View File

@ -21,7 +21,9 @@ import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
import com.tommasoberlose.anotherwidget.helpers.DateHelper
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.ui.activities.CustomDateActivity
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 kotlinx.android.synthetic.main.fragment_general_settings.* import kotlinx.android.synthetic.main.fragment_general_settings.*
@ -29,6 +31,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.*
class GeneralTabFragment : Fragment() { class GeneralTabFragment : Fragment() {
@ -141,6 +144,12 @@ class GeneralTabFragment : Fragment() {
} }
}) })
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
date_format_label?.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
}
})
viewModel.customFont.observe(viewLifecycleOwner, Observer { viewModel.customFont.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it)) custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it))
@ -202,6 +211,27 @@ class GeneralTabFragment : Fragment() {
).show() ).show()
} }
action_date_format.setOnClickListener {
if (Preferences.showEvents) {
val now = Calendar.getInstance()
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
dialog.addItem(DateHelper.getDefaultDateText(requireContext(), now), "")
if (Preferences.dateFormat != "") {
dialog.addItem(DateHelper.getDateText(requireContext(), now), Preferences.dateFormat)
}
dialog.addItem(getString(R.string.custom_date_format), "-")
dialog.addOnSelectItemListener { value ->
if (value == "-") {
startActivity(Intent(requireContext(), CustomDateActivity::class.java))
} else {
Preferences.dateFormat = value
}
}.show()
}
}
action_background_color.setOnClickListener { action_background_color.setOnClickListener {
BottomSheetColorPicker(requireContext(), BottomSheetColorPicker(requireContext(),
colors = colors, colors = colors,

View File

@ -1,31 +1,34 @@
package com.tommasoberlose.anotherwidget.ui.fragments package com.tommasoberlose.anotherwidget.ui.fragments
import android.Manifest
import android.app.Activity
import android.app.AlarmManager import android.app.AlarmManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
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
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import com.google.android.gms.auth.api.signin.GoogleSignIn
import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import androidx.recyclerview.widget.RecyclerView import com.google.android.gms.fitness.FitnessOptions
import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.google.android.gms.fitness.data.DataType
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.components.CustomNotesDialog import com.tommasoberlose.anotherwidget.components.CustomNotesDialog
@ -33,16 +36,14 @@ import com.tommasoberlose.anotherwidget.components.GlanceProviderSortMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper import com.tommasoberlose.anotherwidget.helpers.DailyStepsHelper
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.models.GlanceProvider
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 kotlinx.android.synthetic.main.fragment_glance_settings.* import kotlinx.android.synthetic.main.fragment_glance_settings.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.idik.lib.slimadapter.SlimAdapter
import java.util.*
class GlanceTabFragment : Fragment() { class GlanceTabFragment : Fragment() {
@ -109,6 +110,13 @@ class GlanceTabFragment : Fragment() {
} }
}) })
// viewModel.showDailySteps.observe(viewLifecycleOwner, Observer {
// maintainScrollPosition {
// show_steps_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
// }
// checkFitnessPermission()
// })
viewModel.customInfo.observe(viewLifecycleOwner, Observer { viewModel.customInfo.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
show_custom_notes_label?.text = if (it == "") getString(R.string.settings_not_visible) else it show_custom_notes_label?.text = if (it == "") getString(R.string.settings_not_visible) else it
@ -174,6 +182,20 @@ class GlanceTabFragment : Fragment() {
} }
} }
action_show_steps.setOnClickListener {
if (Preferences.showGlance) {
BottomSheetMenu<Boolean>(
requireContext(),
header = getString(R.string.settings_daily_steps_title)
).setSelectedValue(Preferences.showDailySteps)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
Preferences.showDailySteps = value
}.show()
}
}
action_show_custom_notes.setOnClickListener { action_show_custom_notes.setOnClickListener {
if (Preferences.showGlance) { if (Preferences.showGlance) {
CustomNotesDialog(requireContext()).show() CustomNotesDialog(requireContext()).show()
@ -228,11 +250,89 @@ class GlanceTabFragment : Fragment() {
activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
} }
} else { } else {
show_music_label?.text = getString(R.string.settings_show_music_disabled_subtitle) show_music_label?.text = getString(R.string.settings_not_visible)
notification_permission_alert?.isVisible = false notification_permission_alert?.isVisible = false
} }
} }
// private fun checkFitnessPermission() {
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) {
// fitness_permission_alert?.isVisible = false
// if (Preferences.showDailySteps) {
// val fitnessOptions = FitnessOptions.builder()
// .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
// .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
// .build()
//
// val account: GoogleSignInAccount = GoogleSignIn.getLastSignedInAccount(requireContext()) ?: GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions)
//
// if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
// GoogleSignIn.requestPermissions(
// requireActivity(),
// 1,
// account,
// fitnessOptions)
// } else {
// DailyStepsHelper.registerFence(requireContext())
// }
// } 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() {
// 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
callback.invoke() callback.invoke()

View File

@ -124,143 +124,156 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
private fun updateUI() { private fun updateUI() {
uiJob?.cancel() uiJob?.cancel()
if (preview != null) {
preview.clearAnimation()
time_container.clearAnimation()
if (Preferences.showPreview) { if (Preferences.showPreview) {
preview.setCardBackgroundColor( preview.setCardBackgroundColor(
ContextCompat.getColor( ContextCompat.getColor(
requireContext(), requireContext(),
if (ColorHelper.getFontColor() if (ColorHelper.getFontColor()
.isColorDark() .isColorDark()
) android.R.color.white else R.color.colorAccent ) android.R.color.white else R.color.colorAccent
)
)
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(requireContext(), R.drawable.card_background, ColorHelper.getBackgroundColor()))
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
val generatedView = MainWidget.generateWidgetView(requireContext())
withContext(Dispatchers.Main) {
generatedView.measure(0, 0)
preview.measure(0, 0)
}
val bitmap = BitmapHelper.getBitmapFromView(
generatedView,
if (preview.width > 0) preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
withContext(Dispatchers.Main) {
// Clock
time.setTextColor(ColorHelper.getClockFontColor())
time_am_pm.setTextColor(ColorHelper.getClockFontColor())
time.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext())
) )
time_am_pm.setTextSize( )
TypedValue.COMPLEX_UNIT_SP, widget_shape_background?.setImageDrawable(
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2 BitmapHelper.getTintedDrawable(
requireContext(),
R.drawable.card_background,
ColorHelper.getBackgroundColor()
) )
time_am_pm.isVisible = Preferences.showAMPMIndicator )
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
val generatedView = MainWidget.generateWidgetView(requireContext())
// Clock bottom margin withContext(Dispatchers.Main) {
clock_bottom_margin_none.isVisible = generatedView.measure(0, 0)
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value preview.measure(0, 0)
clock_bottom_margin_small.isVisible = }
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
clock_bottom_margin_medium.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
clock_bottom_margin_large.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) { val bitmap = BitmapHelper.getBitmapFromView(
if (Preferences.showClock) { generatedView,
if (preview.width > 0) preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
withContext(Dispatchers.Main) {
// Clock
time.setTextColor(ColorHelper.getClockFontColor())
time_am_pm.setTextColor(ColorHelper.getClockFontColor())
time.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext())
)
time_am_pm.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
)
time_am_pm.isVisible = Preferences.showAMPMIndicator
// Clock bottom margin
clock_bottom_margin_none.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
clock_bottom_margin_small.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
clock_bottom_margin_medium.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
clock_bottom_margin_large.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
if (Preferences.showClock) {
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container.measure(0, 0)
}
val initialHeight = time_container.measuredHeight
ValueAnimator.ofFloat(
if (Preferences.showClock) 0f else 1f,
if (Preferences.showClock) 1f else 0f
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Float
time_container.layoutParams =
time_container.layoutParams.apply {
height = (initialHeight * animatedValue).toInt()
}
time.alpha = animatedValue
}
addListener(
onStart = {
if (Preferences.showClock) {
time_container.isVisible = true
}
},
onEnd = {
if (!Preferences.showClock) {
time_container.isVisible = false
}
}
)
}.start()
ValueAnimator.ofInt(
preview.height,
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} else {
time_container.layoutParams = time_container.layoutParams.apply { time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT height = RelativeLayout.LayoutParams.WRAP_CONTENT
} }
time_container.measure(0, 0) time_container.measure(0, 0)
} }
val initialHeight = time_container.measuredHeight
ValueAnimator.ofFloat(
if (Preferences.showClock) 0f else 1f,
if (Preferences.showClock) 1f else 0f
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Float
time_container.layoutParams = time_container.layoutParams.apply {
height = (initialHeight * animatedValue).toInt()
}
}
addListener(
onStart = {
if (Preferences.showClock) {
time_container.isVisible = true
}
},
onEnd = {
if (!Preferences.showClock) {
time_container.isVisible = false
}
}
)
}.start()
ValueAnimator.ofInt( if (preview.height == 0) {
preview.height, ValueAnimator.ofInt(
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel( preview.height,
requireContext() PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
) else 0 requireContext()
).apply { ) else 0
duration = 500L ).apply {
addUpdateListener { duration = 300L
val animatedValue = animatedValue as Int addUpdateListener {
val layoutParams = preview.layoutParams val animatedValue = animatedValue as Int
layoutParams.height = animatedValue val layoutParams = preview.layoutParams
preview.layoutParams = layoutParams layoutParams.height = animatedValue
} preview.layoutParams = layoutParams
}.start() }
} else { }.start()
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
} }
time_container.measure(0, 0)
}
if (preview.height == 0) { widget_loader.animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(200L)
ValueAnimator.ofInt( .start()
preview.height, bitmap_container.setImageBitmap(bitmap)
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel( widget.animate().alpha(1f).start()
requireContext()
) else 0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} }
widget_loader.animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(200L).start()
bitmap_container.setImageBitmap(bitmap)
widget.animate().alpha(1f).start()
} }
} else {
ValueAnimator.ofInt(
preview.height,
0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} }
} else {
ValueAnimator.ofInt(
preview.height,
0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} }
showErrorBadge() showErrorBadge()
@ -277,8 +290,16 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
val metrics = DisplayMetrics() val metrics = DisplayMetrics()
act.windowManager.defaultDisplay.getMetrics(metrics) act.windowManager.defaultDisplay.getMetrics(metrics)
height = metrics.heightPixels var newHeight = metrics.heightPixels
width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1) var newWidth = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicHeight ?: 1)
if (newWidth < metrics.widthPixels) {
newWidth = metrics.widthPixels
newHeight = (wallpaper?.intrinsicHeight ?: 1) * metrics.widthPixels / (wallpaper?.intrinsicWidth ?: 1)
}
height = newHeight
width = newWidth
} }
} }
}) })
@ -313,11 +334,6 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
}?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName) }?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)
} }
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
updateUI()
MainWidget.updateWidget(requireContext())
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
Preferences.preferences.registerOnSharedPreferenceChangeListener(this) Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
@ -332,10 +348,29 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
super.onPause() super.onPause()
} }
var delayJob: Job? = null
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
delayJob?.cancel()
delayJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
withContext(Dispatchers.Main) {
updateUI()
}
}
MainWidget.updateWidget(requireContext())
}
class UpdateUiMessageEvent class UpdateUiMessageEvent
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(ignore: UpdateUiMessageEvent?) { fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
updateUI() delayJob?.cancel()
delayJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
withContext(Dispatchers.Main) {
updateUI()
}
}
} }
} }

View File

@ -4,6 +4,7 @@ import android.Manifest
import android.content.Intent import android.content.Intent
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

View File

@ -58,6 +58,7 @@ class MainViewModel : ViewModel() {
val showMusic = Preferences.asLiveData(Preferences::showMusic) val showMusic = Preferences.asLiveData(Preferences::showMusic)
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm) val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging) val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging)
val showDailySteps = Preferences.asLiveData(Preferences::showDailySteps)
val customInfo = Preferences.asLiveData(Preferences::customNotes) val customInfo = Preferences.asLiveData(Preferences::customNotes)
// Advanced Settings // Advanced Settings

View File

@ -12,7 +12,6 @@ import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.text.format.DateUtils import android.text.format.DateUtils
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
@ -261,12 +260,7 @@ class MainWidget : AppWidgetProvider() {
views.setViewVisibility(R.id.empty_layout_rect, View.GONE) views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
} else if (Preferences.showGlance) { } else if (GlanceProviderHelper.showGlanceProviders(context)) {
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) { loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) {
when (provider) { when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> { Constants.GlanceProviderId.PLAYING_SONG -> {
@ -293,28 +287,28 @@ class MainWidget : AppWidgetProvider() {
break@loop break@loop
} }
} }
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
// if (Preferences.isBatteryLevelLow) { if (Preferences.isBatteryLevelLow) {
// val alarmIntent = PendingIntent.getActivity( val alarmIntent = PendingIntent.getActivity(
// context, context,
// widgetID, widgetID,
// IntentHelper.getClockIntent(context), IntentHelper.getClockIntent(context),
// 0 0
// ) )
// views.setOnClickPendingIntent(R.id.second_row_rect, alarmIntent) views.setOnClickPendingIntent(R.id.second_row_rect, alarmIntent)
// break@loop break@loop
// } }
// } }
Constants.GlanceProviderId.CUSTOM_INFO -> { Constants.GlanceProviderId.CUSTOM_INFO -> {
if (Preferences.customNotes.isNotEmpty()) { if (Preferences.customNotes.isNotEmpty()) {
break@loop break@loop
} }
} }
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
// if (Preferences.googleFitSteps > 0) { if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
// break@loop break@loop
// } }
// } }
} }
} }
@ -371,7 +365,7 @@ class MainWidget : AppWidgetProvider() {
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false) BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
) )
if (GlanceProviderHelper.showSpecialWeather(context)) { if (GlanceProviderHelper.showGlanceProviders(context)) {
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE) views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
} else { } else {
views.setViewVisibility(R.id.special_weather_rect, View.GONE) views.setViewVisibility(R.id.special_weather_rect, View.GONE)
@ -524,7 +518,7 @@ class MainWidget : AppWidgetProvider() {
v.empty_layout.visibility = View.GONE v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE v.calendar_layout.visibility = View.VISIBLE
} else if (Preferences.showGlance) { } else if (GlanceProviderHelper.showGlanceProviders(context)) {
v.second_row_icon.isVisible = true v.second_row_icon.isVisible = true
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) { loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) {
when (provider) { when (provider) {
@ -552,18 +546,18 @@ class MainWidget : AppWidgetProvider() {
break@loop break@loop
} }
} }
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
// if (Preferences.isBatteryLevelLow) { if (Preferences.isBatteryLevelLow) {
// v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
// ContextCompat.getDrawable( ContextCompat.getDrawable(
// context, context,
// R.drawable.round_battery_charging_full R.drawable.round_battery_charging_full
// ) )
// ) )
// v.next_event_date.text = context.getString(R.string.battery_low_warning) v.next_event_date.text = context.getString(R.string.battery_low_warning)
// break@loop break@loop
// } }
// } }
Constants.GlanceProviderId.CUSTOM_INFO -> { Constants.GlanceProviderId.CUSTOM_INFO -> {
if (Preferences.customNotes.isNotEmpty()) { if (Preferences.customNotes.isNotEmpty()) {
v.second_row_icon.isVisible = false v.second_row_icon.isVisible = false
@ -571,18 +565,18 @@ class MainWidget : AppWidgetProvider() {
break@loop break@loop
} }
} }
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
// if (Preferences.googleFitSteps > 0) { if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
// v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
// ContextCompat.getDrawable( ContextCompat.getDrawable(
// context, context,
// R.drawable.round_directions_walk R.drawable.round_directions_walk
// ) )
// ) )
// v.next_event_date.text = "" v.next_event_date.text = "${Preferences.googleFitSteps}"
// break@loop break@loop
// } }
// } }
} }
} }
@ -694,7 +688,7 @@ class MainWidget : AppWidgetProvider() {
v.calendar_temp.text = currentTemp v.calendar_temp.text = currentTemp
v.special_temp.text = currentTemp v.special_temp.text = currentTemp
if (GlanceProviderHelper.showSpecialWeather(context)) { if (GlanceProviderHelper.showGlanceProviders(context)) {
v.calendar_weather.visibility = View.GONE v.calendar_weather.visibility = View.GONE
} else { } else {
v.special_weather.visibility = View.GONE v.special_weather.visibility = View.GONE

View File

@ -214,43 +214,6 @@
style="@style/AnotherWidget.Settings.Subtitle"/> style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_multiple_events"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_code"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_show_multiple_events_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_multiple_events_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -325,43 +288,6 @@
style="@style/AnotherWidget.Settings.Subtitle"/> style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_date_format"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="10dp"
android:src="@drawable/round_text_format"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_date_format_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/date_format_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -399,6 +325,43 @@
style="@style/AnotherWidget.Settings.Subtitle"/> style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_multiple_events"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_code"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_show_multiple_events_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_multiple_events_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -166,6 +166,43 @@
style="@style/AnotherWidget.Settings.Subtitle"/> style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_date_format"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="10dp"
android:src="@drawable/round_text_format"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_date_format_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/date_format_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -185,6 +185,60 @@
android:textColor="@color/warningColorText" /> android:textColor="@color/warningColorText" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_steps"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_directions_walk"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_daily_steps_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_steps_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="36dp"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:letterSpacing="0"
android:textAllCaps="false"
android:clickable="true"
android:layout_marginStart="-8dp"
android:layout_marginBottom="-8dp"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:focusable="true"
android:visibility="gone"
android:id="@+id/fitness_permission_alert"
android:textColor="@color/errorColorText"
android:text="@string/action_grant_permission"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -207,6 +207,7 @@
<string name="settings_show_music_disabled_subtitle">Hide playing song info</string> <string name="settings_show_music_disabled_subtitle">Hide playing song info</string>
<string name="settings_song_info_format_title">Song info format</string> <string name="settings_song_info_format_title">Song info format</string>
<string name="settings_request_notification_access">We need the notification access permission to check the current playing song.</string> <string name="settings_request_notification_access">We need the notification access permission to check the current playing song.</string>
<string name="settings_request_fitness_access">We need a few permissions to get your daily steps from Google Fit.</string>
<string name="title_googlefit" translatable="false">Google Fit</string> <string name="title_googlefit" translatable="false">Google Fit</string>
<string name="settings_title_integrations">Integrations</string> <string name="settings_title_integrations">Integrations</string>
<string name="label_count_installed_integrations">%d installed integrations</string> <string name="label_count_installed_integrations">%d installed integrations</string>

View File

@ -1,9 +1,5 @@
apply plugin: 'com.android.dynamic-feature' apply plugin: 'com.android.dynamic-feature'
def apiKeyPropertiesFile = rootProject.file("apikey.properties")
def apiKeyProperties = new Properties()
apiKeyProperties.load(new FileInputStream(apiKeyPropertiesFile))
android { android {
compileSdkVersion 29 compileSdkVersion 29
@ -12,8 +8,6 @@ android {
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
manifestPlaceholders = [ "AWARENESS_API_KEY": apiKeyProperties['AWARENESS_API_KEY']]
} }
compileOptions { compileOptions {

View File

@ -11,10 +11,6 @@
<dist:on-demand /> <dist:on-demand />
</dist:delivery> </dist:delivery>
<dist:fusing dist:include="true" /> <dist:fusing dist:include="true" />
<meta-data
android:name="com.google.android.awareness.API_KEY"
android:value="${AWARENESS_API_KEY}"/>
</dist:module> </dist:module>
</manifest> </manifest>

View File

@ -1,4 +1,2 @@
rootProject.name='Another Widget' rootProject.name='Another Widget'
include ':app' include ':app'
include ':tasksintegration'
include ':googlefit'

View File

@ -1,4 +1,4 @@
#Sat May 09 22:27:49 CEST 2020 #Sun May 10 11:42:33 CEST 2020
base.0=/Users/tommaso/Documents/MyCode/another-widget/tasksintegration/build/intermediates/dex/debug/mergeProjectDexDebug/out/classes.dex base.0=/Users/tommaso/Documents/MyCode/another-widget/tasksintegration/build/intermediates/dex/debug/mergeProjectDexDebug/out/classes.dex
path.0=classes.dex path.0=classes.dex
renamed.0=classes.dex renamed.0=classes.dex