diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..f2b2897b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root=true + +[*.{kt,kts}] +charset=utf-8 +end_of_line=lf +insert_final_newline=false + +max_line_length=120 + +indent_size=2 +indent_style=space + +ij_kotlin_name_count_to_use_star_import=2147483647 +ij_kotlin_name_count_to_use_star_import_for_members=2147483647 +ij_kotlin_imports_layout=*,java.**,javax.**,kotlin.**,^ \ No newline at end of file diff --git a/.gitignore b/.gitignore index cb0d9ed2..a5f898a6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Built application files *.apk +*.aar *.ap_ *.aab @@ -58,42 +59,7 @@ captures/ # IntelliJ *.iml *.iws -.idea/artifacts -.idea/modules -.idea/modules.xml -.idea/workspace.xml -.idea/navEditor.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/libraries -.idea/caches -.idea/shelf -.idea/.name -.idea/compiler.xml -.idea/copyright/profiles_settings.xml -.idea/encodings.xml -.idea/misc.xml -.idea/scopes/scope_settings.xml -.idea/vcs.xml -.idea/jsLibraryMappings.xml -.idea/dataSources -.idea/datasources.xml -.idea/dataSources.local.xml -.idea/dataSources.ids -.idea/sqlDataSources.xml -.idea/dbnavigator.xml -.idea/dynamic.xml -.idea/uiDesigner.xml -.idea/usage.statistics.xml -.idea/contentModel.xml -.idea/kotlinc.xml -.idea/jarRepositories.xml -# optional -.idea/dictionaries -.idea/inspectionProfiles -.idea/runConfigurations -.idea/runConfigurations.xml +.idea/* # Keystore files *.jks diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index a5a6c41b..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 001ed074..7694e32e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ git: env: global: # for updates check https://developer.android.com/studio#downloads - - ANDROID_SDK_CMD_TOOLS=commandlinetools-linux-6825553_latest.zip + - ANDROID_SDK_CMD_TOOLS=commandlinetools-linux-7006259_latest.zip # storepass, keypass, keyalias - secure: K4PVOrcYr6ZV16GgZWcw5RGDqxRTrilMK6pjz1r+RkQX6EPywmTsUH0y8EGP44bZc+TFMM0UfGPulHfrKzC3LDVSe+CpvNdQqq8c2Ysc9lQLubvFmVlWZ2rjHhA3jtg33FDIAWipb41WZEdmCJE1EI+OMbh8p8/7cGZ4K4tpd3B8ViXrf16ht50C56glL1lS3Jog/g9OEIPdhzYF23nYPOAeV3xJg3WBGxUUMOwp3vrpMJ/bYvnh/XLHUpPWnCcSWhKZolE3C6Itlv3CUdCyd2u8dnbTFX7KK0g4nrJdXJAyith0aE2RB6APdDDIdZkF3p2qU3aWBWVvNzjGc6tYpP9OB8sjobcx9oG8lIaO09qZnM+fLTs5b3ulvl8d3UZI0KxgSocvjxpltrqeuNODGarzwIWAmjxKr3Qnfo5LFUna1UMxKJ1ARyT7zS9yUbfE6ek42aEe7rEaqryjNFE5X6b9D2WexN+68YynvdRfDXlFx2JIW3hWTi7AG4zBI0LKhhtruwLY1hKty3JR5/Dz/dIMW6JZUmLdE7drPmLNBcKRh1H778EOcaD+1q1bzVnwbA+HLfHkO9Rzmk7UOY1ttWzFBH23W/pI6D6mn4WTFng0/iOEsw7fwHaXPGv6ZXxserC/nzmeYb0AfK3wq2p2ztEDtbSblw9lkMBYlvNi5I8= - secure: SEcF7dl6ImTdeUYtw6dGeHRXbS4h8Ec9+Dnt2rFeobupo4e64818Fo10Uqqf+eM/5VVF2FAJLnEiq1SgfWZKjvUz9batJZNknc2JSKEGQPFaUD55USFCt2rxoLPFJKIee07kPTiXGPM2WWA+42cD+HpXAErMTd3BESsGwjni+xj2PhJuETDGrw+0D5T4TOXgd0uXNPl4p1PE+l3SejPqGQ961Wo+hbxd/y9JyZy/jZ9WW8XA6eEXXtecRY33NspwT58mBXDgZLIM/C3W0qfrGCiOPxwk0RpMo7YMbmYVPLG75AzihDtQ2F7P5edHz7v0yCAejrN23hi1LHb4Uku8tC2jzrH5eUpKfZuqap8DRcbdXq5je3oeuLSUu39FrzsDEmennS0eaD4jTsB5Sy2wld/UCmzV0QenUtPdBaFLU2Rxos3xJW4a2KyENRm5TGVNR/NAWpoacLed3zqDmb3K13WwskTGE1/mXRl+o0T0BVOBXuHXQ+nqATnGuAbw97LhhOeBZ/jA2yWBsaTxdjhB3E3uKWYZYdGIIgOwrZdM0RrVSgepg7NP+vh9iO70ckEzP+w4yws2ElKE3ZiOexEmrkFmqlxQW08b1FMaKJwpfsNiHkwW6u1jq1oeEBIzUrAMmo92uAjDAHKfn7FOsx5RVg20EKP9Rk9l2YKRA5dGJFI= diff --git a/README.md b/README.md index b84719eb..18172212 100644 --- a/README.md +++ b/README.md @@ -45,12 +45,6 @@ The main feature of the app is an 4x1 (horizontally resizable) homescreen widget * Written in Kotlin using Coroutines and Dagger * No internet permission -#### Planned Features -* Customize the displayed device data of the widget -* Allow changing the button shortcuts -* Show more information in the APK install view - * currently installed version, filepath, certificates ... - ## Release Notes Check out the [Release Notes](https://github.com/G00fY2/DeveloperWidget/releases) to find out what changed diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a7bd5283..4386e368 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,20 +1,21 @@ plugins { - id("com.android.application") - kotlin("android") - kotlin("kapt") - id("de.nanogiants.android-versioning") + id(Plugins.Android.application) + id(Plugins.Kotlin.android) + id(Plugins.Kotlin.kapt) + id(Plugins.Misc.androidVersioning) version Versions.androidVersioning } android { - compileSdkVersion(29) - buildToolsVersion = "30.0.2" + compileSdk = Versions.androidCompileSdk + buildToolsVersion = Versions.androidBuildTools defaultConfig { applicationId = "com.g00fy2.developerwidget" - minSdkVersion(14) - targetSdkVersion(29) + minSdk = Versions.androidMinSdk + targetSdk = Versions.androidTargetSdk versionCode = versioning.getVersionCode() versionName = versioning.getVersionName() + resourceConfigurations.add("en") vectorDrawables.useSupportLibrary = true setProperty("archivesBaseName", "developerwidget") } @@ -34,7 +35,7 @@ android { signingConfig = signingConfigs.getByName("release") isShrinkResources = true isMinifyEnabled = true - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } } buildFeatures { @@ -52,56 +53,42 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { + allWarningsAsErrors = true jvmTarget = JavaVersion.VERSION_1_8.toString() - useIR = true - } - lintOptions { - isCheckReleaseBuilds = false // TODO remove when https://issuetracker.google.com/issues/141126614 is fixed + freeCompilerArgs = freeCompilerArgs + arrayOf("-progressive") } dependenciesInfo { includeInApk = false } + packagingOptions.resources { + excludes += "DebugProbesKt.bin" + } } versioning { keepOriginalMappingFile = false } -repositories { - google() - mavenCentral() - jcenter { - content { - includeModule("com.g00fy2", "versioncompare") - includeModule("org.jetbrains.trove4j", "trove4j") // required by com.android.tools.lint:lint-gradle - } - } -} dependencies { - // Kotlin - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9") + implementation(Deps.Kotlin.coroutines) - // AndroidX - implementation("androidx.appcompat:appcompat:1.3.0-alpha02") - implementation("androidx.core:core-ktx:1.5.0-alpha04") - implementation("androidx.activity:activity:1.2.0-beta01") - implementation("androidx.fragment:fragment:1.3.0-beta01") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01") - implementation("androidx.recyclerview:recyclerview:1.2.0-alpha06") - implementation("androidx.constraintlayout:constraintlayout:2.0.2") - implementation("androidx.vectordrawable:vectordrawable:1.2.0-alpha02") + implementation(Deps.AndroidX.appcompat) + implementation(Deps.AndroidX.core) + implementation(Deps.AndroidX.activity) + implementation(Deps.AndroidX.fragment) + implementation(Deps.AndroidX.lifecycle) + implementation(Deps.AndroidX.recyclerView) + implementation(Deps.AndroidX.constraintLayout) + implementation(Deps.AndroidX.vectorDrawable) - // UI - implementation("com.google.android.material:material:1.3.0-alpha03") + implementation(Deps.UI.materialDesign) - // Misc - implementation("com.jakewharton.timber:timber:4.7.1") - implementation("com.g00fy2:versioncompare:1.3.5") + implementation(Deps.Misc.timber) + implementation(Deps.Misc.versionCompare) - // Dagger - implementation("com.google.dagger:dagger:2.29.1") - kapt("com.google.dagger:dagger-compiler:2.29.1") - implementation("com.google.dagger:dagger-android:2.29.1") - implementation("com.google.dagger:dagger-android-support:2.29.1") - kapt("com.google.dagger:dagger-android-processor:2.29.1") + implementation(Deps.Dagger.dagger) + kapt(Deps.Dagger.daggerCompiler) + implementation(Deps.Dagger.daggerAndroid) + implementation(Deps.Dagger.daggerAndroidSupport) + kapt(Deps.Dagger.daggerAndroidProcessor) } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro deleted file mode 100644 index ce2b2616..00000000 --- a/app/proguard-rules.pro +++ /dev/null @@ -1 +0,0 @@ -# Add project specific ProGuard rules here. \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dfcf9068..f8de68a2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,6 +36,7 @@ @@ -53,7 +54,9 @@ @@ -63,11 +66,13 @@ + android:screenOrientation="portrait" + android:theme="@style/AppTheme.CustomAnimation"/> @@ -82,7 +87,9 @@ android:taskAffinity="" android:theme="@android:style/Theme.Translucent.NoTitleBar"/> - + @@ -103,5 +110,4 @@ - - + \ No newline at end of file diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/about/AboutActivity.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/about/AboutActivity.kt index afa05e0b..38aa1718 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/about/AboutActivity.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/about/AboutActivity.kt @@ -125,10 +125,7 @@ class AboutActivity : BaseActivity(), AboutContract.AboutView { if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { binding.aboutRootScrollview.apply { doOnApplyWindowInsets { _, insets, padding, _ -> - updatePadding( - bottom = padding.bottom + WindowInsetsCompat.toWindowInsetsCompat(insets) - .getInsets(WindowInsetsCompat.Type.systemBars()).bottom - ) + updatePadding(bottom = padding.bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom) } viewTreeObserver.addOnScrollChangedListener { val scrollableRange = getChildAt(0).bottom - height + paddingBottom diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/controllers/StorageDirsControllerImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/controllers/StorageDirsControllerImpl.kt index 1c61d029..4a3bdd65 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/controllers/StorageDirsControllerImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/controllers/StorageDirsControllerImpl.kt @@ -21,10 +21,7 @@ class StorageDirsControllerImpl @Inject constructor() : StorageDirsController { @Named(ACTIVITY) lateinit var activity: BaseActivity - /** - * Return all storage directories. - * Inspired by AOSP (API 18) and the Amaze File Manager sourcecode - */ + // return all storage directories (inspired by AOSP API 18 and the Amaze File Manager sourcecode) override fun getStorageDirectories(): Collection { return mutableSetOf().apply { if (VERSION.SDK_INT < VERSION_CODES.M) { @@ -37,7 +34,9 @@ class StorageDirsControllerImpl @Inject constructor() : StorageDirsController { } @Suppress("DEPRECATION") - // TODO replace getExternalStorageDirectory calls when target API > 29 + // TODO getExternalStorageDirectory and requestLegacyExternalStorage only work with targetSdk <= 29 + // If we want to raise the targetSdk we would have to switch to Androids Scoped storage API, which doesn not + // offer access to all folders private fun getExtSdCardPathsDeprecated(): Collection { val dirs = mutableListOf() val rawExternalStorage = System.getenv("EXTERNAL_STORAGE") diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/dialogs/PermissionsAdapter.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/dialogs/PermissionsAdapter.kt index 84b7d1f2..2fd8ca78 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/dialogs/PermissionsAdapter.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/apkinstall/dialogs/PermissionsAdapter.kt @@ -2,12 +2,13 @@ package com.g00fy2.developerwidget.activities.apkinstall.dialogs import android.view.LayoutInflater import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil import com.g00fy2.developerwidget.activities.apkinstall.dialogs.PermissionsAdapter.PermissionViewHolder import com.g00fy2.developerwidget.base.BaseAdapter import com.g00fy2.developerwidget.base.BaseViewHolder import com.g00fy2.developerwidget.databinding.PermissionItemBinding -class PermissionsAdapter : BaseAdapter, PermissionViewHolder>(null) { +class PermissionsAdapter : BaseAdapter, PermissionViewHolder>(PermissionsDiffUtilsCallback()) { class PermissionViewHolder(val binding: PermissionItemBinding) : BaseViewHolder>(binding) { override fun onBind(item: Pair) { @@ -20,4 +21,10 @@ class PermissionsAdapter : BaseAdapter, PermissionViewHold override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PermissionViewHolder(PermissionItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)) +} + +class PermissionsDiffUtilsCallback : DiffUtil.ItemCallback>() { + + override fun areItemsTheSame(oldItem: Pair, newItem: Pair) = false + override fun areContentsTheSame(oldItem: Pair, newItem: Pair) = false } \ No newline at end of file diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/appmanager/AppsPresenterImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/appmanager/AppsPresenterImpl.kt index 43c8f5b1..e821c3c6 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/appmanager/AppsPresenterImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/appmanager/AppsPresenterImpl.kt @@ -17,10 +17,13 @@ class AppsPresenterImpl @Inject constructor() : BasePresenterImpl(), AppsContrac @Inject lateinit var view: AppsContract.AppsView + @Inject lateinit var appInfoBuilder: AppInfo.AppInfoBuilder + @Inject lateinit var intentController: IntentController + @Inject lateinit var widgetPreferenceController: WidgetPreferenceController diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/CreateShortcutActivity.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/CreateShortcutActivity.kt index 3ffb11a6..a077b814 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/CreateShortcutActivity.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/CreateShortcutActivity.kt @@ -62,10 +62,7 @@ class CreateShortcutActivity : BaseActivity(), CreateShortcutContract.CreateShor adapter.setOnShortcutSelected { shortcutPosition -> onItemClick(shortcutPosition) } if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { binding.root.doOnApplyWindowInsets { view, insets, padding, _ -> - view.updatePadding( - bottom = padding.bottom + WindowInsetsCompat.toWindowInsetsCompat(insets) - .getInsets(WindowInsetsCompat.Type.systemBars()).bottom - ) + view.updatePadding(bottom = padding.bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom) } } } diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutAdapter.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutAdapter.kt index 16d5c2dc..53bb37ba 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutAdapter.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutAdapter.kt @@ -5,6 +5,7 @@ import android.os.Build.VERSION_CODES import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.RequiresApi +import androidx.recyclerview.widget.DiffUtil import com.g00fy2.developerwidget.activities.shortcut.ShortcutAdapter.ShortcutViewHolder import com.g00fy2.developerwidget.base.BaseAdapter import com.g00fy2.developerwidget.base.BaseViewHolder @@ -34,3 +35,9 @@ class ShortcutAdapter : BaseAdapter(ShortcutDi this.onShortcutSelected = onShortcutSelected } } + +class ShortcutDiffUtilsCallback : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: ShortcutInfo, newItem: ShortcutInfo) = false + override fun areContentsTheSame(oldItem: ShortcutInfo, newItem: ShortcutInfo) = false +} diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutDiffUtilsCallback.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutDiffUtilsCallback.kt deleted file mode 100644 index 6823d138..00000000 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/shortcut/ShortcutDiffUtilsCallback.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.g00fy2.developerwidget.activities.shortcut - -import android.content.pm.ShortcutInfo -import androidx.recyclerview.widget.DiffUtil - -class ShortcutDiffUtilsCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ShortcutInfo, newItem: ShortcutInfo) = false - override fun areContentsTheSame(oldItem: ShortcutInfo, newItem: ShortcutInfo) = false -} \ No newline at end of file diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigActivity.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigActivity.kt index 81b1732e..f9f969d1 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigActivity.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigActivity.kt @@ -131,16 +131,10 @@ class WidgetConfigActivity : BaseActivity(), WidgetConfigContract.WidgetConfigVi binding.shareFab.setOnClickListener { presenter.shareDeviceData() } if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { binding.widgetConfigRootScrollview.doOnApplyWindowInsets { view, insets, padding, _ -> - view.updatePadding( - bottom = padding.bottom + WindowInsetsCompat.toWindowInsetsCompat(insets) - .getInsets(WindowInsetsCompat.Type.systemBars()).bottom - ) + view.updatePadding(bottom = padding.bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom) } binding.shareFab.doOnApplyWindowInsets { view, insets, _, margin -> - view.updateMargin( - bottom = margin.bottom + WindowInsetsCompat.toWindowInsetsCompat(insets) - .getInsets(WindowInsetsCompat.Type.systemBars()).bottom - ) + view.updateMargin(bottom = margin.bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom) } } } @@ -279,7 +273,7 @@ class WidgetConfigActivity : BaseActivity(), WidgetConfigContract.WidgetConfigVi putExtra(EXTRA_APPWIDGET_FROM_PIN_APP, true) putExtra(EXTRA_APPWIDGET_CUSTOM_DEVICE_NAME, binding.deviceTitleEdittextview.text.toString()) }, - PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) appWidgetManager.requestPinAppWidget( ComponentName(applicationContext, WidgetProviderImpl::class.java), diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigPresenterImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigPresenterImpl.kt index 7cb05e46..4c9e8b01 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigPresenterImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/activities/widgetconfig/WidgetConfigPresenterImpl.kt @@ -21,14 +21,19 @@ class WidgetConfigPresenterImpl @Inject constructor() : BasePresenterImpl(), @Inject lateinit var view: WidgetConfigContract.WidgetConfigView + @Inject lateinit var deviceDataSource: DeviceDataSource + @Inject lateinit var stringController: StringController + @Inject lateinit var widgetPreferenceController: WidgetPreferenceController + @Inject lateinit var toastController: ToastController + @Inject lateinit var intentController: IntentController diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseActivity.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseActivity.kt index 4440690d..6d79ae88 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseActivity.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseActivity.kt @@ -91,7 +91,6 @@ abstract class BaseActivity(private val isDialogActivity: Boolean = false) : Dag private fun initGestureNavigation() { if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { - // TODO check how to use API 30 features @Suppress("DEPRECATION") window.decorView.let { it.systemUiVisibility.let { flags -> @@ -102,10 +101,7 @@ abstract class BaseActivity(private val isDialogActivity: Boolean = false) : Dag findViewById(Window.ID_ANDROID_CONTENT)?.let { it.doOnApplyWindowInsets { view, insets, padding, _ -> - view.updatePadding( - top = padding.top + WindowInsetsCompat.toWindowInsetsCompat(insets) - .getInsets(WindowInsetsCompat.Type.systemBars()).top - ) + view.updatePadding(top = padding.top + insets.getInsets(WindowInsetsCompat.Type.systemBars()).top) } } } diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseAdapter.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseAdapter.kt index eb23df63..a92a2dc7 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseAdapter.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/base/BaseAdapter.kt @@ -3,8 +3,8 @@ package com.g00fy2.developerwidget.base import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter -abstract class BaseAdapter> constructor(diffCallback: DiffUtil.ItemCallback?) : - ListAdapter(diffCallback ?: EmptyDiffUtil()) { +abstract class BaseAdapter> constructor(diffCallback: DiffUtil.ItemCallback) : + ListAdapter(diffCallback) { private var commitCallback: Runnable? = null @@ -23,9 +23,4 @@ abstract class BaseAdapter> constructor(diffCallback: fun setCommitCallback(commitCallback: Runnable) { this.commitCallback = commitCallback } - - class EmptyDiffUtil : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: T, newItem: T) = false - override fun areContentsTheSame(oldItem: T, newItem: T) = false - } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/DayNightControllerImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/DayNightControllerImpl.kt index 4310446b..18fa1f48 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/DayNightControllerImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/DayNightControllerImpl.kt @@ -6,7 +6,6 @@ import android.os.Build.VERSION import android.os.Build.VERSION_CODES import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.edit -import com.g00fy2.developerwidget.R import com.g00fy2.developerwidget.di.annotations.APPLICATION import com.g00fy2.developerwidget.receiver.widget.WidgetProviderImpl import javax.inject.Inject @@ -17,8 +16,6 @@ class DayNightControllerImpl @Inject constructor() : DayNightController { @Inject @Named(APPLICATION) lateinit var context: Context - @Inject - lateinit var toastController: ToastController private val defaultMode = if (VERSION.SDK_INT >= VERSION_CODES.P) AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM else AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY @@ -38,8 +35,6 @@ class DayNightControllerImpl @Inject constructor() : DayNightController { AppCompatDelegate.MODE_NIGHT_NO -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM else -> AppCompatDelegate.MODE_NIGHT_YES }.let { - // TODO remove if https://issuetracker.google.com/issues/131851825 is fixed - if (VERSION.SDK_INT <= VERSION_CODES.M) toastController.showToast(R.string.day_night_issue) saveCustomDefaultMode(it) applyMode(it) updateWidgetTheme() diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/IntentControllerImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/IntentControllerImpl.kt index c451290f..b72c8487 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/IntentControllerImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/IntentControllerImpl.kt @@ -22,6 +22,7 @@ class IntentControllerImpl @Inject constructor() : IntentController { @Inject @Named(ACTIVITY) lateinit var activity: BaseActivity + @Inject lateinit var toastController: ToastController diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/WidgetPreferenceControllerImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/WidgetPreferenceControllerImpl.kt index f4820da0..6db2f096 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/WidgetPreferenceControllerImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/controllers/WidgetPreferenceControllerImpl.kt @@ -13,6 +13,7 @@ class WidgetPreferenceControllerImpl @Inject constructor() : WidgetPreferenceCon @Inject @Named(ACTIVITY) lateinit var activity: BaseActivity + @Inject @Named(WIDGET_ID) lateinit var widgetId: String diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/devicebuild/BuildDataProvider.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/devicebuild/BuildDataProvider.kt index 447927b2..60885a0f 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/devicebuild/BuildDataProvider.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/devicebuild/BuildDataProvider.kt @@ -1,16 +1,19 @@ package com.g00fy2.developerwidget.data.device.devicebuild -import android.annotation.SuppressLint import android.os.Build +import java.util.Locale object BuildDataProvider { - @SuppressLint("DefaultLocale") fun getCombinedDeviceName(): String { return if (Build.MODEL.contains(Build.MANUFACTURER, true)) { - Build.MODEL.capitalize() + Build.MODEL.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } } else { - Build.MANUFACTURER.capitalize() + " " + Build.MODEL.capitalize() + Build.MANUFACTURER.replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } + " " + Build.MODEL.replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } } } diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/system/SystemDataProvider.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/system/SystemDataProvider.kt index e4b3861c..ce1c32a6 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/system/SystemDataProvider.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/system/SystemDataProvider.kt @@ -1,9 +1,9 @@ package com.g00fy2.developerwidget.data.device.system -import android.annotation.SuppressLint import android.os.Build.VERSION import android.os.Build.VERSION_CODES -import com.g00fy2.versioncompare.Version +import io.github.g00fy2.versioncompare.Version +import java.util.Locale object SystemDataProvider { @@ -13,13 +13,12 @@ object SystemDataProvider { fun getCodename(): String = VERSION.CODENAME - @SuppressLint("DefaultLocale") fun getSDKLevel(): String { getCodename().let { return if (it.isBlank() || it.equals("REL", true)) { VERSION.SDK_INT.toString() } else { - it.toUpperCase() + it.uppercase(Locale.getDefault()) } } } diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/systemapps/SystemAppsDataProvider.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/systemapps/SystemAppsDataProvider.kt index ff0400b7..43df0710 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/systemapps/SystemAppsDataProvider.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/data/device/systemapps/SystemAppsDataProvider.kt @@ -7,7 +7,7 @@ import android.content.pm.PackageManager.NameNotFoundException import android.os.Build.VERSION import android.os.Build.VERSION_CODES import android.webkit.WebView -import com.g00fy2.versioncompare.Version +import io.github.g00fy2.versioncompare.Version object SystemAppsDataProvider { diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/di/ControllerModule.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/di/ControllerModule.kt index 8a693d2b..52ef2960 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/di/ControllerModule.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/di/ControllerModule.kt @@ -18,7 +18,6 @@ import com.g00fy2.developerwidget.di.annotations.ActivityScope import dagger.Binds import dagger.Module import dagger.Reusable -import javax.inject.Singleton @Module abstract class GlobalControllerModule { @@ -26,10 +25,6 @@ abstract class GlobalControllerModule { @Binds @Reusable abstract fun providesDayNightController(dayNightControllerImpl: DayNightControllerImpl): DayNightController - - @Binds - @Singleton - abstract fun provideToastController(toastControllerImpl: ToastControllerImpl): ToastController } @Module @@ -54,4 +49,8 @@ abstract class ActivityControllerModule { @Binds @ActivityScope abstract fun providePreferenceController(preferenceControllerImpl: PreferenceControllerImpl): PreferenceController + + @Binds + @ActivityScope + abstract fun provideToastController(toastControllerImpl: ToastControllerImpl): ToastController } \ No newline at end of file diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/ktx/ViewExtension.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/ktx/ViewExtension.kt index aa86ea9d..749d54ef 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/ktx/ViewExtension.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/ktx/ViewExtension.kt @@ -5,10 +5,11 @@ import android.os.Build.VERSION_CODES import android.util.TypedValue import android.view.View import android.view.ViewGroup -import android.view.WindowInsets import androidx.annotation.Px import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.core.view.marginBottom import androidx.core.view.marginLeft import androidx.core.view.marginRight @@ -37,10 +38,10 @@ fun View.updateMargin( } @RequiresApi(VERSION_CODES.KITKAT_WATCH) -fun View.doOnApplyWindowInsets(f: (View, WindowInsets, InitialPadding, InitialMargin) -> Unit) { +fun View.doOnApplyWindowInsets(f: (View, WindowInsetsCompat, InitialPadding, InitialMargin) -> Unit) { val initialPadding = recordInitialPaddingForView(this) val initialMargin = recordInitialMarginForView(this) - setOnApplyWindowInsetsListener { v, insets -> + ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets -> f(v, insets, initialPadding, initialMargin) insets } diff --git a/app/src/main/kotlin/com/g00fy2/developerwidget/receiver/widget/WidgetProviderImpl.kt b/app/src/main/kotlin/com/g00fy2/developerwidget/receiver/widget/WidgetProviderImpl.kt index 68963522..27b636a3 100644 --- a/app/src/main/kotlin/com/g00fy2/developerwidget/receiver/widget/WidgetProviderImpl.kt +++ b/app/src/main/kotlin/com/g00fy2/developerwidget/receiver/widget/WidgetProviderImpl.kt @@ -6,6 +6,8 @@ import android.appwidget.AppWidgetProvider import android.content.ComponentName import android.content.Context import android.content.Intent +import android.os.Build.VERSION +import android.os.Build.VERSION_CODES import android.util.SparseArray import android.widget.RemoteViews import androidx.appcompat.app.AppCompatDelegate @@ -23,6 +25,7 @@ import com.g00fy2.developerwidget.data.DeviceDataSource import com.g00fy2.developerwidget.data.DeviceDataSourceImpl import com.g00fy2.developerwidget.data.WidgetsPreferencesDataSource import dagger.android.AndroidInjection +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -34,14 +37,17 @@ class WidgetProviderImpl : AppWidgetProvider() { @Inject lateinit var deviceDataSource: DeviceDataSource + @Inject lateinit var widgetsPreferencesDataSource: WidgetsPreferencesDataSource + @Inject lateinit var dayNightController: DayNightController private lateinit var appWidgetManager: AppWidgetManager private lateinit var context: Context + @DelicateCoroutinesApi override fun onReceive(context: Context, intent: Intent) { AndroidInjection.inject(this, context) this.context = context @@ -71,6 +77,7 @@ class WidgetProviderImpl : AppWidgetProvider() { } } + @DelicateCoroutinesApi override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { GlobalScope.launch { withContext(Dispatchers.IO) { @@ -139,21 +146,27 @@ class WidgetProviderImpl : AppWidgetProvider() { putExtra(WidgetConfigActivity.EXTRA_APPWIDGET_UPDATE_EXISTING, true) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } - val configPendingIntent = - PendingIntent.getActivity(context, widgetId, configIntent, PendingIntent.FLAG_UPDATE_CURRENT) + val configPendingIntent = PendingIntent.getActivity(context, widgetId, configIntent, immutableUpdateCurrentFlags()) views.setOnClickPendingIntent(R.id.device_info_linearlayout, configPendingIntent) val appIntent = Intent(context, AppsActivity::class.java).apply { putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId) } - val appPendingIntent = - PendingIntent.getActivity(context, widgetId, appIntent, PendingIntent.FLAG_UPDATE_CURRENT) + val appPendingIntent = PendingIntent.getActivity(context, widgetId, appIntent, immutableUpdateCurrentFlags()) views.setOnClickPendingIntent(R.id.manage_apps_linearlayout, appPendingIntent) val apkIntent = Intent(context, ApkActivity::class.java) - val apkPendingIntent = PendingIntent.getActivity(context, widgetId, apkIntent, 0) + val apkPendingIntent = PendingIntent.getActivity(context, widgetId, apkIntent, immutableUpdateCurrentFlags()) views.setOnClickPendingIntent(R.id.install_apk_linearlayout, apkPendingIntent) } + private fun immutableUpdateCurrentFlags(): Int { + return if (VERSION.SDK_INT >= VERSION_CODES.M) { + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + } else { + PendingIntent.FLAG_UPDATE_CURRENT + } + } + companion object { const val UPDATE_WIDGET_MANUALLY_ACTION = BuildConfig.APPLICATION_ID + ".APPWIDGET_MANUAL_UPDATE" } diff --git a/app/src/main/res/anim-v21/anim_slide_in_from_left.xml b/app/src/main/res/anim-v21/anim_slide_in_from_left.xml new file mode 100644 index 00000000..f857bc2c --- /dev/null +++ b/app/src/main/res/anim-v21/anim_slide_in_from_left.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim-v21/anim_slide_in_from_right.xml b/app/src/main/res/anim-v21/anim_slide_in_from_right.xml new file mode 100644 index 00000000..a0926e2e --- /dev/null +++ b/app/src/main/res/anim-v21/anim_slide_in_from_right.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim-v21/anim_slide_out_to_left.xml b/app/src/main/res/anim-v21/anim_slide_out_to_left.xml new file mode 100644 index 00000000..99f06812 --- /dev/null +++ b/app/src/main/res/anim-v21/anim_slide_out_to_left.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim-v21/anim_slide_out_to_right.xml b/app/src/main/res/anim-v21/anim_slide_out_to_right.xml new file mode 100644 index 00000000..8b0ed188 --- /dev/null +++ b/app/src/main/res/anim-v21/anim_slide_out_to_right.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/anim_slide_in_from_left.xml b/app/src/main/res/anim/anim_slide_in_from_left.xml new file mode 100644 index 00000000..ebe41484 --- /dev/null +++ b/app/src/main/res/anim/anim_slide_in_from_left.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/anim_slide_in_from_right.xml b/app/src/main/res/anim/anim_slide_in_from_right.xml new file mode 100644 index 00000000..63877693 --- /dev/null +++ b/app/src/main/res/anim/anim_slide_in_from_right.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/anim_slide_out_to_left.xml b/app/src/main/res/anim/anim_slide_out_to_left.xml new file mode 100644 index 00000000..017a886c --- /dev/null +++ b/app/src/main/res/anim/anim_slide_out_to_left.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/anim_slide_out_to_right.xml b/app/src/main/res/anim/anim_slide_out_to_right.xml new file mode 100644 index 00000000..75fb5d0f --- /dev/null +++ b/app/src/main/res/anim/anim_slide_out_to_right.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night/ic_sad.xml b/app/src/main/res/drawable-night/ic_sad.xml index bd4c41aa..33e37e6e 100644 --- a/app/src/main/res/drawable-night/ic_sad.xml +++ b/app/src/main/res/drawable-night/ic_sad.xml @@ -14,4 +14,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable-v26/ic_settings_developement_shortcut.xml b/app/src/main/res/drawable-v26/ic_settings_developement_shortcut.xml index 56572220..cc491e1c 100644 --- a/app/src/main/res/drawable-v26/ic_settings_developement_shortcut.xml +++ b/app/src/main/res/drawable-v26/ic_settings_developement_shortcut.xml @@ -6,4 +6,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_app_icon_shape.xml b/app/src/main/res/drawable/bg_app_icon_shape.xml index a4deff24..e6d1c5c7 100644 --- a/app/src/main/res/drawable/bg_app_icon_shape.xml +++ b/app/src/main/res/drawable/bg_app_icon_shape.xml @@ -6,4 +6,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_circle_with_check.xml b/app/src/main/res/drawable/bg_circle_with_check.xml index 3ef438cc..db0d7542 100644 --- a/app/src/main/res/drawable/bg_circle_with_check.xml +++ b/app/src/main/res/drawable/bg_circle_with_check.xml @@ -3,4 +3,4 @@ android:shape="oval"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_inner_shape.xml b/app/src/main/res/drawable/bg_widget_inner_shape.xml index 8df00f71..669b3370 100644 --- a/app/src/main/res/drawable/bg_widget_inner_shape.xml +++ b/app/src/main/res/drawable/bg_widget_inner_shape.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_inner_shape_day.xml b/app/src/main/res/drawable/bg_widget_inner_shape_day.xml index 44ab65b9..1db58967 100644 --- a/app/src/main/res/drawable/bg_widget_inner_shape_day.xml +++ b/app/src/main/res/drawable/bg_widget_inner_shape_day.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_inner_shape_night.xml b/app/src/main/res/drawable/bg_widget_inner_shape_night.xml index e9061b42..d29e2e71 100644 --- a/app/src/main/res/drawable/bg_widget_inner_shape_night.xml +++ b/app/src/main/res/drawable/bg_widget_inner_shape_night.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_outer_shape.xml b/app/src/main/res/drawable/bg_widget_outer_shape.xml index 8eeca606..1dfa2143 100644 --- a/app/src/main/res/drawable/bg_widget_outer_shape.xml +++ b/app/src/main/res/drawable/bg_widget_outer_shape.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_outer_shape_day.xml b/app/src/main/res/drawable/bg_widget_outer_shape_day.xml index 4823e38a..626bb69d 100644 --- a/app/src/main/res/drawable/bg_widget_outer_shape_day.xml +++ b/app/src/main/res/drawable/bg_widget_outer_shape_day.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_widget_outer_shape_night.xml b/app/src/main/res/drawable/bg_widget_outer_shape_night.xml index 99817e62..75e84e05 100644 --- a/app/src/main/res/drawable/bg_widget_outer_shape_night.xml +++ b/app/src/main/res/drawable/bg_widget_outer_shape_night.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_privacy_logo.xml b/app/src/main/res/drawable/ic_privacy_logo.xml index e280fe8a..16b09ab9 100644 --- a/app/src/main/res/drawable/ic_privacy_logo.xml +++ b/app/src/main/res/drawable/ic_privacy_logo.xml @@ -9,4 +9,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml index 9f0bc3e0..6d24e7d6 100644 --- a/app/src/main/res/drawable/ic_share.xml +++ b/app/src/main/res/drawable/ic_share.xml @@ -6,4 +6,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 0908d04b..c9039385 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -180,4 +180,4 @@ /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_apk.xml b/app/src/main/res/layout/activity_apk.xml index 85fff135..bd5b88ce 100644 --- a/app/src/main/res/layout/activity_apk.xml +++ b/app/src/main/res/layout/activity_apk.xml @@ -152,4 +152,4 @@ app:layout_constraintTop_toBottomOf="@+id/recyclerview" style="@style/DialogButtonAppearance" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_apps.xml b/app/src/main/res/layout/activity_apps.xml index 4be3708f..38db3c67 100644 --- a/app/src/main/res/layout/activity_apps.xml +++ b/app/src/main/res/layout/activity_apps.xml @@ -223,4 +223,4 @@ style="@style/DialogButtonAppearance" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/appwidget_layout.xml b/app/src/main/res/layout/appwidget_layout.xml index 53183876..2f779c56 100644 --- a/app/src/main/res/layout/appwidget_layout.xml +++ b/app/src/main/res/layout/appwidget_layout.xml @@ -13,7 +13,7 @@ android:id="@+id/device_info_linearlayout" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_margin="4dp" + android:layout_margin="8dp" android:layout_weight="1" android:background="@drawable/bg_widget_inner_shape" android:gravity="center_vertical" @@ -66,10 +66,10 @@ @@ -131,6 +132,7 @@ android:maxLines="1" android:text="@string/install_apk" android:textColor="@color/widgetTextColor" + android:textSize="16dp" style="@style/TextAppearance.AppCompat.Subhead" /> diff --git a/app/src/main/res/layout/appwidget_layout_day.xml b/app/src/main/res/layout/appwidget_layout_day.xml index b61518a8..9709289a 100644 --- a/app/src/main/res/layout/appwidget_layout_day.xml +++ b/app/src/main/res/layout/appwidget_layout_day.xml @@ -13,7 +13,7 @@ android:id="@+id/device_info_linearlayout" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_margin="4dp" + android:layout_margin="8dp" android:layout_weight="1" android:background="@drawable/bg_widget_inner_shape_day" android:gravity="center_vertical" @@ -66,10 +66,10 @@ @@ -131,6 +132,7 @@ android:maxLines="1" android:text="@string/install_apk" android:textColor="@color/widgetTextColor_day" + android:textSize="16dp" style="@style/TextAppearance.AppCompat.Subhead" /> diff --git a/app/src/main/res/layout/appwidget_layout_night.xml b/app/src/main/res/layout/appwidget_layout_night.xml index a3782eed..78becbd8 100644 --- a/app/src/main/res/layout/appwidget_layout_night.xml +++ b/app/src/main/res/layout/appwidget_layout_night.xml @@ -13,7 +13,7 @@ android:id="@+id/device_info_linearlayout" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_margin="4dp" + android:layout_margin="8dp" android:layout_weight="1" android:background="@drawable/bg_widget_inner_shape_night" android:gravity="center_vertical" @@ -66,10 +66,10 @@ @@ -131,6 +132,7 @@ android:maxLines="1" android:text="@string/install_apk" android:textColor="@color/widgetTextColor_night" + android:textSize="16dp" style="@style/TextAppearance.AppCompat.Subhead" /> diff --git a/app/src/main/res/layout/appwidget_layout_placeholder.xml b/app/src/main/res/layout/appwidget_layout_placeholder.xml index 80b59bb5..3fdb6771 100644 --- a/app/src/main/res/layout/appwidget_layout_placeholder.xml +++ b/app/src/main/res/layout/appwidget_layout_placeholder.xml @@ -12,7 +12,7 @@ @@ -94,6 +95,7 @@ android:maxLines="1" android:text="@string/install_apk" android:textColor="@color/widgetTextColor" + android:textSize="16dp" style="@style/TextAppearance.AppCompat.Subhead" /> diff --git a/app/src/main/res/raw/keep.xml b/app/src/main/res/raw/keep.xml new file mode 100644 index 00000000..73aa6c87 --- /dev/null +++ b/app/src/main/res/raw/keep.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 8a469e66..4876a6e1 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -22,4 +22,4 @@ @color/nightGrey #33000000 @color/iconTintColor - + \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index 59c24f7c..db8d1597 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -1,17 +1,5 @@ - - - - - + - + \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 00000000..e5d40202 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v23/colors.xml b/app/src/main/res/values-v23/colors.xml index 0b50ed03..df8afc3e 100644 --- a/app/src/main/res/values-v23/colors.xml +++ b/app/src/main/res/values-v23/colors.xml @@ -1,4 +1,4 @@ @color/colorPrimary - + \ No newline at end of file diff --git a/app/src/main/res/values-v26/colors.xml b/app/src/main/res/values-v26/colors.xml index 77a1d6f5..be05c7f4 100644 --- a/app/src/main/res/values-v26/colors.xml +++ b/app/src/main/res/values-v26/colors.xml @@ -1,4 +1,4 @@ #A6FFFFFF - + \ No newline at end of file diff --git a/app/src/main/res/values-v29/colors.xml b/app/src/main/res/values-v29/colors.xml index 5400cbc3..8c7d68a3 100644 --- a/app/src/main/res/values-v29/colors.xml +++ b/app/src/main/res/values-v29/colors.xml @@ -2,4 +2,4 @@ @color/transparent @color/transparent - + \ No newline at end of file diff --git a/app/src/main/res/values/animations.xml b/app/src/main/res/values/animations.xml new file mode 100644 index 00000000..8e34473a --- /dev/null +++ b/app/src/main/res/values/animations.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index be13a37a..ad924ffa 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -52,4 +52,4 @@ @color/nightTextPrimary #1a73e8 - + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2cf715d9..acc5fc9e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,7 +63,6 @@ Show all %s apps Show all You have to manually add a new widget using your launcher. - You may need to restart the app to fully take effect. Share device data Potentially harmful app This app contains code that attempts to bypass Android\'s security protections. @@ -110,4 +109,4 @@ CPU Freq Google Play Service Version WebView Implementation - + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d4be6427..9753bc98 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,63 +1,10 @@ - - - - - - - + - - - - - + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..38df7b04 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index ecf136ee..de754a1f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,13 @@ +plugins { + id(Plugins.Android.application) version Versions.androidGradle apply false + kotlin(Plugins.Kotlin.androidGradle) version Versions.kotlin apply false + id(Plugins.Misc.gradleVersions) version Versions.gradleVersions +} + +tasks.dependencyUpdates.configure { + rejectVersionIf { Versions.maturityLevel(candidate.version) < Versions.maturityLevel(currentVersion) } +} + tasks.register("clean") { delete(buildDir) } \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 00000000..f55cb6b1 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt new file mode 100644 index 00000000..edd1378e --- /dev/null +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -0,0 +1,34 @@ +object Deps { + + object AndroidX { + const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}" + const val core = "androidx.core:core-ktx:${Versions.core}" + const val activity = "androidx.activity:activity:${Versions.activity}" + const val fragment = "androidx.fragment:fragment:${Versions.fragment}" + const val lifecycle = "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.lifecycle}" + const val recyclerView = "androidx.recyclerview:recyclerview:${Versions.recyclerView}" + const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}" + const val vectorDrawable = "androidx.vectordrawable:vectordrawable:${Versions.vectorDrawable}" + } + + object Kotlin { + const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}" + } + + object UI { + const val materialDesign = "com.google.android.material:material:${Versions.materialDesign}" + } + + object Misc { + const val timber = "com.jakewharton.timber:timber:${Versions.timber}" + const val versionCompare = "io.github.g00fy2:versioncompare:${Versions.versionCompare}" + } + + object Dagger { + const val dagger = "com.google.dagger:dagger:${Versions.dagger}" + const val daggerCompiler = "com.google.dagger:dagger-compiler:${Versions.dagger}" + const val daggerAndroid = "com.google.dagger:dagger-android:${Versions.dagger}" + const val daggerAndroidSupport = "com.google.dagger:dagger-android-support:${Versions.dagger}" + const val daggerAndroidProcessor = "com.google.dagger:dagger-android-processor:${Versions.dagger}" + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Plugins.kt b/buildSrc/src/main/kotlin/Plugins.kt new file mode 100644 index 00000000..7035eed1 --- /dev/null +++ b/buildSrc/src/main/kotlin/Plugins.kt @@ -0,0 +1,17 @@ +object Plugins { + + object Android { + const val application = "com.android.application" + } + + object Kotlin { + const val androidGradle = "android" + const val android = "kotlin-android" + const val kapt = "kotlin-kapt" + } + + object Misc { + const val androidVersioning = "de.nanogiants.android-versioning" + const val gradleVersions = "com.github.ben-manes.versions" + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt new file mode 100644 index 00000000..a71e1f33 --- /dev/null +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -0,0 +1,39 @@ +object Versions { + + const val androidMinSdk = 14 + const val androidCompileSdk = 29 + const val androidTargetSdk = 29 + + const val androidBuildTools = "31.0.0" + const val androidGradle = "7.0.0-rc01" + const val kotlin = "1.5.21" + + const val gradleVersions = "0.39.0" + const val androidVersioning = "2.4.0" + + const val coroutines = "1.5.1" + + const val appcompat = "1.3.1" + const val core = "1.6.0" + const val activity = "1.2.4" + const val fragment = "1.3.6" + const val lifecycle = "2.3.1" + const val recyclerView = "1.2.1" + const val constraintLayout = "2.1.0-rc01" + const val vectorDrawable = "1.1.0" + + const val materialDesign = "1.4.0" + + const val timber = "4.7.1" + const val versionCompare = "1.4.1" + + const val dagger = "2.38" + + fun maturityLevel(version: String): Int { + val levels = listOf("alpha", "beta", "m", "rc") + levels.forEachIndexed { index, s -> + if (version.matches(".*[.\\-]$s[.\\-\\d]*".toRegex(RegexOption.IGNORE_CASE))) return index + } + return levels.size + } +} \ No newline at end of file diff --git a/fastlane/metadata/android/de/full_description.txt b/fastlane/metadata/android/de/full_description.txt new file mode 100644 index 00000000..e6d7e364 --- /dev/null +++ b/fastlane/metadata/android/de/full_description.txt @@ -0,0 +1,8 @@ +

