Skip to main content

Android v26.11.0

Compatibility​

NameVersionImplementation
Compile SDK36compileSdk = q2libs.versions.compileSdk.get()
Target SDK36targetSdk = q2libs.versions.targetSdk.get()
Min SDK29minSdk = q2libs.versions.minSdk.get()
Java / JVM21javaVersion = q2libs.versions.javaVersion
Gradle9.4.1gradle-wrapper.properties
Android Gradle Plugin9.1.0id(q2libs.plugins.android.application)
Kotlin Gradle Plugin2.3.20(built into AGP 9; no explicit plugin alias)
KSP2.3.6id(q2libs.plugins.ksp)
Google Services Plugin4.4.2id(q2libs.plugins.google.services)
Kotlin Serialization2.3.20id(q2libs.plugins.kotlin.serialization)

No toolchain bumps in this release. The table above is unchanged from 26.10.0.

Migration from 26.10.0 to 26.11.0​

Doing a multi-version migration?

If you're jumping more than 2–3 versions at once, walking each version's migration notes individually can be tedious and error-prone. Consider the Large Version Migrations guide instead. It walks you through replacing your local DevApp with a fresh copy at the target tag and dropping your module back in, which atomically picks up every scaffolding change at once.

Nothing in this release breaks compilation, and no sdk_interfaces signature changed. One change can affect release builds only, so read the keep-rule section below even if your module builds and runs cleanly in debug.

Action required: verify your module in a minified release build​

The consumer ProGuard/R8 rules that sdk_interfaces and Core ship to your app are now much narrower. Earlier versions kept far more than the host needed, and some modules came to depend on that by accident. A module that did will still pass every debug test and then fail in a release build with ClassNotFoundException, NoSuchMethodException, or a Gson model whose fields come back null.

Module classes. The -keep class * implements <module interface> { public *; } rules for SecurityModule, LifecycleModule, AuthenticationModule, UIModule, PushReceiverModule, NotificationModule, and DeepLinkModule are gone. MethodModule and CameraModule implementers still keep public *, because the host looks up their methods by name. For every other module type, one rule now keeps only what the host calls by reflection:

-keep class * implements com.q2.sdk_interfaces.SDKModule {
public <init>(com.q2.sdk_interfaces.SdkUtils);
public static *** getInstance(com.q2.sdk_interfaces.SdkUtils);
}

Methods that implement a Q2 interface are still kept, because they override a kept interface method. Any other public member on your module class is no longer kept on your behalf. The zero-argument <init>() and getInstance() forms are no longer kept either. The host never called them, since it always passes SdkUtils.

App-wide rules removed from Core. These matched classes in every module, including yours:

Removed ruleDepend on it if your module…
-keep class **.R and -keep class **.R$* { <fields>; }reads R fields by reflection
-keepclassmembers class * { static final String *; }reads constants by reflection or by field name
-keep class **.web.** { *; }has a package named web that Gson or reflection uses
-keep public class * extends android.support.v4.** {*;}still extends a support-library class

If any of these apply, add the narrowest rule that covers your own classes to your module's consumer-rules.pro. Don't copy the old blanket rules back. Then build a minified release variant and exercise the module end to end before you submit it. See Consumer ProGuard Rules.


New SDK interface documentation​

AuthenticationModule is now a documented module type​

AuthenticationModule lets a module replace Q2's login screen with its own. The host shows your fragment on launch, after logout, and on UUX timeout. Your fragment hands the login result back, and Q2 takes over the session from there.

The interface and the com.q2.morannon.auth facade it pairs with shipped in 26.10.0. They are unchanged in 26.11.0 and are now documented as a supported module type:

