COMP5216移动计算 辅导

该文档是关于COMP5216移动计算课程2024年第二学期实验05 – 位置访问的指导说明,主要目标是让学生了解如何使用Google Maps API和Google Location Services API。文档包含两个任务,一是使用Google Maps API在Android应用中添加地图,包括创建项目、获取API密钥、添加相关代码等步骤;二是访问当前位置,通过使用Maps SDK和Google Play服务位置API中的融合位置提供程序来实现,涉及创建项目、获取API密钥、添加变量和代码、设置权限等操作。

2024 S2

实验05 – 位置访问

目标: 1. 理解如何使用Google Maps API 2. 理解如何使用Google Location Services API

任务: 1. 使用Google Maps API 2. 访问当前位置

位置服务允许应用程序和网站(包括地图、相机、天气和其他应用程序)使用来自蜂窝网络、Wi-Fi、全球定位系统(GPS)网络和蓝牙的信息来确定您的大致位置。 在您的应用程序中使用基于位置的信息是保持用户与周围世界连接的好方法。无论您将此信息用于导航等实际目的还是娱乐,基于位置的信息都可以为用户提供更具情境性的体验并增强整体用户体验。 在本教程中,我们将探索如何通过在您的移动设备中使用Google Maps API和Google Location Services API来捕获此位置信息。

计算机科学学院

第1页,共11页

COMP5216移动计算

LabW05

任务1:使用Google Maps API 本指南是向Android应用程序添加地图的快速入门。Android Studio是使用Maps SDK for Android构建应用程序的推荐开发环境。 使用Android版Maps SDK,您可以向应用程序添加基于Google Maps数据的地图。该API会自动处理对Google Maps服务器的访问、数据下载、地图显示以及对地图手势的响应。您还可以使用API调用来向基本地图添加标记、多边形和叠加层,并更改用户对特定地图区域的视图。这些对象为地图位置提供了额外的信息,并允许用户与地图进行交互。该API允许您向地图添加这些图形: – 锚定在地图特定位置的图标(标记)。 – 线段集(折线)。 – 封闭段(多边形)。 – 锚定在地图特定位置的位图图形(地面叠加层)。 – 显示在基础地图图块顶部的图像集(图块叠加层)。

此任务基于以下教程链接: – https://developers.google.com/maps/documentation/android-sdk/start – https://developers.google.com/maps/documentation/android-sdk/map-with-marker

  1. 启动Android Studio,在“手机和平板电脑”类别下选择“无活动”项目来创建新项目。按照提示输入以下信息:

    • 名称:“GoogleMaps”
    • 包名:“comp5216.sydney.edu.au.googlemaps”
    • 选择您首选的保存位置
    • 语言:Java
    • 最低API级别:API 24 Android 7.0(牛轧糖)
    • 构建配置级别:Groovy DSL 点击完成
  2. 创建项目后,右键单击App -> Java -> comp5216.sydney.edu.au.googlemaps,选择新建 -> 活动→ 图库 -> Google Maps View Activity,并完成活动屏幕的详细信息。在“新Android活动”对话框中,选中“启动器活动”复选框。

  3. 您的应用程序需要一个Google Map API密钥才能访问Google Maps服务器,因此在接下来的步骤中,您应该获取一个可以添加到应用程序中的Google Maps API密钥。Android Studio的Androidmanifest.xml文件包含一个指向网站的链接,其中包含有关如何获取Google Map API密钥的说明。请勿将您的API密钥添加到该文件中。这样做会降低API密钥的存储安全性。

计算机科学学院

第2页,共11页

COMP5216移动计算

LabW05

  1. 前往Google Cloud Platform控制台创建Google Maps API密钥。在Google Cloud控制台的“选择项目”页面上,点击创建“新项目”以开始创建新的Google Cloud项目。选择项目名称并点击创建。

  2. 提供账单信息以开始免费试用,并启用Maps APIs或Android版SDK以使用Google Maps平台。在“入门”部分选择“APIs和服务 -> 已启用的APIs和服务”。选择“库”选项以进入API库。点击“Maps SDK for Android”磁贴以启用该SDK与您的项目一起使用,然后点击启用按钮。

  3. 如果已经创建了账单账户,请选择付款方式,或者设置付款方式以生成API密钥。

  4. 在Google Maps平台中,转到“密钥和凭据”选项卡。

  5. 在“凭据”页面上,点击“+创建凭据”> API密钥。创建的API密钥对话框将显示您新创建的API密钥。

  6. 点击关闭。新的API密钥将在“凭据”页面的API密钥下列出。(请记住在生产中使用之前限制API密钥)

  7. 在Android Studio中,打开您的项目build.gradle文件,并将以下代码添加到plugins部分下的id中。这些行可能已经自动添加到gradle文件中。