Developer Widget ist eine schlanke Android-Anwendung. Sie bietet ein Widget zur Anzeige von Gerätedaten, zum Verwalten installierter Apps sowie zur Auflistung lokal gespeicherter APK-Dateien.

+

Die App wurde von einem Entwickler für Entwickler erstellt. Vielleicht kennen Sie den Ärger, wenn auf mehreren physischen Geräten unterschiedliche Software läuft. Diese App hilft, wichtige Gerätedaten im Auge zu behalten und ermöglicht es, Apps und lokale APK-Dateien zu verwalten. Sie werden nie wieder Schwierigkeiten haben, APK-Dateien mit einem Dateibrowser zu finden oder auf einer benutzerdefinierten Hersteller-Benutzeroberfläche nach dem Menü für die Anwendungseinstellungen zu suchen.

+

Das Hauptmerkmal der App ist ein 4x1 (horizontal größenveränderbares) Homescreen-Widget, das dynamisch abgerufene Gerätedaten anzeigt und es ermöglicht, installierte Apps und lokale gespeicherte APK-Dateien zu durchsuchen.

+


Features:

    +
  • Homescreen-Widget mit anpassbarem Gerätenamen
  • +
  • Durchsuchen aller installierten (Nicht-System-)Apps und filtern nach Paketnamen
  • +
  • Verwalten lokale gespeicherter APK-Dateien
  • +
  • und mehr
