Move the location updates to a foreground service and fix multiple bugs
This commit is contained in:
parent
ebb37f21ed
commit
66d0214cd9
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@ -16,15 +16,15 @@ apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
||||||
compileSdkVersion 29
|
compileSdkVersion 30
|
||||||
buildToolsVersion "29.0.3"
|
buildToolsVersion "29.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 30
|
||||||
versionCode 110
|
versionCode 112
|
||||||
versionName "2.0.15"
|
versionName "2.1.0"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
||||||
@ -72,9 +72,9 @@ dependencies {
|
|||||||
|
|
||||||
// UI
|
// UI
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
implementation 'com.google.android.material:material:1.3.0-beta01'
|
||||||
implementation 'androidx.browser:browser:1.2.0'
|
implementation 'androidx.browser:browser:1.3.0'
|
||||||
implementation 'net.idik:slimadapter:2.1.2'
|
implementation 'net.idik:slimadapter:2.1.2'
|
||||||
implementation 'com.google.android:flexbox:2.0.1'
|
implementation 'com.google.android:flexbox:2.0.1'
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ dependencies {
|
|||||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
@ -103,7 +103,7 @@ dependencies {
|
|||||||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
|
|
||||||
// Fitness
|
// Fitness
|
||||||
implementation 'com.google.android.gms:play-services-fitness:18.0.0'
|
implementation 'com.google.android.gms:play-services-fitness:20.0.0'
|
||||||
implementation 'com.google.android.gms:play-services-auth:18.1.0'
|
implementation 'com.google.android.gms:play-services-auth:18.1.0'
|
||||||
|
|
||||||
//Weather
|
//Weather
|
||||||
@ -111,8 +111,8 @@ dependencies {
|
|||||||
implementation 'com.google.android.gms:play-services-location:17.1.0'
|
implementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||||
|
|
||||||
// Billing
|
// Billing
|
||||||
implementation 'com.android.billingclient:billing:3.0.1'
|
implementation 'com.android.billingclient:billing:3.0.2'
|
||||||
implementation 'com.android.billingclient:billing-ktx:3.0.1'
|
implementation 'com.android.billingclient:billing-ktx:3.0.2'
|
||||||
|
|
||||||
// KTX
|
// KTX
|
||||||
implementation "androidx.core:core-ktx:1.3.2"
|
implementation "androidx.core:core-ktx:1.3.2"
|
||||||
@ -128,10 +128,10 @@ dependencies {
|
|||||||
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
||||||
|
|
||||||
//Coroutines
|
//Coroutines
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
|
||||||
|
|
||||||
// Add the Firebase SDK for Crashlytics.
|
// Add the Firebase SDK for Crashlytics.
|
||||||
implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
|
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
implementation 'com.chibatching.kotpref:kotpref:2.11.0'
|
implementation 'com.chibatching.kotpref:kotpref:2.11.0'
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
<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" />
|
||||||
@ -13,6 +12,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||||
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
||||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
@ -154,6 +154,14 @@
|
|||||||
android:name=".services.UpdateCalendarJob"
|
android:name=".services.UpdateCalendarJob"
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||||
android:exported="true"/>
|
android:exported="true"/>
|
||||||
|
<service
|
||||||
|
android:name=".services.LocationService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false"
|
||||||
|
android:foregroundServiceType="location" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<package android:name="com.google.android.apps.fitness"/>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
@ -24,6 +24,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
||||||
import com.tommasoberlose.anotherwidget.utils.expand
|
import com.tommasoberlose.anotherwidget.utils.expand
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
import com.tommasoberlose.anotherwidget.utils.reveal
|
import com.tommasoberlose.anotherwidget.utils.reveal
|
||||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||||
import com.warkiz.widget.IndicatorSeekBar
|
import com.warkiz.widget.IndicatorSeekBar
|
||||||
@ -93,6 +94,7 @@ class BottomSheetColorPicker(
|
|||||||
injector
|
injector
|
||||||
.with<MaterialCardView>(R.id.color) {
|
.with<MaterialCardView>(R.id.color) {
|
||||||
it.setCardBackgroundColor(ColorStateList.valueOf(item))
|
it.setCardBackgroundColor(ColorStateList.valueOf(item))
|
||||||
|
it.strokeWidth = if ((colors.indexOf(item) == 0 && !context.isDarkTheme()) || (colors.indexOf(item) == 10 && context.isDarkTheme())) 2 else 0
|
||||||
}
|
}
|
||||||
.with<AppCompatImageView>(R.id.check) {
|
.with<AppCompatImageView>(R.id.check) {
|
||||||
if (getSelected?.invoke() == item) {
|
if (getSelected?.invoke() == item) {
|
||||||
|
@ -10,6 +10,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
|
import com.tommasoberlose.anotherwidget.services.LocationService
|
||||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
@ -31,26 +32,8 @@ object WeatherHelper {
|
|||||||
val networkApi = WeatherNetworkApi(context)
|
val networkApi = WeatherNetworkApi(context)
|
||||||
if (Preferences.customLocationAdd != "") {
|
if (Preferences.customLocationAdd != "") {
|
||||||
networkApi.updateWeather()
|
networkApi.updateWeather()
|
||||||
} else if (context.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION)) {
|
} else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||||
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnCompleteListener { task ->
|
LocationService.requestNewLocation(context)
|
||||||
if (task.isSuccessful) {
|
|
||||||
val location = task.result
|
|
||||||
if (location != null) {
|
|
||||||
Preferences.customLocationLat = location.latitude.toString()
|
|
||||||
Preferences.customLocationLon = location.longitude.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
} else {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.services
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.*
|
||||||
|
import android.app.job.JobScheduler
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.location.Address
|
||||||
|
import android.location.Geocoder
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.app.*
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.android.gms.location.LocationServices
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import java.lang.Exception
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class LocationService : Service() {
|
||||||
|
|
||||||
|
private val jobs: ArrayList<Job> = ArrayList()
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
|
||||||
|
|
||||||
|
jobs += GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
LocationServices.getFusedLocationProviderClient(this@LocationService).lastLocation.addOnCompleteListener { task ->
|
||||||
|
val networkApi = WeatherNetworkApi(this@LocationService)
|
||||||
|
if (task.isSuccessful) {
|
||||||
|
val location = task.result
|
||||||
|
if (location != null) {
|
||||||
|
Preferences.customLocationLat = location.latitude.toString()
|
||||||
|
Preferences.customLocationLon = location.longitude.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
networkApi.updateWeather()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
stopForeground(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
} else {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
networkApi.updateWeather()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
stopForeground(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stopForeground(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
jobs.forEach {
|
||||||
|
it.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LOCATION_ACCESS_NOTIFICATION_ID = 28465
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun requestNewLocation(context: Context) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
|
context.startForegroundService(Intent(context, LocationService::class.java))
|
||||||
|
} else {
|
||||||
|
context.startService(Intent(context, LocationService::class.java))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLocationAccessNotification(): Notification {
|
||||||
|
with(NotificationManagerCompat.from(this)) {
|
||||||
|
// Create channel
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
|
createNotificationChannel(
|
||||||
|
NotificationChannel(
|
||||||
|
getString(R.string.location_access_notification_channel_id),
|
||||||
|
getString(R.string.location_access_notification_channel_name),
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
).apply {
|
||||||
|
description = getString(R.string.location_access_notification_channel_description)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val builder = NotificationCompat.Builder(this@LocationService, getString(R.string.location_access_notification_channel_id))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notification)
|
||||||
|
.setContentTitle(getString(R.string.location_access_notification_title))
|
||||||
|
.setStyle(NotificationCompat.BigTextStyle().bigText(getString(R.string.location_access_notification_subtitle)))
|
||||||
|
.setOngoing(true)
|
||||||
|
.setColor(ContextCompat.getColor(this@LocationService, R.color.colorAccent))
|
||||||
|
|
||||||
|
// Main intent that open the activity
|
||||||
|
builder.setContentIntent(PendingIntent.getActivity(this@LocationService, 0, Intent(this@LocationService, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
|
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -140,7 +140,7 @@ class CustomLocationActivity : AppCompatActivity() {
|
|||||||
private fun requirePermission() {
|
private fun requirePermission() {
|
||||||
Dexter.withContext(this)
|
Dexter.withContext(this)
|
||||||
.withPermissions(
|
.withPermissions(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
).withListener(object: MultiplePermissionsListener {
|
).withListener(object: MultiplePermissionsListener {
|
||||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
report?.let {
|
report?.let {
|
||||||
|
@ -351,7 +351,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}?.isVisible = if (Preferences.showWeather) {
|
}?.isVisible = if (Preferences.showWeather) {
|
||||||
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|
||||||
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
|
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
) != true)
|
) != true)
|
||||||
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|
||||||
|| (Preferences.weatherProviderLocationError != "")
|
|| (Preferences.weatherProviderLocationError != "")
|
||||||
|
@ -161,12 +161,7 @@ class WeatherTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLocationPermission() {
|
private fun checkLocationPermission() {
|
||||||
// Background permission
|
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && activity?.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) == true && activity?.checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != true) {
|
|
||||||
requirePermission()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) == true) {
|
|
||||||
location_permission_alert?.isVisible = false
|
location_permission_alert?.isVisible = false
|
||||||
background_location_warning.isVisible = Preferences.customLocationAdd == ""
|
background_location_warning.isVisible = Preferences.customLocationAdd == ""
|
||||||
WeatherReceiver.setUpdates(requireContext())
|
WeatherReceiver.setUpdates(requireContext())
|
||||||
@ -299,7 +294,7 @@ class WeatherTabFragment : Fragment() {
|
|||||||
private fun requirePermission() {
|
private fun requirePermission() {
|
||||||
Dexter.withContext(requireContext())
|
Dexter.withContext(requireContext())
|
||||||
.withPermissions(
|
.withPermissions(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
).withListener(object: MultiplePermissionsListener {
|
).withListener(object: MultiplePermissionsListener {
|
||||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
report?.let {
|
report?.let {
|
||||||
|
@ -21,6 +21,7 @@ import android.content.Intent
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.ViewPropertyAnimator
|
import android.view.ViewPropertyAnimator
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
|
BIN
app/src/main/res/drawable-hdpi/ic_stat_notification.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_stat_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 674 B |
BIN
app/src/main/res/drawable-mdpi/ic_stat_notification.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_stat_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 381 B |
BIN
app/src/main/res/drawable-xhdpi/ic_stat_notification.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_stat_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 796 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_stat_notification.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_stat_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_stat_notification.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_stat_notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
@ -13,6 +13,7 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:cardCornerRadius="24dp"
|
app:cardCornerRadius="24dp"
|
||||||
|
app:strokeColor="@color/disabledButtonBackground"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
android:id="@+id/color"
|
android:id="@+id/color"
|
||||||
app:cardBackgroundColor="@color/colorNightDark">
|
app:cardBackgroundColor="@color/colorNightDark">
|
||||||
|
@ -161,6 +161,12 @@
|
|||||||
<string name="weather_select_a_provider">Select a provider</string>
|
<string name="weather_select_a_provider">Select a provider</string>
|
||||||
<string name="weather_provider_activity_subtitle">Select a weather provider from the list.\nA few providers need a free personal account,\nbut they are usually more accurate.</string>
|
<string name="weather_provider_activity_subtitle">Select a weather provider from the list.\nA few providers need a free personal account,\nbut they are usually more accurate.</string>
|
||||||
|
|
||||||
|
<string name="location_access_notification_channel_id" translatable="false">location-access</string>
|
||||||
|
<string name="location_access_notification_channel_name">Background service</string>
|
||||||
|
<string name="location_access_notification_channel_description">Service used to update the weather based on the current location of the user.</string>
|
||||||
|
<string name="location_access_notification_title">Weather update</string>
|
||||||
|
<string name="location_access_notification_subtitle">We\'re updating the weather based on your current location.</string>
|
||||||
|
|
||||||
<!-- Clock -->
|
<!-- Clock -->
|
||||||
<string name="settings_clock_title">Clock</string>
|
<string name="settings_clock_title">Clock</string>
|
||||||
<string name="settings_clock_app_title">Tap on clock opens</string>
|
<string name="settings_clock_app_title">Tap on clock opens</string>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.4.10'
|
ext.kotlin_version = '1.4.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
@ -10,12 +10,12 @@ buildscript {
|
|||||||
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'com.google.gms:google-services:4.3.4'
|
classpath 'com.google.gms:google-services:4.3.4'
|
||||||
|
|
||||||
// Add the Crashlytics Gradle plugin.
|
// Add the Crashlytics Gradle plugin.
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
|
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
|
||||||
|
|
||||||
classpath 'io.realm:realm-gradle-plugin:6.0.2'
|
classpath 'io.realm:realm-gradle-plugin:6.0.2'
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user