Add build info screen
This commit is contained in:
parent
5b9ce4d4ae
commit
779e28e217
@ -453,6 +453,8 @@
|
|||||||
<string name="preference_search_websites_summary">Vorschau einer Webseite anzeigen wenn die Suchanfrage eine URL ist</string>
|
<string name="preference_search_websites_summary">Vorschau einer Webseite anzeigen wenn die Suchanfrage eine URL ist</string>
|
||||||
<string name="preference_search_websearch">Websuchen</string>
|
<string name="preference_search_websearch">Websuchen</string>
|
||||||
<string name="preference_search_websearch_summary">Shortcuts zu verschiedenen Websuch-Engines anzeigen</string>
|
<string name="preference_search_websearch_summary">Shortcuts zu verschiedenen Websuch-Engines anzeigen</string>
|
||||||
|
<string name="preference_screen_buildinfo">Build-Information</string>
|
||||||
|
<string name="preference_screen_buildinfo_summary">Weitere Informationen über diesen Build dieser App</string>
|
||||||
|
|
||||||
<string name="preference_wikipedia_customurl">Wikipedia-URL</string>
|
<string name="preference_wikipedia_customurl">Wikipedia-URL</string>
|
||||||
|
|
||||||
|
|||||||
@ -489,6 +489,9 @@
|
|||||||
<item quantity="other">%1$d calendars selected</item>
|
<item quantity="other">%1$d calendars selected</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
<string name="preference_screen_buildinfo">Build information</string>
|
||||||
|
<string name="preference_screen_buildinfo_summary">More information about this build of this app</string>
|
||||||
|
|
||||||
<string name="preference_music_filter_sources">Restrict to music apps</string>
|
<string name="preference_music_filter_sources">Restrict to music apps</string>
|
||||||
<string name="preference_music_filter_sources_summary">Ignore media sessions of apps that are not music apps</string>
|
<string name="preference_music_filter_sources_summary">Ignore media sessions of apps that are not music apps</string>
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import de.mm20.launcher2.ui.settings.main.MainSettingsScreen
|
|||||||
import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen
|
import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen
|
import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen
|
import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen
|
||||||
|
import de.mm20.launcher2.ui.settings.buildinfo.BuildInfoSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen
|
import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen
|
import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.wikipedia.WikipediaSettingsScreen
|
import de.mm20.launcher2.ui.settings.wikipedia.WikipediaSettingsScreen
|
||||||
@ -120,6 +121,9 @@ class SettingsActivity : BaseActivity() {
|
|||||||
composable("settings/about") {
|
composable("settings/about") {
|
||||||
AboutSettingsScreen()
|
AboutSettingsScreen()
|
||||||
}
|
}
|
||||||
|
composable("settings/about/buildinfo") {
|
||||||
|
BuildInfoSettingsScreen()
|
||||||
|
}
|
||||||
composable("settings/debug") {
|
composable("settings/debug") {
|
||||||
DebugSettingsScreen()
|
DebugSettingsScreen()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,13 @@ fun AboutSettingsScreen() {
|
|||||||
title = stringResource(R.string.preference_version),
|
title = stringResource(R.string.preference_version),
|
||||||
summary = appVersion
|
summary = appVersion
|
||||||
)
|
)
|
||||||
|
Preference(
|
||||||
|
title = stringResource(R.string.preference_screen_buildinfo),
|
||||||
|
summary = stringResource(R.string.preference_screen_buildinfo_summary),
|
||||||
|
onClick = {
|
||||||
|
navController?.navigate("settings/about/buildinfo")
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
package de.mm20.launcher2.ui.settings.buildinfo
|
||||||
|
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Base64
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import de.mm20.launcher2.ui.BuildConfig
|
||||||
|
import de.mm20.launcher2.ui.R
|
||||||
|
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||||
|
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||||
|
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BuildInfoSettingsScreen() {
|
||||||
|
val viewModel: BuildInfoSettingsScreenVM = viewModel()
|
||||||
|
val context = LocalContext.current
|
||||||
|
PreferenceScreen(title = stringResource(R.string.preference_screen_buildinfo)) {
|
||||||
|
item {
|
||||||
|
Preference(title = "Build type", summary = BuildConfig.BUILD_TYPE)
|
||||||
|
var buildSignature by remember { mutableStateOf<String?>(null) }
|
||||||
|
LaunchedEffect(null) {
|
||||||
|
val signature = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
val pi = context.packageManager.getPackageInfo(
|
||||||
|
context.packageName,
|
||||||
|
PackageManager.GET_SIGNING_CERTIFICATES
|
||||||
|
)
|
||||||
|
pi.signingInfo.apkContentsSigners.firstOrNull()
|
||||||
|
} else {
|
||||||
|
val pi = context.packageManager.getPackageInfo(
|
||||||
|
context.packageName,
|
||||||
|
PackageManager.GET_SIGNATURES
|
||||||
|
)
|
||||||
|
pi.signatures.firstOrNull()
|
||||||
|
}
|
||||||
|
val signatureHash = if (signature != null) {
|
||||||
|
val digest = MessageDigest.getInstance("SHA")
|
||||||
|
digest.update(signature.toByteArray())
|
||||||
|
Base64.encodeToString(digest.digest(), Base64.NO_WRAP)
|
||||||
|
} else "null"
|
||||||
|
buildSignature = signatureHash
|
||||||
|
}
|
||||||
|
Preference(title = "Signature hash", summary = buildSignature)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
PreferenceCategory(title = "Features") {
|
||||||
|
for (feature in viewModel.buildFeatures) {
|
||||||
|
Preference(
|
||||||
|
title = feature.key,
|
||||||
|
summary = if (feature.value) "YES" else "NO"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package de.mm20.launcher2.ui.settings.buildinfo
|
||||||
|
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Base64
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.liveData
|
||||||
|
import de.mm20.launcher2.accounts.AccountType
|
||||||
|
import de.mm20.launcher2.accounts.AccountsRepository
|
||||||
|
import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider
|
||||||
|
import de.mm20.launcher2.weather.WeatherRepository
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
class BuildInfoSettingsScreenVM : ViewModel(), KoinComponent {
|
||||||
|
private val accountsRepository: AccountsRepository by inject()
|
||||||
|
private val weatherRepository: WeatherRepository by inject()
|
||||||
|
|
||||||
|
private val availableWeatherProviders = weatherRepository.getAvailableProviders()
|
||||||
|
|
||||||
|
val buildFeatures = mapOf(
|
||||||
|
"Accounts: Google" to accountsRepository.isSupported(AccountType.Google),
|
||||||
|
"Accounts: Microsoft" to accountsRepository.isSupported(AccountType.Microsoft),
|
||||||
|
"Weather providers: HERE" to availableWeatherProviders.contains(WeatherProvider.Here),
|
||||||
|
"Weather providers: Met No" to availableWeatherProviders.contains(WeatherProvider.MetNo),
|
||||||
|
"Weather providers: OpenWeatherMap" to availableWeatherProviders.contains(WeatherProvider.OpenWeatherMap),
|
||||||
|
"Weather providers: BrightSky" to availableWeatherProviders.contains(WeatherProvider.BrightSky),
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -2,13 +2,16 @@ package de.mm20.launcher2.weather
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.datastore.dataStore
|
|
||||||
import androidx.work.*
|
import androidx.work.*
|
||||||
import de.mm20.launcher2.database.AppDatabase
|
import de.mm20.launcher2.database.AppDatabase
|
||||||
import de.mm20.launcher2.permissions.PermissionGroup
|
import de.mm20.launcher2.permissions.PermissionGroup
|
||||||
import de.mm20.launcher2.permissions.PermissionsManager
|
import de.mm20.launcher2.permissions.PermissionsManager
|
||||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||||
import de.mm20.launcher2.preferences.Settings.WeatherSettings
|
import de.mm20.launcher2.preferences.Settings.WeatherSettings
|
||||||
|
import de.mm20.launcher2.weather.brightsky.BrightskyProvider
|
||||||
|
import de.mm20.launcher2.weather.here.HereProvider
|
||||||
|
import de.mm20.launcher2.weather.metno.MetNoProvider
|
||||||
|
import de.mm20.launcher2.weather.openweathermap.OpenWeatherMapProvider
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
@ -31,6 +34,8 @@ interface WeatherRepository {
|
|||||||
fun setAutoLocation(autoLocation: Boolean)
|
fun setAutoLocation(autoLocation: Boolean)
|
||||||
fun setLastLocation(lastLocation: WeatherLocation?)
|
fun setLastLocation(lastLocation: WeatherLocation?)
|
||||||
|
|
||||||
|
fun getAvailableProviders(): List<WeatherSettings.WeatherProvider>
|
||||||
|
|
||||||
fun selectProvider(provider: WeatherSettings.WeatherProvider)
|
fun selectProvider(provider: WeatherSettings.WeatherProvider)
|
||||||
|
|
||||||
val selectedProvider: Flow<WeatherSettings.WeatherProvider>
|
val selectedProvider: Flow<WeatherSettings.WeatherProvider>
|
||||||
@ -133,7 +138,7 @@ class WeatherRepositoryImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hasLocationPermission.collectLatest {
|
hasLocationPermission.collectLatest {
|
||||||
if(it) requestUpdate()
|
if (it) requestUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,11 +199,28 @@ class WeatherRepositoryImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getAvailableProviders(): List<WeatherSettings.WeatherProvider> {
|
||||||
|
val providers = mutableListOf<WeatherSettings.WeatherProvider>()
|
||||||
|
if (BrightskyProvider(context).isAvailable()) {
|
||||||
|
providers.add(WeatherSettings.WeatherProvider.BrightSky)
|
||||||
|
}
|
||||||
|
if (OpenWeatherMapProvider(context).isAvailable()) {
|
||||||
|
providers.add(WeatherSettings.WeatherProvider.OpenWeatherMap)
|
||||||
|
}
|
||||||
|
if (MetNoProvider(context).isAvailable()) {
|
||||||
|
providers.add(WeatherSettings.WeatherProvider.MetNo)
|
||||||
|
}
|
||||||
|
if (HereProvider(context).isAvailable()) {
|
||||||
|
providers.add(WeatherSettings.WeatherProvider.Here)
|
||||||
|
}
|
||||||
|
return providers
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WeatherUpdateWorker(val context: Context, params: WorkerParameters) :
|
class WeatherUpdateWorker(val context: Context, params: WorkerParameters) :
|
||||||
CoroutineWorker(context, params), KoinComponent {
|
CoroutineWorker(context, params), KoinComponent {
|
||||||
val repository: WeatherRepository by inject()
|
val repository: WeatherRepository by inject()
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
Log.d("MM20", "Requesting weather data")
|
Log.d("MM20", "Requesting weather data")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user