diff --git a/fastlane/metadata/android/de/short_description.txt b/fastlane/metadata/android/de/short_description.txt new file mode 100644 index 00000000..516ee1b0 --- /dev/null +++ b/fastlane/metadata/android/de/short_description.txt @@ -0,0 +1 @@ +ein Open-Source-Toolset in modernem Design für Android-Entwickler \ No newline at end of file diff --git a/fastlane/metadata/android/de/title.txt b/fastlane/metadata/android/de/title.txt new file mode 100644 index 00000000..3d78fa39 --- /dev/null +++ b/fastlane/metadata/android/de/title.txt @@ -0,0 +1 @@ +Developer Widget - Tools für Android-Entwickler \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt new file mode 100644 index 00000000..de9e9928 --- /dev/null +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -0,0 +1,8 @@ +

Developer Widget is a lightweight Android app that offers a widget to show device data, manage installed apps and list locally stored APK files.

+

The app was built from a developer for developers. You may know the hassle of having multiple physical devices running different software. This app will help you keep track of important device information and allows you to organize your apps and local APK files. You will never again struggle to find APK files using a file browser or search for the app settings menu on a custom manufacturer UI.

+

The main feature of the app is an 4x1 (horizontally resizable) homescreen widget that shows dynamically fetched device data and allows you to browse your installed apps and local APK files.

