From 971f05ec8e0b13864cd9ec825a7aa2c123e68f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Garc=C3=ADa?= Date: Fri, 9 Oct 2020 18:51:07 +0200 Subject: [PATCH 1/8] General library improvements --- .github/ISSUE_TEMPLATE/bug_report.md | 20 ++-- .gitignore | 10 +- .idea/codeStyles/Project.xml | 134 +++++++++++++++++++++++++++ .idea/vcs.xml | 6 -- README.md | 84 ++++++++++++----- app/build.gradle | 68 +++++++++++--- build.gradle | 12 +-- gradle/properties_utils.gradle | 89 ++++++++++++++++++ lib/build.gradle | 53 +++++++---- 9 files changed, 398 insertions(+), 78 deletions(-) create mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/vcs.xml create mode 100644 gradle/properties_utils.gradle diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e164d73..14e551f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,16 +1,22 @@ --- name: Bug report -about: Create a report to help us improve +about: Create a bug report to help us improve title: '' labels: bug assignees: adriangl --- -**Device and SW details (please complete the following information):** - - Device: [e.g. Google Pixel 3] - - OS: [e.g. Android 9] - - Library Version [e.g. 1.0.0] +**Device and SW details** +- Device: [e.g. Google Pixel 3] +- OS: [e.g. Android 9] +- Library Version [e.g. 1.0.0] + +**Conditions for the library to work** +- [ ] I have set the package name of the app to **exactly** the one I'd like to test in-app updates with. +- [ ] I have signed the app with the same key that I used to sign the app I want to test in-app updates with. +- [ ] I've ensured that any of my Google accounts in my test device has access to said app in Google Play Store. +- [ ] The Google Play Store displays updates for the app I want to use to test in-app updates with. **Summary and background of the bug** A clear and concise description of what the bug is. @@ -18,8 +24,8 @@ A clear and concise description of what the bug is. **Steps to reproduce** Steps to reproduce the behavior: 1. Go to '...' -2. Click on '....' -3. Scroll down to '....' +2. Click on '...' +3. Scroll down to '...' 4. See error Also attach notes or stack traces if applicable. diff --git a/.gitignore b/.gitignore index 6a02cb8..b361ee7 100644 --- a/.gitignore +++ b/.gitignore @@ -40,10 +40,10 @@ captures/ .idea/dictionaries .idea/libraries .idea/caches -.idea/codeStyles .idea/modules.xml .idea/misc.xml .idea/jarRepositories.xml +.idea/vcs.xml # Keystore files *.jks @@ -57,4 +57,10 @@ google-services.json # Freeline freeline.py freeline/ -freeline_project_description.json \ No newline at end of file +freeline_project_description.json + +# Signing configurations +app_config.properties + +# Application ID configurations +app_id.properties \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..0d15693 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 367fdaf..c4ab95c 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,12 @@ This utility library aims to help Android developers to use the [Google Play In-App Updates API](https://developer.android.com/guide/app-bundle/in-app-updates) in an easy way. -**It's highly encouraged that you first read the [Google Play In-App Updates API](https://developer.android.com/guide/app-bundle/in-app-updates) documentation before using this library in order to understand the core concepts of the library.** +> It's highly encouraged that you first read the [Google Play In-App Updates API](https://developer.android.com/guide/app-bundle/in-app-updates) documentation before using this library in order to understand the core concepts of the library. -## Installation -Add the following dependencies to your main `build.gradle`: +## Setting Up +In your main `build.gradle`, add [jitpack.io](https://jitpack.io/) repository in the `allprojects` block: + +
Groovy ```groovy allprojects { repositories { @@ -14,24 +16,39 @@ allprojects { } } ``` +
-Add the following dependencies to your app's `build.gradle`: - -* For Gradle < 4.0 - ```groovy - dependencies { - compile "com.github.bq:android-app-updates-helper:1.0.2" +
Kotlin +```kotlin +allprojects { + repositories { + maven(url = "https://jitpack.io") } - ``` +} +``` +
-* For Gradle 4.0+ - ```groovy - dependencies { - implementation "com.github.bq:android-app-updates-helper:1.0.2" - } - ``` -## Example usage +Add the following dependencies to your app or library's `build.gradle`: + +
Groovy +```groovy +dependencies { + implementation "com.github.bq:android-app-updates-helper:1.0.2" +} +``` +
+ + +
Kotlin +```kotlin +dependencies { + implementation("com.github.bq:android-app-updates-helper:1.0.2") +} +``` +
+ +## How to use * Create a new _AppUpdatesHelper_. * Start listening for app update changes with _AppUpdatesHelper.startListening()_, for example in _onCreate()_. * Stop listening for app update changes with _AppUpdatesHelper.stopListening()_ in _onDestroy()_. @@ -41,18 +58,37 @@ Add the following dependencies to your app's `build.gradle`: Check the [example app](app) for more implementation details about [flexible](app/src/main/kotlin/com/bq/appupdateshelper/flexible/FlexibleUpdateActivity.kt) and [immediate](app/src/main/kotlin/com/bq/appupdateshelper/immediate/ImmediateUpdateActivity.kt) updates. -If you use the example app, don't forget the following things when testing: -* Change the package name of the example app to the one you'd like to test in-app updates with. -* Sign the example app with the same keys that you used to sign the app you want to test in-app updates with. -* If the app is not published yet, or you want to test with internal app sharing or closed tracks, ensure that any of your Google accounts in your device has access to said app in Google Play Store. - You can also use a [fake implementation](app/src/main/kotlin/com/bq/appupdateshelper/fake/FakeUpdateActivity.kt) to test in-app updates. +Keep in mind that you may not see in-app updates if these conditions don't match: +* The package name of the app is **exactly** the one you'd like to test in-app updates with. +* The app must be signed with the same keys that you used to sign the app you want to test in-app updates with. +* If the app is not published yet or you want to test with internal app sharing or closed tracks, +ensure that any of your Google accounts in your device has access to said app in Google Play Store. +* Check if the Google Play Store displays updates for the app you want to use to test in-app updates. + +Please ensure that all conditions apply when using this library in order to avoid unnecessary headaches. + +### Using the example app +In order to ease using the example app with the sample data of your own app, +you can create an `app_config.properties` file in the root of the project with the following content: +```properties +applicationId=your.application.id +keystorePath=/full/path/to/your/keystore/file +keystorePwd=your_keystore_password +keystoreAlias=your_keystore_alias +keystoreAliasPwd=your_keystore_alias_password +``` + +These values will be picked up by the compilation process of the example app +and will set the application ID and signing configurations for you. + ## Authors & Collaborators -* [Adrián García](https://github.com/adriangl) - Author and maintainer -* [Daniel Sánchez Ceinos](https://github.com/danielceinos) - Contributor +* **[Adrián García](https://github.com/adriangl)** - *Author and maintainer* +* **[Daniel Sánchez Ceinos](https://github.com/danielceinos)** - *Contributor* ## License +This project is licensed under the Apache Software License, Version 2.0. ``` Copyright (C) 2019 BQ diff --git a/app/build.gradle b/app/build.gradle index 9620f0c..79516ca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,21 +21,65 @@ apply plugin: 'kotlin-android-extensions' apply plugin: 'com.gladed.androidgitversion' +apply from: "$rootDir/gradle/properties_utils.gradle" + +ext { + /* + ******************** + * Android variables + ******************** + */ + compile_sdk_version = 30 + min_sdk_version = 21 + target_sdk_version = 30 + build_tools_version = "30.0.2" +} + android { - compileSdkVersion project.ext.compileSdkVersion + compileSdkVersion compile_sdk_version + buildToolsVersion build_tools_version defaultConfig { - applicationId "com.bq.appupdateshelper" // Fake, replace with your own - minSdkVersion project.ext.minSdkVersion - targetSdkVersion project.ext.targetSdkVersion + /* + * Change your application ID to the app you want to test with + * + * Requires configuration via app_config.properties file or injected via environment variables. + * The loadEnvOrProperty will try to find the environment variable (in snake_case) or the + * property in signing.properties (converted to camelCase) + */ + applicationId loadEnvOrProperty("APPLICATION_ID", "/", "app_config.properties") + minSdkVersion min_sdk_version + targetSdkVersion target_sdk_version versionCode 1 versionName androidGitVersion.name() testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + + signingConfigs { + /* + * Local release signing configuration + * + * Requires configuration via app_config.properties file or injected via environment variables. + * The loadEnvOrProperty will try to find the environment variable (in snake_case) or the + * property in signing.properties (converted to camelCase) + */ + localRelease { + storeFile file(loadEnvOrProperty("KEYSTORE_PATH", "/", "app_config.properties")) + storePassword loadEnvOrProperty("KEYSTORE_PWD", "", "app_config.properties") + keyAlias loadEnvOrProperty("KEYSTORE_ALIAS", "", "app_config.properties") + keyPassword loadEnvOrProperty("KEYSTORE_ALIAS_PWD", "", "app_config.properties") + } + } + buildTypes { + debug { + signingConfig signingConfigs.localRelease + } + release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.localRelease } } @@ -48,15 +92,15 @@ dependencies { implementation project(":lib") implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.core:core-ktx:1.0.2' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.constraintlayout:constraintlayout:2.0.2' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13' - androidTestImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - implementation 'com.google.android.material:material:1.0.0' + androidTestImplementation 'androidx.test:runner:1.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.google.android.material:material:1.2.1' } diff --git a/build.gradle b/build.gradle index 9b6895f..a945c1f 100644 --- a/build.gradle +++ b/build.gradle @@ -17,17 +17,17 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlinVersion = '1.4.10' + ext.kotlin_version = "1.4.10" repositories { google() jcenter() mavenCentral() - maven {url "https://plugins.gradle.org/m2/"} + maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.android.tools.build:gradle:4.0.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath 'com.android.tools.build:gradle:4.0.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" classpath "com.gladed.androidgitversion:gradle-android-git-version:0.4.13" } @@ -40,9 +40,7 @@ allprojects { } ext { - compileSdkVersion = 29 - minSdkVersion = 21 - targetSdkVersion = 29 + kotlin_version = "1.4.10" } } diff --git a/gradle/properties_utils.gradle b/gradle/properties_utils.gradle new file mode 100644 index 0000000..6fe07ae --- /dev/null +++ b/gradle/properties_utils.gradle @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 BQ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Utility method that loads a Properties object from a given file name. + * + * @param fileName name of the properties file + * @return a Properties object, empty if the file could not be loaded + */ +def loadPropertiesFile(fileName) { + try { + Properties properties = new Properties() + properties.load(new FileInputStream(rootProject.file(fileName))) + + return properties + } + catch (ignored) { + logger.info("File \"$fileName\" not found, returning empty properties object") + return new Properties() + } +} + +/** + * Utility method that tries to find a variable in the following places: + * - System environment variable + * - Property in a properties file (the property will try to find the name in camel case) + * + * System environment property takes precedence over the property in a properties file. + * + * @param key Key to find in snake case + * @param defaultValue Default value in case the key is not found, null by default + * @param propertiesFileName file in the root of the project to check for properties. If not defined, + * it will default to the project's gradle.properties + */ +def loadEnvOrProperty(String key, defaultValue = null, String propertiesFileName = "gradle.properties") { + def envVarKey = key + def propertyKey = toCamelCase(key) + + logger.info("Trying to find environment variable \"$envVarKey\" (or $propertiesFileName property \"$propertyKey\")") + + // First try to get the value from the environment variable + def result = System.getenv(envVarKey) + + if (result == null) { + logger.info("Environment variable \"$envVarKey\" not found, trying to find it in $propertiesFileName property \"$propertyKey\"") + + // Then try to get it from the properties file + def properties = loadPropertiesFile(propertiesFileName) + + if (properties == null) { + // If none could be found, return the default value + logger.error("Requested file $propertiesFileName not found, returning default value") + return defaultValue + } + + result = properties[propertyKey] + } + + if (result == null) { + logger.error("Environment variable \"$envVarKey\" (or $propertiesFileName property \"$propertyKey\") not found, returning default value") + return defaultValue + } + else { + return result + } +} + +static String toCamelCase(String text, boolean capitalized = false) { + def newText = text.toLowerCase().replaceAll("(_)([A-Za-z0-9])", { Object[] it -> it[2].toUpperCase() }) + return capitalized ? capitalize(newText) : newText +} + +ext { + loadPropertiesFile = this.&loadPropertiesFile + loadEnvOrProperty = this.&loadEnvOrProperty +} \ No newline at end of file diff --git a/lib/build.gradle b/lib/build.gradle index f713937..fcd1213 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 BQ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + apply plugin: 'com.android.library' apply plugin: "com.gladed.androidgitversion" @@ -7,12 +23,25 @@ androidGitVersion { tagPattern(/^[0-9]+.*/) // Tag names should follow the pattern MM.NN.PP } +ext { + /* + ******************** + * Android variables + ******************** + */ + compile_sdk_version = 30 + min_sdk_version = 21 + target_sdk_version = 30 + build_tools_version = "30.0.2" +} + android { - compileSdkVersion 30 + compileSdkVersion compile_sdk_version + buildToolsVersion = build_tools_version defaultConfig { - minSdkVersion 21 - targetSdkVersion 30 + minSdkVersion min_sdk_version + targetSdkVersion target_sdk_version versionName androidGitVersion.name() versionCode androidGitVersion.code() @@ -35,7 +64,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' // Needed for the in-app updates API - api "com.google.android.play:core:1.8.0" + api "com.google.android.play:core:1.8.2" testImplementation 'junit:junit:4.13' @@ -43,22 +72,6 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' } -/* - * Copyright (C) 2019 BQ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - // Build a jar with source files task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs From 9b0a86d0a4daf0f458988ad6db6196ace2549c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Garc=C3=ADa?= Date: Fri, 9 Oct 2020 20:10:07 +0200 Subject: [PATCH 2/8] Add client version staleness. Rework views of example app to use viewBinding --- .gitignore | 7 +-- app/build.gradle | 4 ++ app/src/main/AndroidManifest.xml | 10 ++-- .../MainActivity.kt | 23 +++++--- .../fake/FakeUpdateActivity.kt | 46 ++++++++------- .../flexible/FlexibleUpdateActivity.kt | 43 ++++++++------ .../immediate/ImmediateUpdateActivity.kt | 31 +++++----- .../misc/ActivityExtensions.kt | 2 +- ...ke_update.xml => fake_update_activity.xml} | 2 +- ...pdate.xml => flexible_update_activity.xml} | 2 +- ...date.xml => immediate_update_activity.xml} | 2 +- .../{activity_main.xml => main_activity.xml} | 2 +- .../appupdateshelper/AppUpdateInfoResult.java | 58 +++++++++++++------ 13 files changed, 138 insertions(+), 94 deletions(-) rename app/src/main/kotlin/com/bq/{appupdateshelper => appupdateshelper_app}/MainActivity.kt (68%) rename app/src/main/kotlin/com/bq/{appupdateshelper => appupdateshelper_app}/fake/FakeUpdateActivity.kt (83%) rename app/src/main/kotlin/com/bq/{appupdateshelper => appupdateshelper_app}/flexible/FlexibleUpdateActivity.kt (85%) rename app/src/main/kotlin/com/bq/{appupdateshelper => appupdateshelper_app}/immediate/ImmediateUpdateActivity.kt (89%) rename app/src/main/kotlin/com/bq/{appupdateshelper => appupdateshelper_app}/misc/ActivityExtensions.kt (97%) rename app/src/main/res/layout/{activity_fake_update.xml => fake_update_activity.xml} (96%) rename app/src/main/res/layout/{activity_flexible_update.xml => flexible_update_activity.xml} (96%) rename app/src/main/res/layout/{activity_immediate_update.xml => immediate_update_activity.xml} (96%) rename app/src/main/res/layout/{activity_main.xml => main_activity.xml} (97%) diff --git a/.gitignore b/.gitignore index b361ee7..6a19dcf 100644 --- a/.gitignore +++ b/.gitignore @@ -59,8 +59,5 @@ freeline.py freeline/ freeline_project_description.json -# Signing configurations -app_config.properties - -# Application ID configurations -app_id.properties \ No newline at end of file +# App configuration properties +app_config.properties \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 79516ca..e244207 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,10 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures { + viewBinding true + } + signingConfigs { /* * Local release signing configuration diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 46626ac..ff33085 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.bq.appupdateshelper_app"> - + - + - + - + diff --git a/app/src/main/kotlin/com/bq/appupdateshelper/MainActivity.kt b/app/src/main/kotlin/com/bq/appupdateshelper_app/MainActivity.kt similarity index 68% rename from app/src/main/kotlin/com/bq/appupdateshelper/MainActivity.kt rename to app/src/main/kotlin/com/bq/appupdateshelper_app/MainActivity.kt index 7ad5ed2..e240e25 100644 --- a/app/src/main/kotlin/com/bq/appupdateshelper/MainActivity.kt +++ b/app/src/main/kotlin/com/bq/appupdateshelper_app/MainActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 BQ + * Copyright (C) 2020 BQ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,28 +14,33 @@ * limitations under the License. */ -package com.bq.appupdateshelper +package com.bq.appupdateshelper_app import android.os.Bundle import android.widget.Button import androidx.appcompat.app.AppCompatActivity -import com.bq.appupdateshelper.fake.FakeUpdateActivity -import com.bq.appupdateshelper.flexible.FlexibleUpdateActivity -import com.bq.appupdateshelper.immediate.ImmediateUpdateActivity +import com.bq.appupdateshelper_app.databinding.MainActivityBinding +import com.bq.appupdateshelper_app.fake.FakeUpdateActivity +import com.bq.appupdateshelper_app.flexible.FlexibleUpdateActivity +import com.bq.appupdateshelper_app.immediate.ImmediateUpdateActivity class MainActivity : AppCompatActivity() { + private lateinit var binding: MainActivityBinding + private val immediateButton: Button - get() = findViewById(R.id.immediate_button) + get() = binding.immediateButton private val flexibleButton: Button - get() = findViewById(R.id.flexible_button) + get() = binding.flexibleButton private val fakeButton: Button - get() = findViewById(R.id.fake_button) + get() = binding.fakeButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + binding = MainActivityBinding.inflate(layoutInflater).apply { + setContentView(root) + } immediateButton.setOnClickListener { startActivity(ImmediateUpdateActivity.newIntent(this)) diff --git a/app/src/main/kotlin/com/bq/appupdateshelper/fake/FakeUpdateActivity.kt b/app/src/main/kotlin/com/bq/appupdateshelper_app/fake/FakeUpdateActivity.kt similarity index 83% rename from app/src/main/kotlin/com/bq/appupdateshelper/fake/FakeUpdateActivity.kt rename to app/src/main/kotlin/com/bq/appupdateshelper_app/fake/FakeUpdateActivity.kt index 3ccbfc5..a1fd3aa 100644 --- a/app/src/main/kotlin/com/bq/appupdateshelper/fake/FakeUpdateActivity.kt +++ b/app/src/main/kotlin/com/bq/appupdateshelper_app/fake/FakeUpdateActivity.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bq.appupdateshelper.fake +package com.bq.appupdateshelper_app.fake import android.content.Context import android.content.Intent @@ -26,8 +26,9 @@ import androidx.appcompat.app.AppCompatActivity import com.bq.appupdateshelper.AppUpdateInfoResult import com.bq.appupdateshelper.AppUpdateInstallState.Status.* import com.bq.appupdateshelper.FakeAppUpdatesHelper -import com.bq.appupdateshelper.R -import com.bq.appupdateshelper.misc.showToast +import com.bq.appupdateshelper_app.databinding.FakeUpdateActivityBinding +import com.bq.appupdateshelper_app.R +import com.bq.appupdateshelper_app.misc.showToast import com.google.android.material.snackbar.Snackbar /** @@ -48,12 +49,17 @@ class FakeUpdateActivity : AppCompatActivity() { private lateinit var fakeAppUpdatesHelper: FakeAppUpdatesHelper + private lateinit var binding: FakeUpdateActivityBinding + private val startUpdateButton: Button - get() = findViewById(R.id.start_update_button) + get() = binding.startUpdateButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_fake_update) + + binding = FakeUpdateActivityBinding.inflate(layoutInflater).apply { + setContentView(root) + } setTitle(R.string.activity_fake_update_title) @@ -86,16 +92,16 @@ class FakeUpdateActivity : AppCompatActivity() { DOWNLOADED -> { showToast("The update has been downloaded!") - Snackbar.make(findViewById(android.R.id.content), "Install the update?", Snackbar.LENGTH_INDEFINITE) - .apply { - setAction("Install") { - fakeAppUpdatesHelper.completeUpdate() + Snackbar.make(binding.root, "Install the update?", Snackbar.LENGTH_INDEFINITE) + .apply { + setAction("Install") { + fakeAppUpdatesHelper.completeUpdate() - // Fake installation process - fakeAppUpdatesHelper.completeFakeUpdate() + // Fake installation process + fakeAppUpdatesHelper.completeFakeUpdate() + } } - } - .show() + .show() } INSTALLING -> { showToast("The update is being installed!") @@ -106,13 +112,13 @@ class FakeUpdateActivity : AppCompatActivity() { FAILED -> { showToast("The update failed! Reason: ${installState.errorCode}") - Snackbar.make(findViewById(android.R.id.content), "Retry?", Snackbar.LENGTH_LONG) - .apply { - setAction("Retry") { - fakeAppUpdatesHelper.startImmediateUpdate(this@FakeUpdateActivity) + Snackbar.make(binding.root, "Retry?", Snackbar.LENGTH_LONG) + .apply { + setAction("Retry") { + fakeAppUpdatesHelper.startImmediateUpdate(this@FakeUpdateActivity) + } } - } - .show() + .show() } CANCELED -> { showToast("The user canceled the flexible update!") @@ -161,7 +167,7 @@ class FakeUpdateActivity : AppCompatActivity() { } } else { showToast("The update info could not be retrieved, " + - "cause: ${appUpdateInfoResult.exception!!.message}") + "cause: ${appUpdateInfoResult.exception!!.message}") } } } diff --git a/app/src/main/kotlin/com/bq/appupdateshelper/flexible/FlexibleUpdateActivity.kt b/app/src/main/kotlin/com/bq/appupdateshelper_app/flexible/FlexibleUpdateActivity.kt similarity index 85% rename from app/src/main/kotlin/com/bq/appupdateshelper/flexible/FlexibleUpdateActivity.kt rename to app/src/main/kotlin/com/bq/appupdateshelper_app/flexible/FlexibleUpdateActivity.kt index d85d41d..ae59091 100644 --- a/app/src/main/kotlin/com/bq/appupdateshelper/flexible/FlexibleUpdateActivity.kt +++ b/app/src/main/kotlin/com/bq/appupdateshelper_app/flexible/FlexibleUpdateActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 BQ + * Copyright (C) 2020 BQ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bq.appupdateshelper.flexible +package com.bq.appupdateshelper_app.flexible import android.content.Context import android.content.Intent @@ -25,8 +25,9 @@ import androidx.appcompat.app.AppCompatActivity import com.bq.appupdateshelper.AppUpdateInfoResult import com.bq.appupdateshelper.AppUpdateInstallState.Status.* import com.bq.appupdateshelper.AppUpdatesHelper -import com.bq.appupdateshelper.R -import com.bq.appupdateshelper.misc.showToast +import com.bq.appupdateshelper_app.databinding.FlexibleUpdateActivityBinding +import com.bq.appupdateshelper_app.R +import com.bq.appupdateshelper_app.misc.showToast import com.google.android.material.snackbar.Snackbar /** @@ -44,12 +45,16 @@ class FlexibleUpdateActivity : AppCompatActivity() { private lateinit var appUpdatesHelper: AppUpdatesHelper + private lateinit var binding: FlexibleUpdateActivityBinding + private val startUpdateButton: Button - get() = findViewById(R.id.start_update_button) + get() = binding.startUpdateButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_flexible_update) + binding = FlexibleUpdateActivityBinding.inflate(layoutInflater).apply { + setContentView(root) + } setTitle(R.string.activity_flexible_update_title) @@ -89,13 +94,13 @@ class FlexibleUpdateActivity : AppCompatActivity() { showToast("The update has been downloaded!") // Prompt the user to install the update when we know that the update has been // downloaded successfully - Snackbar.make(findViewById(android.R.id.content), "Install the update?", Snackbar.LENGTH_INDEFINITE) - .apply { - setAction("Install") { - appUpdatesHelper.completeUpdate() + Snackbar.make(binding.root, "Install the update?", Snackbar.LENGTH_INDEFINITE) + .apply { + setAction("Install") { + appUpdatesHelper.completeUpdate() + } } - } - .show() + .show() } INSTALLING -> { showToast("The update is being installed!") @@ -111,13 +116,13 @@ class FlexibleUpdateActivity : AppCompatActivity() { // process if needed showToast("The update failed! Reason: ${installState.errorCode}") - Snackbar.make(findViewById(android.R.id.content), "Retry?", Snackbar.LENGTH_LONG) - .apply { - setAction("Retry") { - appUpdatesHelper.startFlexibleUpdate(this@FlexibleUpdateActivity) + Snackbar.make(binding.root, "Retry?", Snackbar.LENGTH_LONG) + .apply { + setAction("Retry") { + appUpdatesHelper.startFlexibleUpdate(this@FlexibleUpdateActivity) + } } - } - .show() + .show() } CANCELED -> { // This state is only reachable in flexible updates and it happens when the @@ -167,7 +172,7 @@ class FlexibleUpdateActivity : AppCompatActivity() { } } else { showToast("The update info could not be retrieved, " + - "cause: ${appUpdateInfoResult.exception!!.message}") + "cause: ${appUpdateInfoResult.exception!!.message}") } } } diff --git a/app/src/main/kotlin/com/bq/appupdateshelper/immediate/ImmediateUpdateActivity.kt b/app/src/main/kotlin/com/bq/appupdateshelper_app/immediate/ImmediateUpdateActivity.kt similarity index 89% rename from app/src/main/kotlin/com/bq/appupdateshelper/immediate/ImmediateUpdateActivity.kt rename to app/src/main/kotlin/com/bq/appupdateshelper_app/immediate/ImmediateUpdateActivity.kt index 1badca6..1c73c98 100644 --- a/app/src/main/kotlin/com/bq/appupdateshelper/immediate/ImmediateUpdateActivity.kt +++ b/app/src/main/kotlin/com/bq/appupdateshelper_app/immediate/ImmediateUpdateActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 BQ + * Copyright (C) 2020 BQ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bq.appupdateshelper.immediate +package com.bq.appupdateshelper_app.immediate import android.content.Context import android.content.Intent @@ -25,8 +25,9 @@ import androidx.appcompat.app.AppCompatActivity import com.bq.appupdateshelper.AppUpdateInfoResult import com.bq.appupdateshelper.AppUpdateInstallState.Status.* import com.bq.appupdateshelper.AppUpdatesHelper -import com.bq.appupdateshelper.R -import com.bq.appupdateshelper.misc.showToast +import com.bq.appupdateshelper_app.databinding.ImmediateUpdateActivityBinding +import com.bq.appupdateshelper_app.R +import com.bq.appupdateshelper_app.misc.showToast import com.google.android.material.snackbar.Snackbar /** @@ -44,12 +45,16 @@ class ImmediateUpdateActivity : AppCompatActivity() { private lateinit var appUpdatesHelper: AppUpdatesHelper + private lateinit var binding: ImmediateUpdateActivityBinding + private val startUpdateButton: Button - get() = findViewById(R.id.start_update_button) + get() = binding.startUpdateButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_immediate_update) + binding = ImmediateUpdateActivityBinding.inflate(layoutInflater).apply { + setContentView(root) + } setTitle(R.string.activity_immediate_update_title) @@ -104,13 +109,13 @@ class ImmediateUpdateActivity : AppCompatActivity() { // process if needed showToast("The update failed! Reason: ${installState.errorCode}") - Snackbar.make(findViewById(android.R.id.content), "Retry?", Snackbar.LENGTH_LONG) - .apply { - setAction("Retry") { - appUpdatesHelper.startImmediateUpdate(this@ImmediateUpdateActivity) + Snackbar.make(binding.root, "Retry?", Snackbar.LENGTH_LONG) + .apply { + setAction("Retry") { + appUpdatesHelper.startImmediateUpdate(this@ImmediateUpdateActivity) + } } - } - .show() + .show() } CANCELED -> { // This state is only reachable in flexible updates. @@ -160,7 +165,7 @@ class ImmediateUpdateActivity : AppCompatActivity() { } } else { showToast("The update info could not be retrieved, " + - "cause: ${appUpdateInfoResult.exception!!.message}") + "cause: ${appUpdateInfoResult.exception!!.message}") } } } diff --git a/app/src/main/kotlin/com/bq/appupdateshelper/misc/ActivityExtensions.kt b/app/src/main/kotlin/com/bq/appupdateshelper_app/misc/ActivityExtensions.kt similarity index 97% rename from app/src/main/kotlin/com/bq/appupdateshelper/misc/ActivityExtensions.kt rename to app/src/main/kotlin/com/bq/appupdateshelper_app/misc/ActivityExtensions.kt index 6ffac4e..5923ba5 100644 --- a/app/src/main/kotlin/com/bq/appupdateshelper/misc/ActivityExtensions.kt +++ b/app/src/main/kotlin/com/bq/appupdateshelper_app/misc/ActivityExtensions.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bq.appupdateshelper.misc +package com.bq.appupdateshelper_app.misc import android.app.Activity import android.widget.Toast diff --git a/app/src/main/res/layout/activity_fake_update.xml b/app/src/main/res/layout/fake_update_activity.xml similarity index 96% rename from app/src/main/res/layout/activity_fake_update.xml rename to app/src/main/res/layout/fake_update_activity.xml index eb85412..a1eda58 100644 --- a/app/src/main/res/layout/activity_fake_update.xml +++ b/app/src/main/res/layout/fake_update_activity.xml @@ -21,7 +21,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_height="match_parent" android:layout_width="match_parent" - tools:context="com.bq.appupdateshelper.fake.FakeUpdateActivity" + tools:context="com.bq.appupdateshelper_app.fake.FakeUpdateActivity" tools:ignore="HardcodedText">