plugins '2.0.1' apply false
id 'com.android.application' version '8.1.0' apply false
id 'com.android.library' version '8.1.0' apply false
id 'com.google.android.libraries.mapsplatform.secrets - gradle - plugin' version
  1. 接下来,打开您的模块build.gradle文件,并将以下代码添加到plugins元素中。
id 'com.google.android.libraries.mapsplatform.secrets - gradle - plugin'
  1. 保存文件并与Gradle同步您的项目。在您的AndroidManifest.xml文件中,转到com.google.android.geo.API_KEY,并将android:value属性更新为MAPS_API_KEY,如下所示。
<meta - data
    android:name = "com.google.android.geo.API_KEY"
    android:value = "MAPS_API_KEY" />
  1. 查看Android Studio生成的代码。查看应用程序的布局XML文件activity_maps.xml和定义地图活动的Java文件MapsActivity.java。

计算机科学学院

第3页,共11页

COMP5216移动计算

LabW05

  1. 在地图上启用缩放控件,并在地图准备好使用时立即动画相机缩放到地图。参考以下代码片段。 最终的代码应与附录中给出的MapsActivity.java文件相同。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMapsBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    // 获取SupportMapFragment并在地图准备好使用时得到通知。
    if (mMap == null) { // 进行空检查以确认我们尚未实例化地图。
        SupportMapFragment mapFragment = (SupportMapFragment)
                getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        if (mMap!= null) {
            // 地图已准备好
            Toast.makeText(this, "Map is ready to be used!", Toast.LENGTH_SHORT).show();
            // 在悉尼添加一个标记并移动相机
            LatLng sydney = new LatLng(-33.8692, 151.2089);
            mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
            // 启用缩放控件
            mMap.getUiSettings().setZoomControlsEnabled(true);
            // 动画相机缩放到地图
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sydney, 11));
        } else {
            Toast.makeText(this, "Error - Map was null!", Toast.LENGTH_SHORT).show();
        }
    }
  1. 构建并运行您的应用程序。 应显示一个Google地图、锚定在悉尼特定位置的标记和缩放控件,如下图所示。使用地图上的缩放控件放大或缩小地图。

计算机科学学院

第4页,共11页

COMP5216移动计算

LabW05

任务2:访问当前位置 此任务向您展示如何查找Android设备的当前位置。它使用Android版Maps SDK和Google Play服务位置API中的融合位置提供程序构建一个Android应用程序。内容部分采用了以下教程: https://developers.google.com/maps/documentation/android-sdk/current-place-tutorial

  1. 启动Android Studio,在“手机和平板电脑”类别下选择“无活动”项目来创建新项目。按照提示输入以下信息:
    • 名称:“GoogleLocation”
    • 包名:“comp5216.sydney.edu.au.googlelocation”
    • 选择您首选的保存位置
    • 语言:Java
    • 最低API级别:API 24 Android 7.0(牛轧糖)
    • 构建配置级别:Groovy DSL
    • 点击完成

计算机科学学院

第5页,共11页

COMP5216移动计算

LabW05

  1. 创建项目后,右键单击App -> Java -> comp5216.sydney.edu.au.googlelocation,选择→ 活动 – 图库> Google Maps View Activity,并完成活动屏幕的详细信息。

  2. 将activity_maps.xml(来自附录)复制到项目的res/layout文件夹中。它只包含底部的一个位置TextView来显示纬度和经度,以及上面的一个Google Map Fragment来覆盖屏幕的其余部分。 8:00 GoogleLocation

  3. 获取Google Maps API密钥并将其添加到您的应用程序中。参考任务1中的步骤4至12,了解如何获取密钥并将其用于您的应用程序。

计算机科学学院

第6页,共11页

COMP5216移动计算

LabW05

  1. 在您的MapsActivity.java文件中,声明变量来引用位置(locationTextView)、当前位置(mLastKnownLocation)、默认位置(mDefaultLocation)、默认缩放和其他支持变量。
private ActivityMapsBinding binding;
private TextView locationTextView;
private GoogleMap mMap;
private CameraPosition mCameraPosition;
private static final String TAG = MapsActivity.class.getSimpleName();
private FusedLocationProviderClient mFusedLocationProviderClient; // 融合位置提供程序的入口点。
private Location mLastKnownLocation = new Location(""); // 设备当前所在的地理位置。即,融合位置提供程序检索到的最后已知位置。
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private static final int DEFAULT_ZOOM = 15;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; // 默认位置(澳大利亚悉尼)和默认缩放,用于在位置
private boolean mLocationPermissionGranted = false;
// 用于存储活动状态的键。
private static final String KEY_CAMERA_POSITION = "camera_position";
private static final String KEY_LOCATION = "location";
.
  1. 在应用模块目录内的build.gradle文件中添加Google Play Services库