+


Features include:

    +
  • Homescreen widget with customizable device name
  • +
  • Browse all installed (non system) apps and filter them by package name
  • +
  • Manage local APK files
  • +
  • and more
diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png new file mode 100644 index 00000000..bd243a5a Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt new file mode 100644 index 00000000..a0226446 --- /dev/null +++ b/fastlane/metadata/android/en-US/short_description.txt @@ -0,0 +1 @@ +modern design, open source toolset for Android Developers \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt new file mode 100644 index 00000000..5024a378 --- /dev/null +++ b/fastlane/metadata/android/en-US/title.txt @@ -0,0 +1 @@ +Developer Widget - a toolset for Android Developers \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a375ce61..819eed90 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,3 @@ -# Versions used for dependency resolution in settings.gradle.kts -kotlinVersion=1.4.10 -androidGradlePluginVersion=4.2.0-alpha13 -nanogiantsVersioning=2.4.0 -gradleEnterpriseVersion=3.4.1 - # Allow usage of AndroidX instead of the old support libraries. android.useAndroidX=true # Use R8 in full mode instead of ProGuard compatibility mode. @@ -12,9 +6,7 @@ android.enableR8.fullMode=true # instead of declarations plus all transitive dependency references. android.nonTransitiveRClass=true # Generate the compile time only R class using the app's local resources -android.enableAppCompileTimeRClass=true -# Enable supported AAPT2 optimize suboperations (ResourceObfuscation, SparseResourceEncoding, ResourcePathShortening) as -# an effort to reduce APK size. -android.enableResourceOptimizations=true +# Currently not working: https://issuetracker.google.com/issues/182198793 +# android.enableAppCompileTimeRClass=true # Set the build VMs heap size. org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c0..7454180f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8c6ce341..af7be50b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-rc-4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c..744e882e 100755 --- a/gradlew +++ b/gradlew @@ -72,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) diff --git a/settings.gradle.kts b/settings.gradle.kts index d910d6c7..08408a59 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,29 +1,28 @@ include("app") pluginManagement { - val kotlinVersion: String by settings - val androidGradlePluginVersion: String by settings - val nanogiantsVersioning: String by settings - val gradleEnterpriseVersion: String by settings repositories { google() gradlePluginPortal() - mavenCentral() } resolutionStrategy { eachPlugin { - when (requested.id.id) { - "com.android.application" -> useModule("com.android.tools.build:gradle:$androidGradlePluginVersion") - "de.nanogiants.android-versioning" -> useVersion(nanogiantsVersioning) - "com.gradle.enterprise" -> useVersion(gradleEnterpriseVersion) - } - if (requested.id.namespace == "org.jetbrains.kotlin") useVersion(kotlinVersion) + if (requested.id.namespace == "com.android") useModule("com.android.tools.build:gradle:${requested.version}") } } } +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + plugins { - id("com.gradle.enterprise") + id("com.gradle.enterprise") version "3.6.3" } gradleEnterprise {