49、Android音频录制与播放及Google Maps API集成开发指南

Android音频录制与播放及Google Maps API集成开发指南

一、Android音频录制与播放

1.1 权限检查代码

在Android应用中进行音频录制,需要检查录制权限。以下代码用于检查权限请求结果:

if (requestCode == RECORD_REQUEST_CODE) {
    if (grantResults.length == 0
            || grantResults[0] !=
            PackageManager.PERMISSION_GRANTED) {

        binding.recordButton.setEnabled(false);

        Toast.makeText(this,
                "Record permission required",
                Toast.LENGTH_LONG).show();
    }
}

上述代码首先检查请求标识符代码,以确定哪个权限请求已返回,然后检查相应权限是否被授予。如果权限被拒绝,会向用户显示一条消息,表明应用将无法正常工作,并禁用录制按钮。

1.2 音频设置方法

在应用启动时,需要调用新添加的 requestPermission() 方法来请求麦克风访问权限。以下是修改后的 audioSetup() 方法:

private void audioSetup(){
    binding.recordButton = findViewById(R.id.recordButton);
    binding.playButton = findViewById(R.id.playButton);
    binding.stopButton = findViewById(R.id.stopButton);

    if (!hasMicrophone())
    {
        stopButton.setEnabled(false);
        playButton.setEnabled(false);
        recordButton.setEnabled(false);
    } else {
        playButton.setEnabled(false);
        stopButton.setEnabled(false);
    }

    File audioFile = new File(this.getFilesDir(), "myaudio.3gp");
    audioFilePath = audioFile.getAbsolutePath();

    requestPermission(Manifest.permission.RECORD_AUDIO,
            RECORD_REQUEST_CODE);
}

该方法的主要步骤如下:
1. 初始化录制、播放和停止按钮。
2. 检查设备是否有麦克风,如果没有则禁用所有按钮;如果有则禁用播放和停止按钮。
3. 创建一个音频文件,并获取其绝对路径。
4. 请求录制音频的权限。

1.3 应用测试

要测试应用,可按以下步骤操作:
1. 在包含麦克风的Android设备上编译并运行应用。
2. 允许应用访问麦克风。
3. 点击“Record”按钮进行录制。
4. 录制完成后,点击“Stop”按钮,再点击“Play”按钮。此时,录制的音频应通过设备扬声器播放。

1.4 音频录制与播放总结

Android SDK提供了多种实现音频录制和播放的机制,这里主要介绍了 MediaPlayer MediaRecorder 类。在开发过程中,需要确保设备有麦克风,并在录制音频前请求相应的权限。

二、Google Maps Android API

2.1 Google Maps Android API概述

Google多年前推出地图服务时,可能未曾预料到其能集成到移动应用中。如今,借助Google Maps Android API,开发者可以在Android应用中直接使用Google Maps的强大功能。

2.2 Google Maps Android API的组成元素

Google Maps Android API由一组核心类组成,这些类共同为Android应用提供地图功能。主要元素如下:
| 元素 | 描述 |
| ---- | ---- |
| GoogleMap | 是Google Maps Android API的主要类,负责下载和显示地图图块,以及显示和响应地图控件。该对象不是由应用直接创建,而是在创建 MapView MapFragment 实例时创建。可通过调用 MapView MapFragment SupportMapFragment 实例的 getMap() 方法获取对 GoogleMap 对象的引用。 |
| MapView | 是 View 类的子类,为 GoogleMap 对象提供绘制地图的视图画布,允许将地图放置在活动的用户界面布局中。 |
| SupportMapFragment | 是 Fragment 类的子类,允许在Android布局的 Fragment 中放置地图。 |
| Marker | 用于在地图上标记位置。通过获取与地图关联的 GoogleMap 对象的引用,然后调用该对象实例的 addMarker() 方法来添加标记。标记的位置由经度和纬度定义,还可以进行各种配置,如指定标题、文本和图标,并且标记可以设置为“可拖动”。 |
| Shapes | 使用 Polyline Polygon Circle 类在地图上绘制线条和形状。 |
| UiSettings | 用于自定义地图上显示的控件。例如,应用可以控制缩放、当前位置和指南针控件是否显示,还可以配置地图识别的触摸屏手势。 |
| My Location Layer | 启用后,会在地图上显示一个按钮,用户点击该按钮时,地图将以用户的当前地理位置为中心。如果用户静止,地图上会用蓝色标记表示该位置;如果用户在移动,位置将由一个箭头表示用户的行进方向。 |