implementation "com.q2.msdk:sdk_interfaces:$q2Version"
implementation "com.q2.morannon:morannon:$q2Version"
class PartnerAuthModule internal constructor(
private val sdkUtils: SdkUtils,
private val auth: Q2Login,
) : AuthenticationModule {

constructor(sdkUtils: SdkUtils) : this(sdkUtils, Q2Authentication)

override fun showAuthenticationFragment(): Fragment = PartnerLoginFragment()

override fun onLoginFailed(fragment: Fragment?, errorMessage: String) { … }
}
  • Q2Login authenticates against Q2. It covers password login, biometric login and enrollment, remembered users, maintenance status, and the pre-login notice. No member throws. Failures come back as values.
  • Fragment.completeQ2Login(result) hands the result to the host.
  • Q2SessionCredentials is a thread-safe holder for the password that biometric enrollment needs. Clear it from clearCachedCredentials().

Only one authentication module may be enabled at a time. The class must declare AuthenticationModule directly, not inherit it from a base class, or the host falls back to Q2's login screen without an error. See Authentication Module Interface for the full contract, registration rules, biometrics flow, and limitations.

The members added to AuthenticationModule in 26.10.0 (supportsBiometrics, clearCachedCredentials, postQ2LoginResult, and the documented logOut contract) are covered on the same page. See the 26.10.0 release notes for when each was introduced.


Other changes affecting modules​

MethodModule callback payloads are now JSON-escaped​

Core now serializes the callModule response, and every error payload, with Gson before passing it to the web app. Before this, a returnValue string or an exception message that contained an apostrophe or a quote broke out of the JavaScript literal the bridge builds. The web app then received nothing.

No module-side change is required. The web app sees the same decoded values as before. callModule now also rejects a methodName that is not a valid Java identifier with missingRequiredParameters, rather than attempting the lookup. A real method name always passes.

Over-browser renders framed PDFs in place​

When content opened in the over-browser (presentUrl(url, WebNavigationTarget.OVER_BROWSER)) embeds a PDF in an <iframe>, the over-browser now renders it with a bundled PDF viewer. It no longer leaves a blank frame or closes on the download. No module-side change is required.


Version Updates​

No public library, plugin, or toolchain versions changed in this release. The version catalog is identical to 26.10.0.


Version Catalog​

AndroidX Libraries​

LibraryVersionImplementation
AndroidX Core KTX1.12.0implementation(q2libs.androidx.core.ktx)
AndroidX AppCompat1.6.1implementation(q2libs.androidx.appcompat)
AndroidX Activity KTX1.8.1implementation(q2libs.androidx.activity.ktx)
AndroidX Legacy Support1.0.0implementation(q2libs.androidx.legacy.support)
AndroidX Constraint Layout2.1.4implementation(q2libs.androidx.constraintlayout)
AndroidX CardView1.0.0implementation(q2libs.androidx.cardview)
AndroidX Local Broadcast Manager1.1.0implementation(q2libs.androidx.localbroadcastmanager)
AndroidX Percent Layout1.0.0implementation(q2libs.androidx.percentlayout)
AndroidX Biometric1.1.0implementation(q2libs.androidx.biometric)
AndroidX RecyclerView1.3.2implementation(q2libs.androidx.recyclerview)
AndroidX WebKit1.14.0implementation(q2libs.androidx.webkit)
AndroidX Media1.6.0implementation(q2libs.androidx.media)
AndroidX Browser1.8.0implementation(q2libs.androidx.browser)
AndroidX Grid Layout1.0.0implementation(q2libs.androidx.gridlayout)
AndroidX Preference1.2.1implementation(q2libs.androidx.preference)
AndroidX Security Crypto1.1.0-beta01implementation(q2libs.androidx.security.crypto)
AndroidX ExifInterface1.4.2implementation(q2libs.androidx.exifinterface)
AndroidX Credentials (ref only)1.6.0(catalog version pin; no library alias yet)

AndroidX Fragment​

LibraryVersionImplementation
AndroidX Fragment1.7.0implementation(q2libs.androidx.fragment)
AndroidX Fragment KTX1.7.0implementation(q2libs.androidx.fragment.ktx)

AndroidX Navigation​

