diff --git a/app/src/main/java/io/timelimit/android/integration/platform/PlatformIntegration.kt b/app/src/main/java/io/timelimit/android/integration/platform/PlatformIntegration.kt index 32abd84..e5fe397 100644 --- a/app/src/main/java/io/timelimit/android/integration/platform/PlatformIntegration.kt +++ b/app/src/main/java/io/timelimit/android/integration/platform/PlatformIntegration.kt @@ -31,6 +31,7 @@ abstract class PlatformIntegration( abstract fun getLocalAppActivities(deviceId: String): Collection abstract fun getLocalAppTitle(packageName: String): String? abstract fun getAppIcon(packageName: String): Drawable? + abstract fun isSystemImageApp(packageName: String): Boolean abstract fun getLauncherAppPackageName(): String? abstract fun getCurrentProtectionLevel(): ProtectionLevel abstract fun getForegroundAppPermissionStatus(): RuntimePermissionStatus diff --git a/app/src/main/java/io/timelimit/android/integration/platform/android/AndroidIntegration.kt b/app/src/main/java/io/timelimit/android/integration/platform/android/AndroidIntegration.kt index 4fcb538..a47dbd7 100644 --- a/app/src/main/java/io/timelimit/android/integration/platform/android/AndroidIntegration.kt +++ b/app/src/main/java/io/timelimit/android/integration/platform/android/AndroidIntegration.kt @@ -34,6 +34,7 @@ import android.provider.Settings import android.util.Log import android.view.KeyEvent import android.widget.Toast +import androidx.collection.LruCache import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.LiveData @@ -116,6 +117,18 @@ class AndroidIntegration(context: Context): PlatformIntegration(maximumProtectio return AndroidIntegrationApps.getAppIcon(packageName, context) } + private val isSystemImageAppCache = object: LruCache(8) { + override fun create(key: String): Boolean? = try { + val appInfo: ApplicationInfo = context.packageManager.getApplicationInfo(key, 0) + + appInfo.flags and ApplicationInfo.FLAG_SYSTEM == ApplicationInfo.FLAG_SYSTEM + } catch (ex: PackageManager.NameNotFoundException) { + null + } + } + + override fun isSystemImageApp(packageName: String): Boolean = isSystemImageAppCache.get(packageName) ?: false + override fun getLauncherAppPackageName(): String? { return Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) diff --git a/app/src/main/java/io/timelimit/android/integration/platform/android/NotificationListener.kt b/app/src/main/java/io/timelimit/android/integration/platform/android/NotificationListener.kt index 8e12863..7547529 100644 --- a/app/src/main/java/io/timelimit/android/integration/platform/android/NotificationListener.kt +++ b/app/src/main/java/io/timelimit/android/integration/platform/android/NotificationListener.kt @@ -18,8 +18,6 @@ package io.timelimit.android.integration.platform.android import android.annotation.TargetApi import android.app.NotificationManager import android.content.Context -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager import android.os.Build import android.service.notification.NotificationListenerService import android.service.notification.StatusBarNotification @@ -153,16 +151,19 @@ class NotificationListener: NotificationListenerService() { return if (deviceAndUserRelatedData?.userRelatedData?.user?.type != UserType.Child) { BlockingReason.None } else { + val isSystemImageApp = appLogic.platformIntegration.isSystemImageApp(sbn.packageName) + val appHandling = AppBaseHandling.calculate( foregroundAppPackageName = sbn.packageName, foregroundAppActivityName = null, pauseCounting = false, pauseForegroundAppBackgroundLoop = false, userRelatedData = deviceAndUserRelatedData.userRelatedData, - deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData + deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData, + isSystemImageApp = isSystemImageApp ) - if (appHandling is AppBaseHandling.BlockDueToNoCategory && !isSystemApp(sbn.packageName)) { + if (appHandling is AppBaseHandling.BlockDueToNoCategory && !isSystemImageApp) { BlockingReason.NotPartOfAnCategory } else if (appHandling is AppBaseHandling.UseCategories) { val time = RealTime.newInstance() @@ -201,14 +202,4 @@ class NotificationListener: NotificationListenerService() { } } } - - private fun isSystemApp(packageName: String): Boolean { - try { - val appInfo = packageManager.getApplicationInfo(packageName, 0) - - return appInfo.flags and ApplicationInfo.FLAG_SYSTEM == ApplicationInfo.FLAG_SYSTEM - } catch (ex: PackageManager.NameNotFoundException) { - return false - } - } } \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/integration/platform/dummy/DummyIntegration.kt b/app/src/main/java/io/timelimit/android/integration/platform/dummy/DummyIntegration.kt index 741dd68..eab9fdb 100644 --- a/app/src/main/java/io/timelimit/android/integration/platform/dummy/DummyIntegration.kt +++ b/app/src/main/java/io/timelimit/android/integration/platform/dummy/DummyIntegration.kt @@ -55,6 +55,8 @@ class DummyIntegration( return null } + override fun isSystemImageApp(packageName: String): Boolean = false + override fun getLauncherAppPackageName(): String? = null override fun getCurrentProtectionLevel(): ProtectionLevel { diff --git a/app/src/main/java/io/timelimit/android/logic/AppAffectedByPrimaryDeviceUtil.kt b/app/src/main/java/io/timelimit/android/logic/AppAffectedByPrimaryDeviceUtil.kt index 9fdc63d..3755338 100644 --- a/app/src/main/java/io/timelimit/android/logic/AppAffectedByPrimaryDeviceUtil.kt +++ b/app/src/main/java/io/timelimit/android/logic/AppAffectedByPrimaryDeviceUtil.kt @@ -55,7 +55,8 @@ object AppAffectedByPrimaryDeviceUtil { deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData, userRelatedData = deviceAndUserRelatedData.userRelatedData, pauseCounting = false, - pauseForegroundAppBackgroundLoop = false + pauseForegroundAppBackgroundLoop = false, + isSystemImageApp = logic.platformIntegration.isSystemImageApp(currentApp.packageName) ) if (!(handling is AppBaseHandling.UseCategories)) { diff --git a/app/src/main/java/io/timelimit/android/logic/BackgroundTaskLogic.kt b/app/src/main/java/io/timelimit/android/logic/BackgroundTaskLogic.kt index e5d9554..c504e2b 100644 --- a/app/src/main/java/io/timelimit/android/logic/BackgroundTaskLogic.kt +++ b/app/src/main/java/io/timelimit/android/logic/BackgroundTaskLogic.kt @@ -294,7 +294,8 @@ class BackgroundTaskLogic(val appLogic: AppLogic) { pauseForegroundAppBackgroundLoop = pauseForegroundAppBackgroundLoop, userRelatedData = userRelatedData, deviceRelatedData = deviceRelatedData, - pauseCounting = !isScreenOn + pauseCounting = !isScreenOn, + isSystemImageApp = appLogic.platformIntegration.isSystemImageApp(app.packageName) ) } @@ -304,7 +305,8 @@ class BackgroundTaskLogic(val appLogic: AppLogic) { pauseForegroundAppBackgroundLoop = false, userRelatedData = userRelatedData, deviceRelatedData = deviceRelatedData, - pauseCounting = false + pauseCounting = false, + isSystemImageApp = audioPlaybackPackageName?.let { appLogic.platformIntegration.isSystemImageApp(it) } ?: false ) val allAppsBaseHandlings = foregroundAppWithBaseHandlings.map { it.second } + listOf(backgroundAppBaseHandling) diff --git a/app/src/main/java/io/timelimit/android/logic/DummyApps.kt b/app/src/main/java/io/timelimit/android/logic/DummyApps.kt new file mode 100644 index 0000000..462d9cd --- /dev/null +++ b/app/src/main/java/io/timelimit/android/logic/DummyApps.kt @@ -0,0 +1,47 @@ +/* + * TimeLimit Copyright 2019 - 2020 Jonas Lochmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.timelimit.android.logic + +import android.content.Context +import android.graphics.drawable.Drawable +import androidx.core.content.ContextCompat +import io.timelimit.android.R +import io.timelimit.android.data.model.App +import io.timelimit.android.data.model.AppRecommendation + +object DummyApps { + const val NOT_ASSIGNED_SYSTEM_IMAGE_APP = ".dummy.system_image" + + fun getTitle(packageName: String, context: Context): String? = when (packageName) { + NOT_ASSIGNED_SYSTEM_IMAGE_APP -> context.getString(R.string.dummy_app_unassigned_system_image_app) + else -> null + } + + fun getIcon(packageName: String, context: Context): Drawable? = when (packageName) { + NOT_ASSIGNED_SYSTEM_IMAGE_APP -> ContextCompat.getDrawable(context, R.mipmap.ic_system_app) + else -> null + } + + fun getApps(deviceId: String, context: Context): List = listOf( + App( + deviceId = deviceId, + packageName = NOT_ASSIGNED_SYSTEM_IMAGE_APP, + title = getTitle(NOT_ASSIGNED_SYSTEM_IMAGE_APP, context)!!, + isLaunchable = false, + recommendation = AppRecommendation.None + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt b/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt index bdb1eb0..dfaeb00 100644 --- a/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt +++ b/app/src/main/java/io/timelimit/android/logic/SuspendAppsLogic.kt @@ -171,6 +171,7 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { private fun getAppsWithCategories(packageNames: List, data: UserRelatedData, blockingAtActivityLevel: Boolean): Map> { val categoryForUnassignedApps = data.categoryById[data.user.categoryForNotAssignedApps] + val categoryForOtherSystemApps = data.findCategoryApp(DummyApps.NOT_ASSIGNED_SYSTEM_IMAGE_APP)?.categoryId?.let { data.categoryById[it] } if (blockingAtActivityLevel) { val categoriesByPackageName = data.categoryApps.groupBy { it.packageNameWithoutActivityName } @@ -183,7 +184,9 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { val isMainAppIncluded = categoriesItems?.find { !it.specifiesActivity } != null if (!isMainAppIncluded) { - if (categoryForUnassignedApps != null) { + if (categoryForOtherSystemApps != null && appLogic.platformIntegration.isSystemImageApp(packageName)) { + categories.add(categoryForOtherSystemApps.category.id) + } else if (categoryForUnassignedApps != null) { categories.add(categoryForUnassignedApps.category.id) } } @@ -198,7 +201,10 @@ class SuspendAppsLogic(private val appLogic: AppLogic): Observer { val result = mutableMapOf>() packageNames.forEach { packageName -> - val category = categoryByPackageName[packageName]?.categoryId ?: categoryForUnassignedApps?.category?.id + val category = categoryByPackageName[packageName]?.categoryId ?: run { + if (categoryForOtherSystemApps != null && appLogic.platformIntegration.isSystemImageApp(packageName)) + categoryForOtherSystemApps.category.id else categoryForUnassignedApps?.category?.id + } result[packageName] = if (category != null) setOf(category) else emptySet() } diff --git a/app/src/main/java/io/timelimit/android/logic/blockingreason/AppBaseHandling.kt b/app/src/main/java/io/timelimit/android/logic/blockingreason/AppBaseHandling.kt index 23f37db..b84f91e 100644 --- a/app/src/main/java/io/timelimit/android/logic/blockingreason/AppBaseHandling.kt +++ b/app/src/main/java/io/timelimit/android/logic/blockingreason/AppBaseHandling.kt @@ -22,6 +22,7 @@ import io.timelimit.android.data.model.derived.DeviceRelatedData import io.timelimit.android.data.model.derived.UserRelatedData import io.timelimit.android.integration.platform.android.AndroidIntegrationApps import io.timelimit.android.logic.BlockingLevel +import io.timelimit.android.logic.DummyApps sealed class AppBaseHandling { object Idle: AppBaseHandling() @@ -49,7 +50,8 @@ sealed class AppBaseHandling { pauseForegroundAppBackgroundLoop: Boolean, pauseCounting: Boolean, userRelatedData: UserRelatedData, - deviceRelatedData: DeviceRelatedData + deviceRelatedData: DeviceRelatedData, + isSystemImageApp: Boolean ): AppBaseHandling { if (pauseForegroundAppBackgroundLoop) { return PauseLogic @@ -71,7 +73,9 @@ sealed class AppBaseHandling { } else if (foregroundAppPackageName != null) { val appCategory = run { val tryActivityLevelBlocking = deviceRelatedData.deviceEntry.enableActivityLevelBlocking && foregroundAppActivityName != null - val appLevelCategory = userRelatedData.findCategoryApp(foregroundAppPackageName) + val appLevelCategory = userRelatedData.findCategoryApp(foregroundAppPackageName) ?: run { + if (isSystemImageApp) userRelatedData.findCategoryApp(DummyApps.NOT_ASSIGNED_SYSTEM_IMAGE_APP) else null + } (if (tryActivityLevelBlocking) { userRelatedData.findCategoryApp("$foregroundAppPackageName:$foregroundAppActivityName") diff --git a/app/src/main/java/io/timelimit/android/ui/lock/LockModel.kt b/app/src/main/java/io/timelimit/android/ui/lock/LockModel.kt index 4e475b0..d754a83 100644 --- a/app/src/main/java/io/timelimit/android/ui/lock/LockModel.kt +++ b/app/src/main/java/io/timelimit/android/ui/lock/LockModel.kt @@ -96,7 +96,8 @@ class LockModel(application: Application): AndroidViewModel(application) { deviceRelatedData = deviceAndUserRelatedData.deviceRelatedData, userRelatedData = deviceAndUserRelatedData.userRelatedData, pauseForegroundAppBackgroundLoop = false, - pauseCounting = false + pauseCounting = false, + isSystemImageApp = logic.platformIntegration.isSystemImageApp(packageName) ) val needsNetworkId = appBaseHandling.needsNetworkId() diff --git a/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddAppAdapter.kt b/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddAppAdapter.kt index 263fdd4..4bfcbe3 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddAppAdapter.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddAppAdapter.kt @@ -1,5 +1,5 @@ /* - * TimeLimit Copyright 2019 Jonas Lochmann + * TimeLimit Copyright 2019 - 2020 Jonas Lochmann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView import io.timelimit.android.data.model.App import io.timelimit.android.databinding.FragmentAddCategoryAppsItemBinding import io.timelimit.android.logic.DefaultAppLogic +import io.timelimit.android.logic.DummyApps import kotlin.properties.Delegates class AddAppAdapter: RecyclerView.Adapter() { @@ -61,6 +62,7 @@ class AddAppAdapter: RecyclerView.Adapter() { override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = getItem(position) + val context = holder.itemView.context holder.apply { binding.item = item @@ -70,7 +72,8 @@ class AddAppAdapter: RecyclerView.Adapter() { binding.executePendingBindings() binding.icon.setImageDrawable( - DefaultAppLogic.with(holder.itemView.context) + DummyApps.getIcon(item.packageName, context) ?: + DefaultAppLogic.with(context) .platformIntegration.getAppIcon(item.packageName) ) } diff --git a/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddCategoryAppsFragment.kt b/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddCategoryAppsFragment.kt index 9ffd945..31d3372 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddCategoryAppsFragment.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/category/apps/add/AddCategoryAppsFragment.kt @@ -44,6 +44,7 @@ import io.timelimit.android.livedata.liveDataFromValue import io.timelimit.android.livedata.map import io.timelimit.android.livedata.switchMap import io.timelimit.android.logic.DefaultAppLogic +import io.timelimit.android.logic.DummyApps import io.timelimit.android.sync.actions.AddCategoryAppsAction import io.timelimit.android.ui.main.ActivityViewModel import io.timelimit.android.ui.main.getActivityViewModel @@ -147,6 +148,8 @@ class AddCategoryAppsFragment : DialogFragment() { val installedApps = realShowAppsFromAllDevices.switchMap { appsFromAllDevices -> if (appsFromAllDevices) appsAtAllDevices else appsAtAssignedDevices + }.map { list -> + if (list.isEmpty()) list else list + DummyApps.getApps(deviceId = list.first().deviceId, context = requireContext()) }.map { apps -> apps.distinctBy { app -> app.packageName } } val userRelatedDataLive = database.derivedDataDao().getUserRelatedDataLive(childId) diff --git a/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppAndRuleAdapter.kt b/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppAndRuleAdapter.kt index ed897c3..8c444cf 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppAndRuleAdapter.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppAndRuleAdapter.kt @@ -25,6 +25,7 @@ import io.timelimit.android.data.model.UsedTimeItem import io.timelimit.android.databinding.* import io.timelimit.android.extensions.MinuteOfDay import io.timelimit.android.logic.DefaultAppLogic +import io.timelimit.android.logic.DummyApps import io.timelimit.android.ui.manage.category.apps.AppAdapterHandlers import io.timelimit.android.ui.manage.category.timelimit_rules.TimeLimitRulesHandlers import io.timelimit.android.util.JoinUtil @@ -133,13 +134,15 @@ class AppAndRuleAdapter: RecyclerView.Adapter() { when (item) { is AppAndRuleItem.AppEntry -> { val binding = holder.itemView.tag as FragmentCategoryAppsItemBinding + val context = binding.root.context binding.item = item binding.handlers = handlers binding.executePendingBindings() binding.icon.setImageDrawable( - DefaultAppLogic.with(binding.root.context) + DummyApps.getIcon(item.packageNameWithoutActivityName, context) ?: + DefaultAppLogic.with(context) .platformIntegration.getAppIcon(item.packageNameWithoutActivityName) ) } diff --git a/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppsAndRulesModel.kt b/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppsAndRulesModel.kt index 3ecf1db..33ac108 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppsAndRulesModel.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/category/appsandrules/AppsAndRulesModel.kt @@ -26,6 +26,7 @@ import io.timelimit.android.extensions.takeDistributedElements import io.timelimit.android.livedata.map import io.timelimit.android.livedata.switchMap import io.timelimit.android.logic.DefaultAppLogic +import io.timelimit.android.logic.DummyApps import java.util.* class AppsAndRulesModel(application: Application): AndroidViewModel(application) { @@ -114,15 +115,18 @@ class AppsAndRulesModel(application: Application): AndroidViewModel(application) private val appsOfCategoryWithNames = installedApps.switchMap { allApps -> appsOfThisCategory.map { apps -> apps.map { categoryApp -> - categoryApp to allApps.find { app -> app.packageName == categoryApp.packageNameWithoutActivityName } + val title = DummyApps.getTitle(categoryApp.packageNameWithoutActivityName, getApplication()) ?: + allApps.find { app -> app.packageName == categoryApp.packageNameWithoutActivityName }?.title + + categoryApp to title } } } private val appEntries = appsOfCategoryWithNames.map { apps -> - apps.map { (app, appEntry) -> - if (appEntry != null) { - AppAndRuleItem.AppEntry(appEntry.title, app.packageName, app.packageNameWithoutActivityName) + apps.map { (app, title) -> + if (title != null) { + AppAndRuleItem.AppEntry(title, app.packageName, app.packageNameWithoutActivityName) } else { AppAndRuleItem.AppEntry("app not found", app.packageName, app.packageNameWithoutActivityName) } diff --git a/app/src/main/java/io/timelimit/android/ui/manage/child/apps/ChildAppsAdapter.kt b/app/src/main/java/io/timelimit/android/ui/manage/child/apps/ChildAppsAdapter.kt index fcba9a3..3404bb6 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/child/apps/ChildAppsAdapter.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/child/apps/ChildAppsAdapter.kt @@ -25,6 +25,7 @@ import io.timelimit.android.databinding.FragmentChildAppsItemBinding import io.timelimit.android.databinding.GenericBigListHeaderBinding import io.timelimit.android.databinding.GenericListHeaderBinding import io.timelimit.android.logic.DefaultAppLogic +import io.timelimit.android.logic.DummyApps import kotlin.properties.Delegates class ChildAppsAdapter: RecyclerView.Adapter() { @@ -101,10 +102,13 @@ class ChildAppsAdapter: RecyclerView.Adapter() { is ChildAppsApp -> { holder as AppHolder + val context = holder.binding.root.context + holder.binding.item = item.app holder.binding.currentCategoryTitle = item.shownCategoryName holder.binding.icon.setImageDrawable( - DefaultAppLogic.with(holder.binding.root.context).platformIntegration.getAppIcon(item.app.packageName) + DummyApps.getIcon(item.app.packageName, context) ?: + DefaultAppLogic.with(context).platformIntegration.getAppIcon(item.app.packageName) ) holder.binding.handlers = handlers holder.binding.executePendingBindings() diff --git a/app/src/main/res/mipmap-hdpi/ic_system_app.png b/app/src/main/res/mipmap-hdpi/ic_system_app.png new file mode 100644 index 0000000..81d22e6 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_system_app.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_system_app.png b/app/src/main/res/mipmap-mdpi/ic_system_app.png new file mode 100644 index 0000000..9df34e3 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_system_app.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_system_app.png b/app/src/main/res/mipmap-xhdpi/ic_system_app.png new file mode 100644 index 0000000..517dea5 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_system_app.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_system_app.png b/app/src/main/res/mipmap-xxhdpi/ic_system_app.png new file mode 100644 index 0000000..0f0dafa Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_system_app.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_system_app.png b/app/src/main/res/mipmap-xxxhdpi/ic_system_app.png new file mode 100644 index 0000000..78fb427 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_system_app.png differ diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 7bb6a76..a4bb6f8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1514,4 +1514,6 @@ %1$s hat angegeben, %2$s erledigt zu haben. Ist das richtig? Dafür wird es %1$s Extrazeit für %2$s geben Diese Aufgabe wurde zuletzt bestätigt am %s + + nicht zugeordnete Apps von der Systempartition diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a420de2..a47eb48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1567,4 +1567,6 @@ %1$s said that %2$s was finished. Is this correct? This will grant %1$s extra time for %2$s This task was confirmed last time at %s + + not assigned Apps from the system image