以下是一个简单的mermaid流程图,展示了获取 GoogleMap 对象的流程:

graph TD;
    A[创建MapView或MapFragment实例] --> B[自动创建GoogleMap对象];
    B --> C[通过getMap()方法获取引用];

2.3 创建Google Maps项目

创建Google Maps项目的步骤如下:
1. 从欢迎屏幕中选择“New Project”选项。
2. 在新的项目对话框中选择“No Activity”模板,然后点击“Next”按钮。
3. 在“Name”字段中输入“MapDemo”,并指定包名为“com.ebookfrenzy.mapdemo”。
4. 在点击“Finish”按钮之前,将“Minimum API level”设置为“API 26: Android 8.0 (Oreo)”,将“Language”菜单设置为“Java”。
5. 在项目工具窗口中,右键点击“app -> java -> com.ebookfrenzy.mapdemo”,选择“New -> Google -> Google Maps Views Activity”菜单选项。
6. 在“New Android Activity”对话框中启用“Launcher Activity”复选框,然后点击“Finish”按钮。

2.4 创建Google Cloud计费账户

在使用Google Map API之前,需要创建一个Google Cloud计费账户(如果已有则可跳过此步骤)。操作步骤如下:
1. 打开浏览器,使用以下链接导航到Google Cloud控制台: https://console.cloud.google.com/
2. 点击控制台页面左上角的菜单按钮,选择“Billing”条目。
3. 在“Billing”页面上,选择添加新的计费账户,然后按照步骤开始免费试用。需要提供信用卡信息,但在未经同意的情况下,免费试用结束后Google不会收费。

2.5 创建新的Google Cloud项目

创建与 MapDemo 应用关联的Google Cloud项目的步骤如下:
1. 使用以下URL返回Google Cloud控制台仪表板: https://console.cloud.google.com/home/dashboard
2. 在仪表板中,点击顶部工具栏中的“Select a project”按钮。
3. 当项目选择对话框出现时,点击“New Project”按钮。
4. 在新项目屏幕上,为项目提供一个名称。控制台会在项目名称字段下方显示一个默认的项目ID,如果不喜欢该默认ID,可以点击“Edit”按钮进行更改。
5. 点击“Create”按钮,稍作等待后,将返回仪表板,新创建的项目将列在其中。

2.6 启用Google Maps SDK

启用项目对Google Maps SDK的使用权限,步骤如下:
1. 在Google Cloud控制台中选择项目。
2. 点击左上角的菜单按钮,选择“Google Maps Platform”条目。
3. 从结果菜单中选择“APIs”选项。
4. 在“APIs”屏幕上,点击“Maps SDK for Android”选项,然后在结果屏幕上点击“Enable”按钮。
5. 重复上述步骤,启用“Geocoding API”凭证,后续应用需要该凭证来显示用户的当前位置。
6. 启用项目的凭证后,点击返回箭头,返回产品详细信息页面,为下一步做准备。

2.7 生成Google Maps API密钥

在应用使用Google Maps Android SDK之前,需要配置一个API密钥,将其与启用地图的Google Cloud项目关联。生成API密钥的步骤如下:
1. 选择“Credentials”菜单选项。
2. 点击“Create Credentials”按钮。
3. 凭证创建完成后,会出现一个显示API密钥的对话框。

2.8 将API密钥添加到Android Studio项目