LibraryVersionImplementation
AndroidX Navigation Fragment KTX2.7.4implementation(q2libs.androidx.navigation.fragment.ktx)
AndroidX Navigation UI KTX2.7.4implementation(q2libs.androidx.navigation.ui.ktx)
AndroidX Navigation Compose2.8.9implementation(q2libs.androidx.navigation.compose)

AndroidX Lifecycle​

LibraryVersionImplementation
AndroidX Lifecycle Runtime KTX2.7.0implementation(q2libs.androidx.lifecycle.runtime.ktx)
AndroidX Lifecycle ViewModel KTX2.7.0implementation(q2libs.androidx.lifecycle.viewmodel.ktx)
AndroidX Lifecycle Process2.7.0implementation(q2libs.androidx.lifecycle.process)
AndroidX Lifecycle Compiler2.7.0ksp(q2libs.androidx.lifecycle.compiler)
AndroidX Lifecycle Extensions2.2.0 (Deprecated)implementation(q2libs.androidx.lifecycle.extensions)
AndroidX Lifecycle ViewModel Compose2.7.0implementation(q2libs.androidx.lifecycle.viewmodel.compose)

AndroidX Room​

LibraryVersionImplementation
Room Runtime2.8.4implementation(q2libs.androidx.room.runtime)
Room Compiler2.8.4ksp(q2libs.androidx.room.compiler)
Room KTX2.8.4implementation(q2libs.androidx.room.ktx)

AndroidX CameraX​

LibraryVersionImplementation
CameraX Camera21.5.0implementation(q2libs.androidx.camera.camera2)
CameraX Lifecycle1.5.0implementation(q2libs.androidx.camera.lifecycle)
Camera View1.5.0implementation(q2libs.androidx.camera.view)

AndroidX Compose​

LibraryVersionImplementation
Compose BOM2025.12.01implementation(platform(q2libs.androidx.compose.bom))
Compose Foundation-implementation(q2libs.androidx.compose.foundation)
Compose UI-implementation(q2libs.androidx.compose.ui)
Compose UI Graphics-implementation(q2libs.androidx.compose.ui.graphics)
Compose UI Tooling-implementation(q2libs.androidx.compose.ui.tooling)
Compose UI Tooling Preview-implementation(q2libs.androidx.compose.ui.tooling.preview)
Compose UI Test Manifest-implementation(q2libs.androidx.compose.ui.test.manifest)
Compose UI Test JUnit4-implementation(q2libs.androidx.compose.ui.test.junit4)
Compose Runtime LiveData-implementation(q2libs.androidx.compose.runtime.livedata)
Material Icons Core-implementation(q2libs.material.icons.core)
Material3-implementation(q2libs.material3)
Material3 Adaptive-implementation(q2libs.androidx.compose.material3.adpative)
Activity Compose1.8.2implementation(q2libs.activity.compose)

Google Libraries​

LibraryVersionImplementation
Material1.10.0implementation(q2libs.google.material)
GSON2.10.1implementation(q2libs.google.gson)
Play Services Vision20.1.3 (Deprecated)implementation(q2libs.google.play.services.vision)
ZXing Core3.5.1implementation(q2libs.google.zxing.core)
Age Signals0.0.4implementation(q2libs.google.age.signals)

Firebase​

LibraryVersionImplementation
Firebase Messaging23.3.0implementation(q2libs.google.firebase.messaging)
Firebase Messaging KTX23.3.0implementation(q2libs.google.firebase.messaging.ktx)
Firebase Instance ID21.1.0implementation(q2libs.google.firebase.iid)
Firebase Core21.1.1implementation(q2libs.google.firebase.core)
Firebase Crashlytics Build Tools2.9.9implementation(q2libs.google.firebase.crashlytics.buildtools)

Kotlin & Jetbrains​

LibraryVersionImplementation
Kotlinx Coroutines1.7.3implementation(q2libs.jetbrains.kotlinx.coroutines)
Kotlinx Serialization JSON1.11.0implementation(q2libs.kotlinx.serialization)
Jetbrains Annotations20.1.0implementation(q2libs.jetbrains.annotations)

