chore: Update WearOS sample and add Kotlin version. (#659)

* Add secrets-gradle-plugin.

* Using new ambient mode API.

* Applying fullscreen.

* Add Kotlin samples.

* Use java 11.

* Include local.defaults.properties.

* Rename to local.defaults.properties.

* Add value for GOOGLE_MAPS_API_KEY

* s/master/main
This commit is contained in:
Chris Arriola 2021-08-12 16:29:54 -07:00 committed by GitHub
parent b92eeef28b
commit 8c8e3a3b51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 387 additions and 170 deletions

View File

@ -58,10 +58,11 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: set up JDK 1.8
uses: actions/setup-java@v1
- name: set up Java 11
uses: actions/setup-java@v2
with:
java-version: 1.8
distribution: 'adopt'
java-version: '11'
- name: Build and check
run: cd WearOS && ./gradlew assembleDebug lintDebug
@ -96,7 +97,7 @@ jobs:
- uses: actions/checkout@v2
- name: set up Java 11
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'

View File

@ -16,7 +16,6 @@ Pre-requisites
Getting Started
---------------
This sample use the Gradle build system.
First download the samples by cloning this repository or downloading an archived
@ -29,7 +28,7 @@ If prompted for a gradle configuration accept the default settings.
Alternatively use the "gradlew build" command to build the project directly.
Add your API key to the `AndroidManifest.xml` file.
Add your API key to the `local.properties` file and call it `GOOGLE_MAPS_API_KEY`.
See the [quick guide to getting an API key](https://developers.google.com/maps/documentation/android-api/signup).
Support
@ -51,4 +50,4 @@ CONTRIBUTING.md.
License
-------
Please refer to the [LICENSE](https://github.com/googlemaps/android-samples/blob/master/LICENSE) at the root of this repo.
Please refer to the [LICENSE](https://github.com/googlemaps/android-samples/blob/main/LICENSE) at the root of this repo.

View File

@ -14,16 +14,19 @@
* limitations under the License.
*/
apply plugin: 'com.android.application'
plugins {
id 'com.android.application'
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
apply plugin: 'kotlin-android'
android {
compileSdkVersion 29
compileSdkVersion 30
defaultConfig {
applicationId "com.example.wearos"
minSdkVersion 21
targetSdkVersion 29
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
@ -39,15 +42,21 @@ repositories {
mavenCentral()
}
// [START maps_wear_os_depdendencies]
dependencies {
// [START_EXCLUDE]
implementation fileTree(dir: 'libs', include: ['*.jar'])
// Required for DismissOverlayView to exit full screen wearable app.
implementation 'com.google.android.support:wearable:2.5.0'
// // Required to support ambient mode.
compileOnly 'com.google.android.wearable:wearable:2.5.0'
// Include the Google Maps Android API from Google Play Services.
// [END_EXCLUDE]
compileOnly 'com.google.android.wearable:wearable:2.8.1'
implementation 'androidx.wear:wear:1.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.1'
// This dependency is necessary for ambient mode
implementation 'com.google.android.support:wearable:2.8.1'
implementation "androidx.core:core-ktx:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
// [END maps_wear_os_depdendencies]
secrets {
defaultPropertiesFileName 'local.defaults.properties'
}

View File

@ -1,30 +0,0 @@
<!--
Copyright (C) 2015 Google Inc. All Rights Reserved.
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.
-->
<resources>
<!--
TODO: Before you run your application, you need a Google Maps API key.
See this page for more information:
https://developers.google.com/maps/documentation/android/start#get_an_android_certificate_and_the_google_maps_api_key
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" translatable="false" templateMergeStrategy="preserve">
ADD_API_KEY_HERE
</string>
</resources>

View File

@ -28,17 +28,17 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
android:theme="@style/Theme.AppCompat.NoActionBar" >
<!-- API key for the Android Maps API v2. The value is defined as a string resource. -->
<!-- API key for the Android Maps API v2. The value is defined in local.properties. -->
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"/>
android:value="${GOOGLE_MAPS_API_KEY}"/>
<!-- Reference the wearable shared library required to support ambient mode. -->
<uses-library android:name="com.google.android.wearable" android:required="false" />
<activity
android:name=".MainActivity"
android:name=".kt.MainActivity"
android:label="@string/app_name" >
<intent-filter>

View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2015 Google Inc. All Rights Reserved.
*
* 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.example.wearosmap;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.wear.ambient.AmbientModeSupport;
import androidx.wear.ambient.AmbientModeSupport.AmbientCallback;
import androidx.wear.widget.SwipeDismissFrameLayout;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
/**
* Sample that shows how to set up a basic Google Map on Wear OS.
*/
// [START maps_wear_os_ambient_mode_support]
public class AmbientActivity extends AppCompatActivity implements
AmbientModeSupport.AmbientCallbackProvider {
private SupportMapFragment mapFragment;
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
// Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
setContentView(R.layout.activity_main);
// Enable ambient support, so the map remains visible in simplified, low-color display
// when the user is no longer actively using the app but the app is still visible on the
// watch face.
AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
Log.d(AmbientActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());
// Obtain the MapFragment and set the async listener to be notified when the map is ready.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
}
@Override
public AmbientCallback getAmbientCallback() {
return new AmbientCallback() {
/**
* Starts ambient mode on the map.
* The API swaps to a non-interactive and low-color rendering of the map when the user is no
* longer actively using the app.
*/
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
mapFragment.onEnterAmbient(ambientDetails);
}
/**
* Exits ambient mode on the map.
* The API swaps to the normal rendering of the map when the user starts actively using the app.
*/
@Override
public void onExitAmbient() {
super.onExitAmbient();
mapFragment.onExitAmbient();
}
};
}
}
// [END maps_wear_os_ambient_mode_support]

View File

@ -16,42 +16,35 @@
package com.example.wearosmap;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.DismissOverlayView;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.wear.ambient.AmbientModeSupport;
import androidx.wear.ambient.AmbientModeSupport.AmbientCallback;
import androidx.wear.widget.SwipeDismissFrameLayout;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
/**
* Sample that shows how to set up a basic Google Map on Wear OS.
*/
public class MainActivity extends WearableActivity implements OnMapReadyCallback,
GoogleMap.OnMapLongClickListener {
// [START maps_wear_os_swipe_dismiss_callback]
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
AmbientModeSupport.AmbientCallbackProvider {
// [START_EXCLUDE silent]
private static final LatLng SYDNEY = new LatLng(-33.85704, 151.21522);
/**
* Overlay that shows a short help text when first launched. It also provides an option to
* exit the app.
*/
private DismissOverlayView mDismissOverlay;
/**
* The map. It is initialized when the map has been fully loaded and is ready to be used.
*
* @see #onMapReady(com.google.android.gms.maps.GoogleMap)
*/
private GoogleMap mMap;
private MapFragment mMapFragment;
private SupportMapFragment mapFragment;
// [END_EXCLUDE]
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
@ -62,47 +55,44 @@ public class MainActivity extends WearableActivity implements OnMapReadyCallback
// Enable ambient support, so the map remains visible in simplified, low-color display
// when the user is no longer actively using the app but the app is still visible on the
// watch face.
setAmbientEnabled();
// [START maps_wear_os_ambient_mode_support]
AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
// [END maps_wear_os_ambient_mode_support]
Log.d(MainActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());
// Retrieve the containers for the root of the layout and the map. Margins will need to be
// set on them to account for the system window insets.
final FrameLayout topFrameLayout = (FrameLayout) findViewById(R.id.root_container);
final FrameLayout mapFrameLayout = (FrameLayout) findViewById(R.id.map_container);
// Set the system view insets on the containers when they become available.
topFrameLayout.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
final SwipeDismissFrameLayout mapFrameLayout = (SwipeDismissFrameLayout) findViewById(
R.id.map_container);
mapFrameLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
// Call through to super implementation and apply insets
insets = topFrameLayout.onApplyWindowInsets(insets);
FrameLayout.LayoutParams params =
(FrameLayout.LayoutParams) mapFrameLayout.getLayoutParams();
// Add Wearable insets to FrameLayout container holding map as margins
params.setMargins(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom());
mapFrameLayout.setLayoutParams(params);
return insets;
public void onDismissed(SwipeDismissFrameLayout layout) {
onBackPressed();
}
});
// Obtain the DismissOverlayView and display the intro help text.
mDismissOverlay = (DismissOverlayView) findViewById(R.id.dismiss_overlay);
mDismissOverlay.setIntroText(R.string.intro_text);
mDismissOverlay.showIntroIfNecessary();
// Obtain the MapFragment and set the async listener to be notified when the map is ready.
mMapFragment = (MapFragment) getFragmentManager()
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mMapFragment.getMapAsync(this);
mapFragment.getMapAsync(this);
}
// [START_EXCLUDE]
// [START maps_wear_os_on_map_ready]
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
// Add a marker with a title that is shown in its info window.
googleMap.addMarker(new MarkerOptions().position(SYDNEY)
.title("Sydney Opera House"));
// Move the camera to show the marker.
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10));
}
// [END maps_wear_os_on_map_ready]
@Override
public AmbientCallback getAmbientCallback() {
return new AmbientCallback() {
/**
* Starts ambient mode on the map.
* The API swaps to a non-interactive and low-color rendering of the map when the user is no
@ -111,7 +101,7 @@ public class MainActivity extends WearableActivity implements OnMapReadyCallback
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
mMapFragment.onEnterAmbient(ambientDetails);
mapFragment.onEnterAmbient(ambientDetails);
}
/**
@ -121,28 +111,10 @@ public class MainActivity extends WearableActivity implements OnMapReadyCallback
@Override
public void onExitAmbient() {
super.onExitAmbient();
mMapFragment.onExitAmbient();
mapFragment.onExitAmbient();
}
@Override
public void onMapReady(GoogleMap googleMap) {
// Map is ready to be used.
mMap = googleMap;
// Set the long click listener as a way to exit the map.
mMap.setOnMapLongClickListener(this);
// Add a marker with a title that is shown in its info window.
mMap.addMarker(new MarkerOptions().position(SYDNEY)
.title("Sydney Opera House"));
// Move the camera to show the marker.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10));
}
@Override
public void onMapLongClick(LatLng latLng) {
// Display the dismiss overlay with a button to exit this activity.
mDismissOverlay.show();
};
}
// [END_EXCLUDE]
}
// [END maps_wear_os_swipe_dismiss_callback]

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2015 Google Inc. All Rights Reserved.
*
* 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.example.wearosmap.kt
import androidx.appcompat.app.AppCompatActivity
import androidx.wear.ambient.AmbientModeSupport
import com.google.android.gms.maps.SupportMapFragment
import android.os.Bundle
import android.util.Log
import com.example.wearosmap.R
/**
* Sample that shows how to set up a basic Google Map on Wear OS.
*/
// [START maps_wear_os_ambient_mode_support]
class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {
private lateinit var mapFragment: SupportMapFragment
public override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
// Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
setContentView(R.layout.activity_main)
// Enable ambient support, so the map remains visible in simplified, low-color display
// when the user is no longer actively using the app but the app is still visible on the
// watch face.
val controller = AmbientModeSupport.attach(this)
Log.d(AmbientActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)
// Obtain the MapFragment and set the async listener to be notified when the map is ready.
mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
}
override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
return object : AmbientModeSupport.AmbientCallback() {
/**
* Starts ambient mode on the map.
* The API swaps to a non-interactive and low-color rendering of the map when the user is no
* longer actively using the app.
*/
override fun onEnterAmbient(ambientDetails: Bundle) {
super.onEnterAmbient(ambientDetails)
mapFragment.onEnterAmbient(ambientDetails)
}
/**
* Exits ambient mode on the map.
* The API swaps to the normal rendering of the map when the user starts actively using the app.
*/
override fun onExitAmbient() {
super.onExitAmbient()
mapFragment.onExitAmbient()
}
}
}
}
// [END maps_wear_os_ambient_mode_support]

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2015 Google Inc. All Rights Reserved.
*
* 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.example.wearosmap.kt
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.OnMapReadyCallback
import androidx.wear.ambient.AmbientModeSupport
import com.google.android.gms.maps.SupportMapFragment
import android.os.Bundle
import android.util.Log
import com.example.wearosmap.R
import androidx.wear.widget.SwipeDismissFrameLayout
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.model.LatLng
/**
* Sample that shows how to set up a basic Google Map on Wear OS.
*/
// [START maps_wear_os_swipe_dismiss_callback]
class MainActivity : AppCompatActivity(), OnMapReadyCallback,
AmbientModeSupport.AmbientCallbackProvider {
// [START_EXCLUDE silent]
private lateinit var mapFragment: SupportMapFragment
// [END_EXCLUDE]
public override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
// Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
setContentView(R.layout.activity_main)
// Enable ambient support, so the map remains visible in simplified, low-color display
// when the user is no longer actively using the app but the app is still visible on the
// watch face.
// [START maps_wear_os_ambient_mode_support]
val controller = AmbientModeSupport.attach(this)
// [END maps_wear_os_ambient_mode_support]
Log.d(MainActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)
// Retrieve the containers for the root of the layout and the map. Margins will need to be
// set on them to account for the system window insets.
val mapFrameLayout = findViewById<SwipeDismissFrameLayout>(R.id.map_container)
mapFrameLayout.addCallback(object : SwipeDismissFrameLayout.Callback() {
override fun onDismissed(layout: SwipeDismissFrameLayout) {
onBackPressed()
}
})
// Obtain the MapFragment and set the async listener to be notified when the map is ready.
mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
// [START_EXCLUDE]
// [START maps_wear_os_on_map_ready]
override fun onMapReady(googleMap: GoogleMap) {
// Add a marker with a title that is shown in its info window.
googleMap.addMarker(
MarkerOptions().position(SYDNEY)
.title("Sydney Opera House")
)
// Move the camera to show the marker.
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10f))
}
// [END maps_wear_os_on_map_ready]
override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
return object : AmbientModeSupport.AmbientCallback() {
/**
* Starts ambient mode on the map.
* The API swaps to a non-interactive and low-color rendering of the map when the user is no
* longer actively using the app.
*/
override fun onEnterAmbient(ambientDetails: Bundle) {
super.onEnterAmbient(ambientDetails)
mapFragment.onEnterAmbient(ambientDetails)
}
/**
* Exits ambient mode on the map.
* The API swaps to the normal rendering of the map when the user starts actively using the app.
*/
override fun onExitAmbient() {
super.onExitAmbient()
mapFragment.onExitAmbient()
}
}
}
companion object {
private val SYDNEY = LatLng(-33.85704, 151.21522)
}
// [END_EXCLUDE]
}
// [END maps_wear_os_swipe_dismiss_callback]

View File

@ -17,28 +17,22 @@
limitations under the License.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_container"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- [START maps_wear_os_swipedismissframelayout] -->
<androidx.wear.widget.SwipeDismissFrameLayout
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"/>
</FrameLayout>
<android.support.wearable.view.DismissOverlayView
android:id="@+id/dismiss_overlay"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
android:layout_height="match_parent" />
</androidx.wear.widget.SwipeDismissFrameLayout>
<!-- [END maps_wear_os_swipedismissframelayout] -->
</FrameLayout>

View File

@ -17,15 +17,15 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.5.30-RC'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:7.0.0'
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@ -19,4 +19,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip

View File

@ -0,0 +1 @@
GOOGLE_MAPS_API_KEY=YOUR_API_KEY