将生成的API密钥添加到项目中,步骤如下:
1. 返回Android Studio,编辑“manifests -> AndroidManifest.xml”文件,找到以下API密钥条目:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY" />

删除“YOUR_API_KEY”文本,并将其替换为在Google Play控制台中创建的API密钥。
2. 编辑“Gradle Scripts -> local.properties”文件,添加一行内容如下(将 YOUR_API_KEY 替换为项目的API密钥):

MAPS_API_KEY=YOUR_API_KEY

2.9 应用测试

进行应用测试,以验证API密钥是否配置正确。如果配置正确,应用将运行并在屏幕上显示地图。如果地图未显示,可检查以下方面:
- 如果应用在模拟器上运行,确保模拟器运行的是包含Google API的Android版本。可以通过选择“Tools -> Android -> AVD Manager”菜单选项,点击AVD“Actions”列中的铅笔图标,然后点击当前Android版本旁边的“Change…”按钮,在系统镜像对话框中选择包含Google API的目标。
- 检查Logcat输出中是否有与Google Maps API认证问题相关的信息。这通常意味着API密钥输入错误,确保 AndroidManifest.xml local.properties 文件中的API密钥与Google Cloud控制台中生成的密钥匹配。
- 在Google API控制台中验证“Maps SDK for Android”是否已在“Credentials”面板中启用。

2.10 地理编码和反向地理编码

2.10.1 地理编码

地理编码是将基于文本的地理位置(如街道地址)转换为以经度和纬度表示的地理坐标。可以使用Android的 Geocoder 类实现地理编码。例如,以下代码请求华盛顿特区国家航空航天博物馆的位置:

import java.io.IOException;
import java.util.List;

import android.location.Address;
import android.location.Geocoder;
...
double latitude;
double longitude;

List<Address> geocodeMatches = null;

try {
    geocodeMatches = 
        new Geocoder(this).getFromLocationName(
            "600 Independence Ave SW, Washington, DC 20560", 1);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

if (!geocodeMatches.isEmpty())
{
    latitude = geocodeMatches.get(0).getLatitude(); 
    longitude = geocodeMatches.get(0).getLongitude();
}

上述代码是正向地理编码的示例,根据文本位置描述计算坐标。注意, getFromLocationName() 方法的第二个参数传递的值为1,表示只返回数组中的一个结果。对于更模糊的位置名称,可能需要请求更多潜在匹配结果,并允许用户选择正确的结果。

2.10.2 反向地理编码

反向地理编码是将地理坐标转换为人类可读的地址字符串。以下是一个反向地理编码的示例代码:

import java.io.IOException;
import java.util.List;

import android.location.Address;
import android.location.Geocoder;
...
List<Address> geocodeMatches = null;
String Address1;
String Address2;
String State;
String Zipcode;
String Country;

try {
    geocodeMatches = 
        new Geocoder(this).getFromLocation(38.8874245, -77.0200729, 1);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

if (!geocodeMatches.isEmpty())
{
    Address1 = geocodeMatches.get(0).getAddressLine(0);
    Address2 = geocodeMatches.get(0).getAddressLine(1);
    State = geocodeMatches.get(0).getAdminArea();
    Zipcode = geocodeMatches.get(0).getPostalCode();
    Country = geocodeMatches.get(0).getCountryName();
}

地理编码不是在Android设备上执行的,而是在设备需要进行转换时连接到服务器进行处理,转换完成后返回结果。地理编码只能在设备有活动的互联网连接时进行。

2.11 向应用中添加地图

向应用中添加地图的最简单方法是在活动的用户界面布局XML文件中指定地图。以下是一个示例布局文件,展示了如何将 SupportMapFragment 实例添加到Android Studio创建的 activity_maps.xml 文件中:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/map"
    tools:context=".MapsActivity"
    android:name="com.google.android.gms.maps.SupportMapFragment"/> 

2.12 请求当前位置权限

在Android 6.0及更高版本中,某些权限被认为是危险权限,需要特殊处理。允许应用识别用户当前位置的权限就属于此类。操作步骤如下:
1. 编辑项目工具窗口中“app -> manifests”下的 AndroidManifest.xml 文件,添加以下权限行:

<uses-permission   
    android:name="android.permission.ACCESS_FINE_LOCATION" /> 

<uses-permission
    android:name="android.permission.ACCESS_COARSE_LOCATION" />

这些设置确保应用在较旧版本的Android上安装时可以提供获取位置信息的权限。

  1. 为了支持Android 6.0及更高版本,需要在 MapsActivity.java 文件中添加一些代码来在运行时请求此权限。首先,添加一些导入指令和一个常量作为权限请求代码:
package com.ebookfrenzy.mapdemo;
...
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.widget.Toast;
import android.content.pm.PackageManager;
...
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback 
{ 
    private static final int LOCATION_REQUEST_CODE = 101;
    private GoogleMap mMap;
...
}
  1. MapsActivity 类中添加一个方法,用于向用户请求指定的权限:
protected void requestPermission(String permissionType,
                                 int requestCode) {

    ActivityCompat.requestPermissions(this,
            new String[]{permissionType}, requestCode
    ); 
}
  1. 当用户响应权限请求后,活动的 onRequestPermissionsResult() 方法将被调用。在 MapsActivity.java 文件中实现该方法如下:
@Override
public void onRequestPermissionsResult(int requestCode,
         @NonNull String[] permissions, @NonNull int[] grantResults) {

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == LOCATION_REQUEST_CODE) {
        if (grantResults.length == 0
                || grantResults[0] !=
                PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this,
                    "Unable to show location - permission required",
                    Toast.LENGTH_LONG).show();
        } else {

            SupportMapFragment mapFragment =
                    (SupportMapFragment) getSupportFragmentManager()
                            .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
        }
    }
}