Networking​

LibraryVersionImplementation
Retrofit22.9.0implementation(q2libs.retrofit2.retrofit)
Retrofit2 Converter GSON2.9.0implementation(q2libs.retrofit2.converter.gson)
Retrofit2 RxJava Adapter2.1.0implementation(q2libs.retrofit2.adapter.rxjava)
OkHttp34.10.0implementation(q2libs.okhttp3.okhttp)
OkHttp3 Logging Interceptor4.10.0implementation(q2libs.okhttp3.logging.interceptor)
RxAndroid1.2.0implementation(q2libs.reactivex.rxandroid)
Volley1.2.1implementation(q2libs.volley)

Dependency Injection​

LibraryVersionImplementation
Dagger2.59.2implementation(q2libs.dagger)
Dagger Compiler2.59.2ksp(q2libs.dagger.compiler)
Hilt2.59.2implementation(q2libs.hilt)
Hilt Compiler2.59.2ksp(q2libs.hilt.compiler)
Hilt Navigation Compose1.2.0implementation(q2libs.androidx.hilt.navigation.compose)
Glassfish Annotation10.0-b28implementation(q2libs.glassfish.annotation)

Dependency Injection (Koin)​

LibraryVersionImplementation
Koin Android3.4.3implementation(q2libs.koin.android)
Koin Core3.4.3implementation(q2libs.koin.core)
Koin AndroidX Compose3.5.0implementation(q2libs.koin.androidx.compose)

Third-Party Libraries​

LibraryVersionImplementation
EventBus3.3.1implementation(q2libs.eventbus)
EventBus Processor3.3.1ksp(q2libs.eventbus.processor)
Commons IO2.6implementation(q2libs.commons.io)
Picasso2.8implementation(q2libs.picasso)
Coil Compose2.7.0implementation(q2libs.coil)
Coil View2.7.0implementation(q2libs.coil.view)
Timber5.0.1implementation(q2libs.timber)
Apache Commons Imaging1.0-alpha2implementation(q2libs.apache.commons.imaging)

Q2 SDK Components​

LibraryCoordVersionImplementation
Q2 SDK Interfacescom.q2.msdk:sdk_interfacesq2Versionimplementation project(':sdk_interfaces')
Q2 UI Componentscom.q2:ui-components0.1.1implementation(q2libs.q2.ui.components)
Q2 Routing Service(local project, unpublished)q2Versionimplementation project(':modules:q2_routing_service')

Plugin Declarations​

PluginIDImplementation
Android Applicationcom.android.applicationid(q2libs.plugins.android.application)
Android Librarycom.android.libraryid(q2libs.plugins.android.library)
KSPcom.google.devtools.kspid(q2libs.plugins.ksp)
Compose Compilerorg.jetbrains.kotlin.plugin.composeid(q2libs.plugins.compose.compiler)
Hiltcom.google.dagger.hilt.androidid(q2libs.plugins.hilt)
Kotlin Parcelizeorg.jetbrains.kotlin.plugin.parcelizeid(q2libs.plugins.kotlin.parcelize)
Google Servicescom.google.gms.google-servicesid(q2libs.plugins.google.services)
Artifactorycom.jfrog.artifactoryid(q2libs.plugins.artifactory)
Kotlin Serializationorg.jetbrains.kotlin.plugin.serializationid(q2libs.plugins.kotlin.serialization)
Dokkaorg.jetbrains.dokkaid(q2libs.plugins.dokka)

Library Bundles​

BundleLibrariesImplementation
Daggerdagger, glassfish-annotationimplementation(q2libs.bundles.dagger)
Retrofit2retrofit2-retrofit, retrofit2-converter-gsonimplementation(q2libs.bundles.retrofit2)
Koinkoin-android, koin-core, koin-androidx-composeimplementation(q2libs.bundles.koin)