implementation libs.play.services.maps
implementation 'com.google.android.gms:play - services - location:21.0.1'

计算机科学学院

第7页,共11页

Computer Science Tutoring

COMP5216移动计算

LabW05

  1. 在onCreate()方法中,使用布局activity_maps,并初始化融合位置提供程序客户端。还初始化Google Map。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 获取呈现地图的内容视图。
    binding = ActivityMapsBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    if // 从保存的实例状态中检索位置和相机位置。
    (savedInstanceState!= null) {
        mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
        mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
        // 获取SupportMapFragment并在地图准备好使用时得到通知。
        SupportMapFragment mapFragment = (SupportMapFragment)
                getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        // 获取位置TextView
        locationTextView = (TextView) this.findViewById(R.id.location);
        // 构造融合位置提供程序客户端。
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    }
  1. 确保您的活动扩展FragmentActivity而不是Activity,并实现OnMapReadyCallback。我们将在下一步添加所需的方法。
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
  1. 添加所需的回调方法。
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    getLocationPermission(); // 提示用户获取权限。
    // 打开“我的位置”层和地图上的相关控制。
    updateLocationUI();
    // 获取设备的当前位置并设置地图的位置。
    getDeviceLocation();

计算机科学学院

第8页,共11页

COMP5216移动计算

LabW05

  1. 确保getLocationPermission、updateLocationUI和getDeviceLocation方法已实现,并且您理解每个函数的作用。参考实验文件中的MapsActivity.java。
private void getDeviceLocation() {
    try {
        if (mLocationPermissionGranted) {
            Task<Location> locationResult =
                    mFusedLocationProviderClient.getLastLocation();
            locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
                @Override
                public void onComplete(@NonNull Task<Location> task) {
                    if (task.isSuccessful()) {
                        mLastKnownLocation = task.getResult();
                        String currentOrDefault = "Current";
                        // 获取设备的当前位置
                        if (mLastKnownLocation!= null) {
                            DEFAULT_ZOOM));
                        } else {
                            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                                    Log.d(TAG, "Current location is null. Using defaults.");
                            new LatLng(mLastKnownLocation.getLatitude(),
                                    mLastKnownLocation.getLongitude()),
                                    currentOrDefault = "Default";
                            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation,
                                    DEFAULT_ZOOM));
                            mMap.getUiSettings().setMyLocationButtonEnabled(false);
                            mLastKnownLocation = new Location("");
                            // 将当前位置设置为默认位置
                            mLastKnownLocation.setLatitude(mDefaultLocation.latitude);
                            mLastKnownLocation.setLongitude(mDefaultLocation.longitude);
                            String msg = currentOrDefault + " Location: " +
                                    // 在位置TextView上显示位置详细信息
                                    toString(mLastKnownLocation.getLatitude()) + ",
                                    locationTextView.setText(msg);
                                    toString(mLastKnownLocation.getLongitude());
                            // 在地图上为我的当前位置添加一个标记
                            MarkerOptions marker = new MarkerOptions().position(
                                    new LatLng(mLastKnownLocation.getLatitude(),
                                            mLastKnownLocation.getLongitude()))
                            else {
                                mMap.addMarker(marker);
                                e(TAG, "Exception: %s", task.getException());
                                d(TAG, "Current location is null. Using defaults.");
                                "I am here");
                            mMap.moveCamera(CameraUpdateFactory
                                    mMap.getUiSettings().setMyLocationButtonEnabled(false);
                                    newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
                        }
                    }
                }
            });
        }
    } catch (SecurityException e) {
        Log.e("Exception: %s", e.getMessage());
    }
  1. 设置访问位置的权限。您可以参考实验材料中的AndroidManifest.xml文件来更新您自己的版本。
<uses - permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
<uses - permission android:name = "android.permission.ACCESS_COARSE_LOCATION" />
  1. 构建并运行应用程序,最好在移动电话上。该应用程序应显示您的当前位置。最终的代码将与附录中的MapsActivity.java类似。

要了解有关Location Services API的更多信息,请参阅Google Location Services for Android: – 构建位置感知应用程序 – https://developer.android.com/training/location/ – 获取最后已知位置 – https://developer.android.com/training/location/retrieve-current

要了解有关在Android模拟器中使嵌入式Google Map正常工作的逐步过程的更多信息,请参考本教程: https://github.com/codepath/android_guides/wiki/Google-Maps-Fragment-Guide

计算机科学学院

第10页,共11页

MOCO COMP5216移动计算

LabW05

附录

Activity_maps.xml “`xml <RelativeLayout xmlns:android = “http://schemas.android.com/apk/res/android” android: