Add the app notifications filter
This commit is contained in:
parent
5259a81cfb
commit
1c1f55e20a
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@ -23,8 +23,8 @@ android {
|
|||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 106
|
versionCode 107
|
||||||
versionName "2.0.14"
|
versionName "2.0.15"
|
||||||
|
|
||||||
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'])
|
||||||
@ -64,13 +64,13 @@ dependencies {
|
|||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
||||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
||||||
implementation 'androidx.browser:browser:1.2.0'
|
implementation 'androidx.browser:browser:1.2.0'
|
||||||
implementation 'net.idik:slimadapter:2.1.2'
|
implementation 'net.idik:slimadapter:2.1.2'
|
||||||
@ -84,15 +84,15 @@ dependencies {
|
|||||||
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
||||||
|
|
||||||
// EventBus
|
// EventBus
|
||||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'joda-time:joda-time:2.10.3'
|
implementation 'joda-time:joda-time:2.10.6'
|
||||||
implementation 'me.everything:providers-android:1.0.1'
|
implementation 'me.everything:providers-android:1.0.1'
|
||||||
implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
|
implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
|
||||||
|
|
||||||
@ -121,8 +121,8 @@ dependencies {
|
|||||||
//Retrofit
|
//Retrofit
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
|
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
|
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
|
||||||
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
||||||
|
|
||||||
//Coroutines
|
//Coroutines
|
||||||
@ -137,7 +137,7 @@ dependencies {
|
|||||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
implementation 'com.karumi:dexter:6.1.0'
|
implementation 'com.karumi:dexter:6.2.1'
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
implementation 'com.github.firatkarababa:downloadable-font-list-library:1.0.2'
|
implementation 'com.github.firatkarababa:downloadable-font-list-library:1.0.2'
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
<activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.IntegrationsActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.IntegrationsActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.MusicPlayersFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.MusicPlayersFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
<activity android:name=".ui.activities.AppNotificationsFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
|
||||||
|
|
||||||
<receiver android:name=".ui.widgets.MainWidget">
|
<receiver android:name=".ui.widgets.MainWidget">
|
||||||
|
@ -23,9 +23,11 @@ import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
|||||||
import com.tommasoberlose.anotherwidget.R
|
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.helpers.ActiveNotificationsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
|
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
|
||||||
@ -94,6 +96,9 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
|
view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
|
||||||
if (provider == Constants.GlanceProviderId.NOTIFICATIONS) {
|
if (provider == Constants.GlanceProviderId.NOTIFICATIONS) {
|
||||||
checkLastNotificationsPermission(view)
|
checkLastNotificationsPermission(view)
|
||||||
|
view.action_filter_notifications_app.setOnClickListener {
|
||||||
|
context.startActivity(Intent(context, AppNotificationsFilterActivity::class.java))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GREETINGS */
|
/* GREETINGS */
|
||||||
@ -200,7 +205,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
|
|
||||||
private fun checkNotificationPermission(view: View) {
|
private fun checkNotificationPermission(view: View) {
|
||||||
when {
|
when {
|
||||||
NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) -> {
|
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
|
||||||
view.warning_container.isVisible = false
|
view.warning_container.isVisible = false
|
||||||
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||||
}
|
}
|
||||||
@ -220,7 +225,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
|
|
||||||
private fun checkLastNotificationsPermission(view: View) {
|
private fun checkLastNotificationsPermission(view: View) {
|
||||||
when {
|
when {
|
||||||
NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) -> {
|
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
|
||||||
view.warning_container.isVisible = false
|
view.warning_container.isVisible = false
|
||||||
}
|
}
|
||||||
Preferences.showNotifications -> {
|
Preferences.showNotifications -> {
|
||||||
|
@ -138,6 +138,7 @@ object Preferences : KotprefModel() {
|
|||||||
var mediaPlayerArtist by stringPref(default = "")
|
var mediaPlayerArtist by stringPref(default = "")
|
||||||
var mediaPlayerPackage by stringPref(default = "")
|
var mediaPlayerPackage by stringPref(default = "")
|
||||||
var musicPlayersFilter by stringPref(default = "")
|
var musicPlayersFilter by stringPref(default = "")
|
||||||
|
var appNotificationsFilter by stringPref(default = "")
|
||||||
|
|
||||||
// Integrations
|
// Integrations
|
||||||
var installedIntegrations by intPref(default = 0)
|
var installedIntegrations by intPref(default = 0)
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package com.tommasoberlose.anotherwidget.helpers
|
package com.tommasoberlose.anotherwidget.helpers
|
||||||
|
|
||||||
import android.app.Notification
|
import android.content.ContentResolver
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.service.notification.StatusBarNotification
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import com.chibatching.kotpref.Kotpref
|
import com.chibatching.kotpref.Kotpref
|
||||||
import com.chibatching.kotpref.blockingBulk
|
import com.chibatching.kotpref.blockingBulk
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import java.lang.Exception
|
import com.tommasoberlose.anotherwidget.receivers.NotificationListener
|
||||||
|
|
||||||
object ActiveNotificationsHelper {
|
object ActiveNotificationsHelper {
|
||||||
fun showLastNotification(): Boolean {
|
fun showLastNotification(): Boolean {
|
||||||
@ -25,4 +24,22 @@ object ActiveNotificationsHelper {
|
|||||||
remove(Preferences::lastNotificationIcon)
|
remove(Preferences::lastNotificationIcon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkNotificationAccess(context: Context): Boolean {
|
||||||
|
val contentResolver: ContentResolver = context.contentResolver
|
||||||
|
val enabledNotificationListeners =
|
||||||
|
Settings.Secure.getString(contentResolver, "enabled_notification_listeners")
|
||||||
|
val packageName: String = context.packageName
|
||||||
|
return NotificationManagerCompat.getEnabledListenerPackages(context).contains(packageName) && (enabledNotificationListeners != null && enabledNotificationListeners.contains(NotificationListener::class.java.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAppAccepted(appPkg: String): Boolean = Preferences.appNotificationsFilter == "" || Preferences.appNotificationsFilter.contains(appPkg)
|
||||||
|
|
||||||
|
fun toggleAppFilter(appPkg: String) {
|
||||||
|
if (Preferences.appNotificationsFilter == "" || !Preferences.appNotificationsFilter.contains(appPkg)) {
|
||||||
|
Preferences.appNotificationsFilter = Preferences.appNotificationsFilter.split(",").union(listOf(appPkg)).joinToString(separator = ",")
|
||||||
|
} else {
|
||||||
|
Preferences.appNotificationsFilter = Preferences.appNotificationsFilter.split(",").filter { it != appPkg }.joinToString(separator = ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,7 +6,6 @@ import android.media.MediaMetadata
|
|||||||
import android.media.session.MediaController
|
import android.media.session.MediaController
|
||||||
import android.media.session.MediaSessionManager
|
import android.media.session.MediaSessionManager
|
||||||
import android.media.session.PlaybackState
|
import android.media.session.PlaybackState
|
||||||
import androidx.core.app.NotificationManagerCompat
|
|
||||||
import com.chibatching.kotpref.Kotpref
|
import com.chibatching.kotpref.Kotpref
|
||||||
import com.chibatching.kotpref.blockingBulk
|
import com.chibatching.kotpref.blockingBulk
|
||||||
import com.chibatching.kotpref.bulk
|
import com.chibatching.kotpref.bulk
|
||||||
@ -16,7 +15,7 @@ import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
|||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
object MediaPlayerHelper {
|
object MediaPlayerHelper {
|
||||||
fun isSomeonePlaying(context: Context) = Preferences.showMusic && NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) && Preferences.mediaPlayerTitle != ""
|
fun isSomeonePlaying(context: Context) = Preferences.showMusic && ActiveNotificationsHelper.checkNotificationAccess(context) && Preferences.mediaPlayerTitle != ""
|
||||||
|
|
||||||
fun getMediaInfo(): String {
|
fun getMediaInfo(): String {
|
||||||
return if (Preferences.mediaPlayerArtist == "") {
|
return if (Preferences.mediaPlayerArtist == "") {
|
||||||
@ -28,7 +27,7 @@ object MediaPlayerHelper {
|
|||||||
|
|
||||||
fun updatePlayingMediaInfo(context: Context) {
|
fun updatePlayingMediaInfo(context: Context) {
|
||||||
Kotpref.init(context)
|
Kotpref.init(context)
|
||||||
if (NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName)) {
|
if (ActiveNotificationsHelper.checkNotificationAccess(context)) {
|
||||||
val list = try {
|
val list = try {
|
||||||
(context.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager).getActiveSessions(
|
(context.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager).getActiveSessions(
|
||||||
ComponentName(context.packageName, NotificationListener::class.java.name)
|
ComponentName(context.packageName, NotificationListener::class.java.name)
|
||||||
@ -89,7 +88,7 @@ object MediaPlayerHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMusicPlayerAccepted(appPkg: String): Boolean = Preferences.musicPlayersFilter.contains(appPkg)
|
fun isMusicPlayerAccepted(appPkg: String): Boolean = Preferences.musicPlayersFilter == "" || Preferences.musicPlayersFilter.contains(appPkg)
|
||||||
|
|
||||||
fun toggleMusicPlayerFilter(appPkg: String) {
|
fun toggleMusicPlayerFilter(appPkg: String) {
|
||||||
if (Preferences.musicPlayersFilter == "" || !Preferences.musicPlayersFilter.contains(appPkg)) {
|
if (Preferences.musicPlayersFilter == "" || !Preferences.musicPlayersFilter.contains(appPkg)) {
|
||||||
|
@ -7,6 +7,7 @@ import android.media.session.MediaSession
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.service.notification.NotificationListenerService
|
import android.service.notification.NotificationListenerService
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
|
import android.util.Log
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
||||||
@ -30,7 +31,7 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
||||||
val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0
|
val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0
|
||||||
|
|
||||||
if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing) {
|
if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing && ActiveNotificationsHelper.isAppAccepted(sbn.packageName)) {
|
||||||
Preferences.lastNotificationId = sbn.id
|
Preferences.lastNotificationId = sbn.id
|
||||||
Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: ""
|
Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: ""
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.activities
|
||||||
|
|
||||||
|
import android.content.pm.ResolveInfo
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.ActivityAppNotificationsFilterBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.AppNotificationsViewModel
|
||||||
|
import kotlinx.android.synthetic.main.activity_app_notifications_filter.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
|
|
||||||
|
|
||||||
|
class AppNotificationsFilterActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var adapter: SlimAdapter
|
||||||
|
private lateinit var viewModel: AppNotificationsViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this).get(AppNotificationsViewModel::class.java)
|
||||||
|
val binding = DataBindingUtil.setContentView<ActivityAppNotificationsFilterBinding>(this, R.layout.activity_app_notifications_filter)
|
||||||
|
|
||||||
|
list_view.setHasFixedSize(true)
|
||||||
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
|
list_view.layoutManager = mLayoutManager
|
||||||
|
|
||||||
|
adapter = SlimAdapter.create()
|
||||||
|
adapter
|
||||||
|
.register<ResolveInfo>(R.layout.application_info_layout) { item, injector ->
|
||||||
|
injector
|
||||||
|
.text(R.id.text, item.loadLabel(viewModel.pm))
|
||||||
|
.with<ImageView>(R.id.icon) {
|
||||||
|
Glide
|
||||||
|
.with(this)
|
||||||
|
.load(item.loadIcon(viewModel.pm))
|
||||||
|
.centerCrop()
|
||||||
|
.into(it)
|
||||||
|
}
|
||||||
|
.visible(R.id.checkBox)
|
||||||
|
.clicked(R.id.item) {
|
||||||
|
toggleApp(item)
|
||||||
|
adapter.notifyItemRangeChanged(0, adapter.data.size)
|
||||||
|
}
|
||||||
|
.clicked(R.id.checkBox) {
|
||||||
|
toggleApp(item)
|
||||||
|
adapter.notifyItemRangeChanged(0, adapter.data.size)
|
||||||
|
}
|
||||||
|
.checked(R.id.checkBox, ActiveNotificationsHelper.isAppAccepted(item.activityInfo.packageName))
|
||||||
|
}
|
||||||
|
.attachTo(list_view)
|
||||||
|
|
||||||
|
setupListener()
|
||||||
|
subscribeUi(binding, viewModel)
|
||||||
|
|
||||||
|
search.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var filterJob: Job? = null
|
||||||
|
|
||||||
|
private fun subscribeUi(binding: ActivityAppNotificationsFilterBinding, viewModel: AppNotificationsViewModel) {
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
binding.lifecycleOwner = this
|
||||||
|
|
||||||
|
viewModel.appList.observe(this, Observer {
|
||||||
|
updateList(list = it)
|
||||||
|
loader.visibility = View.INVISIBLE
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.searchInput.observe(this, Observer { search ->
|
||||||
|
updateList(search = search)
|
||||||
|
clear_search.isVisible = search.isNotBlank()
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.appNotificationsFilter.observe(this, {
|
||||||
|
updateList()
|
||||||
|
clear_selection.isVisible = Preferences.appNotificationsFilter != ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateList(list: List<ResolveInfo>? = viewModel.appList.value, search: String? = viewModel.searchInput.value) {
|
||||||
|
loader.visibility = View.VISIBLE
|
||||||
|
filterJob?.cancel()
|
||||||
|
filterJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
if (list != null && list.isNotEmpty()) {
|
||||||
|
delay(200)
|
||||||
|
val filteredList: List<ResolveInfo> = if (search == null || search == "") {
|
||||||
|
list
|
||||||
|
} else {
|
||||||
|
list.filter {
|
||||||
|
it.loadLabel(viewModel.pm).contains(search, true)
|
||||||
|
}
|
||||||
|
}.sortedWith { app1, app2 ->
|
||||||
|
if (ActiveNotificationsHelper.isAppAccepted(app1.activityInfo.packageName) && ActiveNotificationsHelper.isAppAccepted(app2.activityInfo.packageName)) {
|
||||||
|
app1.loadLabel(viewModel.pm).toString().compareTo(app2.loadLabel(viewModel.pm).toString(), ignoreCase = true)
|
||||||
|
} else if (ActiveNotificationsHelper.isAppAccepted(app1.activityInfo.packageName)) {
|
||||||
|
-1
|
||||||
|
} else if (ActiveNotificationsHelper.isAppAccepted(app2.activityInfo.packageName)) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
app1.loadLabel(viewModel.pm).toString().compareTo(app2.loadLabel(viewModel.pm).toString(), ignoreCase = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.updateData(filteredList)
|
||||||
|
loader.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListener() {
|
||||||
|
action_back.setOnClickListener {
|
||||||
|
onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_search.setOnClickListener {
|
||||||
|
viewModel.searchInput.value = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_selection.setOnClickListener {
|
||||||
|
Preferences.appNotificationsFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleApp(app: ResolveInfo) {
|
||||||
|
ActiveNotificationsHelper.toggleAppFilter(app.activityInfo.packageName)
|
||||||
|
}
|
||||||
|
}
|
@ -142,7 +142,7 @@ class MusicPlayersFilterActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_selection.setOnClickListener {
|
clear_selection.setOnClickListener {
|
||||||
Preferences.musicPlayersFilter = ","
|
Preferences.musicPlayersFilter = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import com.tommasoberlose.anotherwidget.components.GlanceSettingsDialog
|
|||||||
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
|
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
|
||||||
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.helpers.ActiveNotificationsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
|
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
@ -121,9 +122,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
when (provider) {
|
when (provider) {
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> {
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
when {
|
when {
|
||||||
NotificationManagerCompat.getEnabledListenerPackages(requireContext())
|
ActiveNotificationsHelper.checkNotificationAccess(requireContext()) -> {
|
||||||
.contains(
|
|
||||||
requireContext().packageName) -> {
|
|
||||||
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
@ -167,9 +166,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
when {
|
when {
|
||||||
NotificationManagerCompat.getEnabledListenerPackages(requireContext())
|
ActiveNotificationsHelper.checkNotificationAccess(requireContext()) -> {
|
||||||
.contains(
|
|
||||||
requireContext().packageName) -> {
|
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
injector.text(R.id.label,
|
injector.text(R.id.label,
|
||||||
@ -305,6 +302,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
adapter.updateData(
|
adapter.updateData(
|
||||||
GlanceProviderHelper.getGlanceProviders(requireContext())
|
GlanceProviderHelper.getGlanceProviders(requireContext())
|
||||||
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) }
|
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) }
|
||||||
|
.filterNot { it.id == Constants.GlanceProviderId.GREETINGS.id }
|
||||||
)
|
)
|
||||||
providers_list.isNestedScrollingEnabled = false
|
providers_list.isNestedScrollingEnabled = false
|
||||||
|
|
||||||
|
@ -72,8 +72,6 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
subscribeUi(viewModel)
|
|
||||||
|
|
||||||
// Viewpager
|
// Viewpager
|
||||||
pager.adapter = ViewPagerAdapter(requireActivity())
|
pager.adapter = ViewPagerAdapter(requireActivity())
|
||||||
pager.offscreenPageLimit = 4
|
pager.offscreenPageLimit = 4
|
||||||
@ -89,17 +87,20 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}.attach()
|
}.attach()
|
||||||
|
|
||||||
// Init clock
|
// Init clock
|
||||||
|
if (Preferences.showClock) {
|
||||||
time.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
|
time.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
|
||||||
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()))
|
time.setTextSize(TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(requireContext()))
|
||||||
time_am_pm.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
|
time_am_pm.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
|
||||||
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2)
|
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2)
|
||||||
|
}
|
||||||
time_container.isVisible = Preferences.showClock
|
time_container.isVisible = Preferences.showClock
|
||||||
|
|
||||||
preview.layoutParams = preview.layoutParams.apply {
|
preview.layoutParams = preview.layoutParams.apply {
|
||||||
height = PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
|
height = PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
|
||||||
}
|
}
|
||||||
subscribeUi(viewModel)
|
subscribeUi(viewModel)
|
||||||
updateUI()
|
|
||||||
|
|
||||||
// Warnings
|
// Warnings
|
||||||
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
|
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
|
||||||
@ -361,7 +362,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
tabs?.getTabAt(4)?.orCreateBadge?.apply {
|
tabs?.getTabAt(4)?.orCreateBadge?.apply {
|
||||||
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
||||||
badgeGravity = BadgeDrawable.TOP_END
|
badgeGravity = BadgeDrawable.TOP_END
|
||||||
}?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)) ||
|
}?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !ActiveNotificationsHelper.checkNotificationAccess(requireContext())) ||
|
||||||
(Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) ||
|
(Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) ||
|
||||||
(AlarmHelper.isAlarmProbablyWrong(requireContext()))
|
(AlarmHelper.isAlarmProbablyWrong(requireContext()))
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.ResolveInfo
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.chibatching.kotpref.livedata.asLiveData
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
|
class AppNotificationsViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
|
val pm: PackageManager by lazy { application.packageManager }
|
||||||
|
val appList: MutableLiveData<List<ResolveInfo>> = MutableLiveData()
|
||||||
|
val searchInput: MutableLiveData<String> = MutableLiveData("")
|
||||||
|
var appNotificationsFilter = Preferences.asLiveData(Preferences::appNotificationsFilter)
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val mainIntent = Intent(Intent.ACTION_MAIN, null).apply {
|
||||||
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
}
|
||||||
|
|
||||||
|
val app = application.packageManager.queryIntentActivities(mainIntent, 0)
|
||||||
|
val sortedApp = app.sortedWith(Comparator { app1: ResolveInfo, app2: ResolveInfo ->
|
||||||
|
app1.loadLabel(pm).toString().compareTo(app2.loadLabel(pm).toString())
|
||||||
|
})
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
appList.postValue(sortedApp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
app/src/main/res/layout/activity_app_notifications_filter.xml
Normal file
123
app/src/main/res/layout/activity_app_notifications_filter.xml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout>
|
||||||
|
<data>
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.tommasoberlose.anotherwidget.ui.viewmodels.AppNotificationsViewModel" />
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/colorPrimaryDark"
|
||||||
|
tools:context="com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity">
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardCornerRadius="0dp"
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
app:cardBackgroundColor="@color/colorPrimary">
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp">
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:id="@+id/action_back"
|
||||||
|
app:tint="@color/colorPrimaryText"
|
||||||
|
android:src="@drawable/round_arrow_back" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:text="@string/applications_filter_title"
|
||||||
|
android:gravity="center"
|
||||||
|
style="@style/AnotherWidget.Main.Title"/>
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/round_clear_all"
|
||||||
|
app:tint="@color/colorPrimaryText"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:id="@+id/clear_selection" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardCornerRadius="0dp"
|
||||||
|
app:cardBackgroundColor="@color/colorPrimary">
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardBackgroundColor="@color/colorPrimaryDark"
|
||||||
|
app:cardCornerRadius="9dp"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@color/colorPrimaryDark"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="64dp"
|
||||||
|
android:inputType="textCapWords"
|
||||||
|
android:textColor="@color/colorPrimaryText"
|
||||||
|
android:textColorHint="@color/colorSecondaryText"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:id="@+id/search"
|
||||||
|
android:fontFamily="@font/google_sans"
|
||||||
|
android:gravity="center_vertical|start"
|
||||||
|
android:hint="@string/search"
|
||||||
|
android:text="@={viewModel.searchInput}"
|
||||||
|
android:autofillHints="" />
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:src="@drawable/round_close"
|
||||||
|
app:tint="@color/colorPrimaryText"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:id="@+id/clear_search" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<androidx.core.widget.ContentLoadingProgressBar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:indeterminateTint="@color/colorAccent"
|
||||||
|
android:layout_marginTop="-7dp"
|
||||||
|
android:id="@+id/loader"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/list_view" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</layout>
|
@ -49,6 +49,9 @@
|
|||||||
android:layout_width="48dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/round_clear_all"
|
android:src="@drawable/round_clear_all"
|
||||||
app:tint="@color/colorPrimaryText"
|
app:tint="@color/colorPrimaryText"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
|
@ -197,12 +197,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
style="@style/AnotherWidget.Settings.Title"
|
style="@style/AnotherWidget.Settings.Title"
|
||||||
android:text="App notifications filter"/>
|
android:text="@string/applications_filter_title"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:text="@string/settings_music_players_filter_subtitle"
|
android:text="@string/applications_filter_subtitle"
|
||||||
style="@style/AnotherWidget.Settings.Subtitle"/>
|
style="@style/AnotherWidget.Settings.Subtitle"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -209,6 +209,8 @@
|
|||||||
<string name="google_fit">Google Fit</string>
|
<string name="google_fit">Google Fit</string>
|
||||||
<string name="action_connect">Collega</string>
|
<string name="action_connect">Collega</string>
|
||||||
<string name="action_disconnect">Scollega</string>
|
<string name="action_disconnect">Scollega</string>
|
||||||
|
<string name="applications_filter_title">Applicazioni</string>
|
||||||
|
<string name="applications_filter_subtitle">Scegli le notifiche che vuoi vedere</string>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="action_share">Condividi</string>
|
<string name="action_share">Condividi</string>
|
||||||
|
@ -226,6 +226,8 @@
|
|||||||
<string name="google_fit">Google Fit</string>
|
<string name="google_fit">Google Fit</string>
|
||||||
<string name="action_connect">Connect</string>
|
<string name="action_connect">Connect</string>
|
||||||
<string name="action_disconnect">Disconnect</string>
|
<string name="action_disconnect">Disconnect</string>
|
||||||
|
<string name="applications_filter_title">Applications</string>
|
||||||
|
<string name="applications_filter_subtitle">Choose which notifications to view</string>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="action_share">Share</string>
|
<string name="action_share">Share</string>
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Tue Oct 13 10:06:21 CEST 2020
|
#Wed Oct 14 12:52:53 CEST 2020
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user