如果用户未授予权限,应用将显示一条消息,表明无法显示当前位置;如果权限被授予,地图将刷新,以便显示位置标记。

2.13 显示用户的当前位置

当获得适当的权限后,可以通过获取与显示的地图关联的 GoogleMap 对象的引用,并调用该实例的 setMyLocationEnabled() 方法(传递 true 值)来在地图上显示用户的当前位置。

当地图准备好显示时,活动的 onMapReady() 方法将被调用。默认情况下,Android Studio已经实现了该方法,并添加了一些代码,将地图定位到澳大利亚,并在悉尼市放置一个标记。需要编辑 MapsActivity.java 文件中的 onMapReady() 方法,移除这些模板代码,并添加代码来检查是否已授予位置权限,然后再启用显示用户的当前位置。如果未授予权限,则通过调用之前添加的 requestPermission() 方法向用户请求权限:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    // Add a marker in Sydney and move the camera
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

    if (mMap != null) {
        int permission = ContextCompat.checkSelfPermission(this, 
              Manifest.permission.ACCESS_FINE_LOCATION);

        if (permission == PackageManager.PERMISSION_GRANTED) {
            // 此处可添加显示用户当前位置的代码
        }
    }
}

通过以上步骤,开发者可以在Android应用中实现音频录制与播放功能,并集成Google Maps API,为用户提供地图服务。

2.14 操作流程总结

为了更清晰地理解如何在 Android 应用中集成 Google Maps Android API,以下是一个完整的操作流程总结:
1. 创建项目 :在 Android Studio 中创建一个新的项目,选择合适的模板和配置。
2. 创建计费账户和项目 :在 Google Cloud 控制台创建计费账户和关联的项目。
3. 启用 SDK 和生成密钥 :在 Google Cloud 控制台启用 Google Maps SDK 和 Geocoding API,并生成 API 密钥。
4. 添加密钥到项目 :将生成的 API 密钥添加到 Android Studio 项目的相关文件中。
5. 添加地图布局 :在 XML 布局文件中添加 SupportMapFragment 来显示地图。
6. 请求权限 :在 AndroidManifest.xml 中添加位置权限,并在代码中请求运行时权限。
7. 显示用户位置 :在地图准备好后,检查权限并显示用户的当前位置。

