diff --git a/.github/workflows/lint-report.yml b/.github/workflows/lint-report.yml index 729bd9d..0bc3143 100644 --- a/.github/workflows/lint-report.yml +++ b/.github/workflows/lint-report.yml @@ -36,12 +36,6 @@ jobs: - name: Run Android Lint run: ./gradlew lint - - name: Upload SARIF for shared - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: shared/build/reports/lint-results.sarif - category: shared - - name: Upload SARIF for places-rx uses: github/codeql-action/upload-sarif@v3 with: diff --git a/.gitignore b/.gitignore index 69f06a0..d12d7d5 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ secure.properties # This covers new IDEs, like Antigravity .vscode/ -**/bin/ \ No newline at end of file +**/bin/ +/secrets.properties diff --git a/README.md b/README.md index d452226..7ad5930 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,34 @@ # Maps Android Rx +# ⚠️ PROJECT ARCHIVED & DEPRECATED ⚠️ + +**This library is no longer maintained and has been officially archived.** + +### Why is this project being retired? + +Since the launch of this project, the Android ecosystem has largely transitioned from RxJava to +**Kotlin Coroutines and Flows**. In alignment with modern Android development practices, +maintenance effort has shifted to libraries that natively support these features. + +### Alternatives and Migration + +1. **Maps SDK for Android KTX:** We recommend using the +[Maps SDK for Android KTX](https://github.com/googlemaps/android-maps-ktx). This is the current +standard for idiomatic Kotlin development and provides native support for **Coroutines** and **Flow**. +2. **Bridging to RxJava:** If your codebase remains strictly RxJava-based, you can use the Maps KTX +library and convert the resulting Flows into Observables using the [Kotlinx Coroutines RxJava bridge](https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx3). +3. **Source Access:** The source code for these Rx wrappers remains available in this repository for +reference or manual inclusion in your project. However, no further updates, bug fixes, or dependency +bumps will be performed. + +--- + +### Final Maintenance Note + +This project is being archived to provide clarity to the developer community and to ensure users are +directed toward the most active and supported tools for the Maps SDK. + ## Description This repository contains RxJava bindings for the [Maps SDK for Android](maps-sdk) and [Places SDK for Android](places-sdk). diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ef66262..aeb0272 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,20 +22,20 @@ plugins { android { lint { - sarifOutput = file("$buildDir/reports/lint-results.sarif") + sarifOutput = layout.buildDirectory.file("reports/lint-results.sarif").get().asFile } buildFeatures { buildConfig = true } - compileSdk = 35 + compileSdk = libs.versions.compileSdk.get().toInt() namespace = "com.google.maps.android.rx.demo" defaultConfig { applicationId = "com.google.maps.android.rx.demo" - minSdk = 24 - targetSdk = 35 + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -52,18 +52,14 @@ android { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } - - kotlinOptions { - jvmTarget = "1.8" - } } dependencies { // RxJava bindings for the Maps SDK - implementation(libs.mapsRx) + implementation(project(":maps-rx")) // RxJava bindings for the Places SDK - implementation(libs.placesRx) + implementation(project(":places-rx")) // It is recommended to also include the latest Maps SDK, Places SDK and RxJava so you // have the latest features and bug fixes. @@ -71,14 +67,21 @@ dependencies { implementation(libs.places) implementation(libs.rxJava) implementation(libs.appCompat) + implementation(libs.activityKtx) implementation(libs.lifecycleRuntimeKtx) implementation(libs.material) implementation(libs.rxLifecycle) implementation(libs.mapsKtx) implementation(libs.kotlinStdlib) - } secrets { + propertiesFileName = "secrets.properties" defaultPropertiesFileName = "local.defaults.properties" } + +tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8) + } +} diff --git a/app/src/androidTest/java/com/google/maps/android/rx/demo/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/google/maps/android/rx/demo/ExampleInstrumentedTest.kt deleted file mode 100644 index 06ddfdf..0000000 --- a/app/src/androidTest/java/com/google/maps/android/rx/demo/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 Google LLC -// -// 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. - -package com.google.maps.android.rx.demo - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.google.maps.android.rx.demo", appContext.packageName) - } -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e38dab7..048deb0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,9 +15,11 @@ limitations under the License. --> - + + + + + if (permissions.all { it.value }) { + enableMyLocation() + } else { + Toast.makeText(this, "Permissions required for Places demo", Toast.LENGTH_SHORT).show() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(mapView) + setContentView(R.layout.activity_main) + + // 1. Inset Handling: Decor fits system windows = false + WindowCompat.setDecorFitsSystemWindows(window, false) + + // 2 & 3. Visibility & Behavior: Hide bars, transient swipe behavior + val controller = WindowCompat.getInsetsController(window, window.decorView) + controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + controller.hide(WindowInsetsCompat.Type.systemBars()) + + // 3. Cutout Support: Short edges + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + } + + // 4. Inset Handling: Apply insets to controls + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.controls_container)) { v, insets -> + val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, bars.bottom + v.paddingBottom) + insets + } + + // Initialize Places (provide a valid API key in local.defaults.properties or secrets) + // Note: SDK must be initialized. Usually done in Application class, + // but here confirming if it's initialized or doing it here if simple. + // Assuming Places is initialized in application or we do it here if needed. + // For this demo, let's assume Application class initializes it or we add a check. + // Actually, we should check if Places is initialized. + if (!Places.isInitialized()) { + try { + val appInfo = packageManager.getApplicationInfo(packageName, android.content.pm.PackageManager.GET_META_DATA) + val apiKey = appInfo.metaData?.getString("com.google.android.geo.API_KEY") ?: "" + if (apiKey.isNotEmpty()) { + @Suppress("DEPRECATION") + Places.initialize(applicationContext, apiKey) + } + } catch (e: Exception) { + Log.e(TAG, "Places not initialized", e) + } + } + + placesClient = Places.createClient(this) + mapView = findViewById(R.id.mapView) + val mapViewBundle = savedInstanceState?.getBundle(MAPVIEW_BUNDLE_KEY) mapView.onCreate(mapViewBundle) mapView.observe(lifecycle) - lifecycle.coroutineScope.launchWhenCreated { - val googleMap = mapView.awaitMap() - googleMap.cameraIdleEvents() - .compose(provider.bindToLifecycle()) - .subscribe { - Log.d(TAG, "Camera is idle") + lifecycleScope.launch { + lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) { + val googleMap = mapView.awaitMap() + + // Set padding on Google Map to account for cutouts/bars + // We can use the View's root insets to determine safe area + ViewCompat.setOnApplyWindowInsetsListener(mapView) { _, insets -> + val bars = insets.getInsets(WindowInsetsCompat.Type.displayCutout() or WindowInsetsCompat.Type.systemBars()) + googleMap.setPadding(bars.left, bars.top, bars.right, bars.bottom) // Ensure map controls aren't hidden + insets } + + // Trigger an inset pass to ensure padding is applied if map is ready after layout + mapView.requestApplyInsets() + + // Camera events demo + googleMap.cameraIdleEvents() + .compose(provider.bindToLifecycle()) + .subscribe { + Log.d(TAG, "Camera is idle") + } + + // Enable location if permission granted + checkPermissions() + } + } + + findViewById