以下是这个流程的 mermaid 流程图:

graph LR
    A[创建 Android 项目] --> B[创建 Google Cloud 计费账户]
    B --> C[创建 Google Cloud 项目]
    C --> D[启用 Google Maps SDK 和 Geocoding API]
    D --> E[生成 API 密钥]
    E --> F[将 API 密钥添加到项目]
    F --> G[在 XML 中添加地图布局]
    G --> H[请求位置权限]
    H --> I[显示用户当前位置]

2.15 常见问题及解决方法

在使用 Google Maps Android API 过程中,可能会遇到一些常见问题,以下是一些解决方法:
| 问题描述 | 解决方法 |
| ---- | ---- |
| 地图不显示 | 检查 API 密钥是否正确配置,模拟器是否包含 Google API,以及 Logcat 输出是否有认证问题。 |
| 无法获取用户位置 | 确保在 AndroidManifest.xml 中添加了正确的位置权限,并在运行时请求权限。 |
| 地理编码失败 | 检查设备是否有活动的互联网连接,因为地理编码需要连接服务器进行处理。 |

2.16 代码优化建议

为了提高应用的性能和稳定性,可以对代码进行一些优化:
- 权限请求优化 :可以将权限请求逻辑封装成一个单独的工具类,提高代码的复用性。
- 地理编码优化 :对于频繁的地理编码请求,可以考虑使用缓存机制,减少服务器请求次数。
- 地图加载优化 :可以在地图加载完成后再进行其他操作,避免界面卡顿。

2.17 总结

通过本文的介绍,我们学习了如何在 Android 应用中实现音频录制与播放功能,以及如何集成 Google Maps Android API。在音频录制与播放方面,需要注意权限的检查和设备麦克风的可用性。在 Google Maps API 集成方面,需要完成一系列的配置步骤,包括创建项目、启用 SDK、生成 API 密钥等,并处理好权限请求和地理编码等问题。

在实际开发中,开发者可以根据具体需求对代码进行进一步的优化和扩展,为用户提供更好的体验。同时,需要不断关注 Google Maps API 的更新和变化,以确保应用的兼容性和性能。

希望本文对开发者有所帮助,让大家能够顺利地在 Android 应用中实现音频和地图功能。

【四旋翼无人机】具备螺旋桨倾斜机构的全驱动四旋翼无人机:建模控制研究(Matlab代码、Simulink仿真实现)内容概要:本文围绕具备螺旋桨倾斜机构的全驱动四旋翼无人机展开研究,重点探讨其系统建模控制策略,结合Matlab代码Simulink仿真实现。文章详细分析了无人机的动力学模型,特别是引入螺旋桨倾斜机构后带来的全驱动特性,使其在姿态位置控制上具备更强的机动性自由度。研究涵盖了非线性系统建模、控制器设计(如PID、MPC、非线性控制等)、仿真验证及动态响应分析,旨在提升无人机在复杂环境下的稳定性和控制精度。同时,文中提供的Matlab/Simulink资源便于读者复现实验并进一步优化控制算法。; 适合人群:具备一定控制理论基础和Matlab/Simulink仿真经验的研究生、科研人员及无人机控制系统开发工程师,尤其适合从事飞行器建模先进控制算法研究的专业人员。; 使用场景及目标:①用于全驱动四旋翼无人机的动力学建模仿真平台搭建;②研究先进控制算法(如模型预测控制、非线性控制)在无人机系统中的应用;③支持科研论文复现、课程设计或毕业课题开发,推动无人机高机动控制技术的研究进展。; 阅读建议:建议读者结合文档提供的Matlab代码Simulink模型,逐步实现建模控制算法,重点关注坐标系定义、力矩分配逻辑及控制闭环的设计细节,同时可通过修改参数和添加扰动来验证系统的鲁棒性适应性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值