【Trae+AI】和Trae学习搭建App_2.2.1:第4章·安卓APP调用Express后端实战1:前端调用后端

📚前言

跟着trae规划的学习开发安卓手机app的教程,一步一步学习实践,总规划见下面文档

【Trae+AI】和Trae学习搭建App_00:总项目规划_trae 封装apk-CSDN博客

下面开始规划的第四章,开始之前还有点事要说。

🌍战略调整

在进行核心API实现之前,现把前后端连起来,现了解整体运行机制,这样会更有成就感。

实践方式,尽量手搓,即Android Studio+文本编辑器+CMD+AI教程指导【豆包】

✍️AI提示语:

我要学习安卓手机app的开发,我已经完成第一章规划,第二章:开发环境配置(包括Android Studio、node.js、MongoDB、Git),以及第三章,后端基础框架 Express框架搭建 数据库模型设计(用户、任务、分类) 中间件配置(日志、跨域、认证)。请为我规划第四章的教学内容,安卓APP调用后端Express的详细教程,可以分多次输出,一定要有详细的操作过程,和对应原理,指导初学的我逐步掌握。


第二部分:后端API开发

第四章 安卓APP调用Express后端实战

一、第四章整体教学规划(语言Kotlin)

本章核心目标:基于Kotlin语言(Android官方首选开发语言),从零基础到完整调用后端所有核心接口(登录、任务CRUD、分类管理),兼顾「手把手操作步骤」和「底层原理」,整体分为6个部分,适配初学者节奏:

模块 核心内容 学习目标
第一部分 安卓端网络通信基础准备(Kotlin项目创建+权限+核心依赖) 搭建Kotlin版安卓基础项目,解决"安卓能访问后端"的前提问题(权限、依赖)
第二部分 安卓网络请求工具封装(OkHttp3 + Kotlin协程) 掌握Kotlin环境下的主流网络库封装,用协程替代传统子线程,简化异步逻辑
第三部分 登录接口调用(获取JWT令牌)+ 令牌本地存储(Kotlin版) 实现"账号密码→后端验证→获取令牌"全流程,理解JWT在Kotlin端的使用逻辑
第四部分 带令牌调用认证接口(任务/分类查询) 掌握"请求头携带JWT"的Kotlin实现,适配后端auth中间件验证逻辑
第五部分 业务接口CRUD(任务/分类的增、删、改、查) 覆盖完整业务场景,掌握不同请求方式(GET/POST/PUT/DELETE)的Kotlin实现
第六部分 网络异常处理+调试技巧(Kotlin端+后端联调) 解决实战中常见问题,掌握Kotlin环境下的调试方法

二、第四章(第一部分):安卓端网络通信基础准备(Kotlin版)

学习目标

  1. 用Android Studio创建Kotlin版安卓项目(适配后端业务);
  2. 配置安卓网络通信必备的「权限」和「核心依赖」;
  3. 理解Kotlin环境下安卓网络通信的核心原理(协程、空安全等);
  4. 验证安卓端与后端Express的网络连通性(Kotlin代码实现)。

之前教程参考


前置知识回顾

  • 后端已启动:http://localhost:3000(安卓模拟器访问本地后端需用 http://10.0.2.2:3000,原理后文讲);
  • 后端已有核心接口:/api/login(登录)、/api/tasks(任务查询)、/test(测试接口)。

步骤1:创建Kotlin版安卓项目(详细操作)

操作流程(手把手)
  1. 打开Android Studio,点击「New Project」→ 选择「Empty ViewsActivity」→ 点击「Next」;
  2. 配置项目信息:
    • Name:AndroidExpressDemo(项目名,自定义,英文);
    • Package name:com.example.androidexpressdemo(包名,默认即可,安卓唯一标识);
    • Save location:选择本地存储路径(如E:\AndroidProjects);
    • Language:Kotlin(Android官方首选,初学者易上手,语法更简洁);
    • Minimum SDK:选择API 24: Android 7.0 (Nougat)(覆盖95%以上设备);
  3. 点击「Finish」,等待Android Studio自动构建项目(首次构建需下载gradle,耐心等待);
  4. Kotlin项目结构说明(初学者重点关注):
    • app/src/main/AndroidManifest.xml:安卓核心配置文件(权限、组件声明);
    • app/src/main/java/com/example/androidexpressdemo/MainActivity.kt:主界面逻辑(Kotlin代码编写处);
    • app/src/main/res/layout/activity_main.xml:主界面布局(UI控件);
    • app/build.gradle:依赖配置文件(添加网络库、协程等依赖)。
说明
  • Kotlin是Android官方2017年宣布的首选开发语言,相比Java:
    • 语法更简洁(少样板代码,如无需写findViewById);
    • 天然支持空安全(避免空指针异常,初学者踩坑少);
    • 内置协程(优雅处理异步操作,替代Java的Thread);
  • Minimum SDK选7.0:既保证兼容性,又能使用Kotlin协程、OkHttp3等现代API。

步骤2:配置安卓网络权限(必做)

操作流程
  1. 打开app/src/main/AndroidManifest.xml文件;

  2. <manifest>标签内、<application>标签 添加网络权限:

    复制代码
    <!-- 网络访问权限(安卓访问后端必须) -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 允许访问网络状态(可选,用于判断网络是否可用) -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  3. 解除安卓9.0+的"明文网络限制"(后端是http://协议):
    <application>标签内添加android:usesCleartextTraffic="true"

    复制代码
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AndroidExpressDemo"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
原理说明(和Java版一致,补充Kotlin无影响)
  1. 安卓权限机制:所有敏感操作(如网络访问)需在AndroidManifest.xml声明,否则APP崩溃;
  2. 明文网络限制:安卓9.0+默认禁止http://,需usesCleartextTraffic="true"解除;
  3. 权限类型:INTERNET是普通权限,安卓自动授予,无需运行时申请。

📌Android应用中的权限声明

Android 应用清单文件(AndroidManifest.xml)中的权限声明是应用向系统申请访问设备资源 / 功能的核心方式,Android 官方将权限分为 普通权限(Normal)危险权限(Dangerous)特殊权限(Special) 三类,普通权限只需清单声明,危险权限需动态申请,特殊权限需引导用户到系统设置授权,且所有权限需适配对应 Android 版本的行为变更。

➡️更详细内容见附录部分。

步骤3:添加核心依赖(OkHttp3 + Gson + Kotlin协程)

操作流程
  1. 打开app/build.gradle文件(注意是app模块下的,不是项目根目录的);

  2. dependencies代码块中添加依赖(Kotlin需额外添加协程依赖):

    复制代码
    dependencies {
        // 基础Kotlin依赖(默认已有)
        implementation 'androidx.core:core-ktx:1.9.0'
        implementation 'androidx.appcompat:appcompat:1.6.1'
        implementation 'com.google.android.material:material:1.11.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.5'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    
        // 新增:OkHttp3网络请求库(核心)
        implementation 'com.squareup.okhttp3:okhttp:4.12.0'
        // 新增:Gson(JSON解析,后端返回JSON→Kotlin对象)
        implementation 'com.google.code.gson:gson:2.10.1'
        // 新增:Kotlin协程(处理异步网络请求,替代Java的Thread)
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
    }
  3. 点击右上角「Sync Now」按钮,等待Gradle同步依赖(首次同步需下载包,耐心等待);

  4. 同步成功后,查看「External Libraries」,能看到okhttp-4.12.0gson-2.10.1kotlinx-coroutines-android-1.7.3即配置完成。

🧩实际操作界面参考:

添加依赖后,同步前的界面:

同步后,成功界面如下:

📖原理说明(Kotlin专属补充)
  1. OkHttp3:Android官方推荐的网络库,Kotlin/Java调用方式一致,优点是自动处理连接池、超时;
  2. Gson:Google JSON解析库,Kotlin中可快速将JSON转为数据类(Data Class),比Java更简洁;
  3. Kotlin协程:替代Java的Thread,是Kotlin处理异步任务的标准方式------
    • 避免"回调地狱",用同步写法实现异步逻辑;
    • 适配Android主线程规则,自动切换线程(网络请求在子线程,UI更新在主线程)。

📌app/build.gradle文件中依赖的两种书写格式:

写法形式 核心特点
implementation(libs.androidx.core.ktx) 基于 Gradle 版本目录(Version Catalog),依赖版本集中管理,工程级统一维护;这是 Gradle 7.0+ 引入的 Version Catalog 特性 (Android Gradle Plugin 7.0+ 适配),版本号不在 build.gradle 中 ,而是集中写在工程根目录的 libs.versions.toml 文件里
implementation 'androidx.core:core-ktx:1.9.0' 传统直接声明,版本号硬编码在 build.gradle 中,分散管理

💡建议:两种写法都能正确引入依赖,推荐新建项目(AGP 7.0+)优先使用版本目录写法。

步骤4:基础测试------Kotlin版安卓访问Express后端(验证连通性)

前置准备:确保后端正常运行
  1. 启动Express后端(node app.js),确认http://localhost:3000可访问;

  2. 后端添加测试接口(临时):在app.js中添加无需认证的/test接口:

    复制代码
    // 后端app.js
    app.get('/test', (req, res) => {
      res.json({ 
        code: 200, 
        message: '安卓(Kotlin)端连通测试成功', 
        data: { time: new Date().toString() } 
      });
    });

🧩实际操作参考:

修改app.js后,通过浏览器,访问测试地址:localhost:3000/test,显示如下信息:

步骤4.1:修改布局文件(显示请求结果)

打开app/src/main/res/layout/activity_main.xml,添加TextView用于显示请求结果:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="等待请求..."
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

🧩界面设置参考:

步骤4.2:编写Kotlin网络请求代码(协程版)

打开MainActivity.kt,编写核心代码(Kotlin+协程,适配Android最佳实践):

复制代码
package com.example.androidexpressdemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException

class MainActivity : AppCompatActivity() {
    // 日志标签(调试用)
    private val TAG = "NetworkTest"
    // 后端地址:安卓模拟器中localhost映射为10.0.2.2(关键!)
    private val BASE_URL = "http://10.0.2.2:3000"
    
    // 延迟初始化TextView(Kotlin空安全特性,避免空指针)
    private lateinit var tvResult: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 绑定UI控件(Kotlin无需findViewById,直接用id引用,需开启视图绑定或直接引用)
        tvResult = findViewById(R.id.tvResult)

        // 1. 创建OkHttp客户端(全局单例更佳,此处简化)
        val okHttpClient = OkHttpClient()

        // 2. 构建GET请求(访问后端/test接口)
        val request = Request.Builder()
            .url("$BASE_URL/test") // 拼接测试接口地址
            .get() // 指定GET请求(可省略,默认GET)
            .build()

        // 3. 启动协程处理网络请求(Kotlin核心,替代Java的Thread)
        GlobalScope.launch(Dispatchers.Main) {
            // 子线程执行网络请求(Dispatchers.IO:IO密集型任务)
            val responseResult = withContext(Dispatchers.IO) {
                try {
                    // 执行同步请求(OkHttp同步调用,协程中无阻塞问题)
                    val response = okHttpClient.newCall(request).execute()
                    // 获取响应体字符串
                    val responseBody = response.body?.string()
                    // 返回成功结果
                    "请求成功:$responseBody"
                } catch (e: IOException) {
                    // 捕获网络异常
                    e.printStackTrace()
                    "请求失败:${e.message}"
                }
            }

            // 4. 主线程更新UI(Dispatchers.Main:自动切换到主线程)
            tvResult.text = responseResult
            // 日志打印结果(调试用)
            Log.d(TAG, "后端返回:$responseResult")
        }
    }
}

📌相关说明

  • GlobalScope的提示

    • 如下图

    • 警告说明

      • GlobalScope的定义:它是一个全局协程作用域,不绑定任何任务,用于启动 "全应用生命周期" 的协程,但不会保持进程存活(类似守护线程)。

      • 风险点:GlobalScope是 "敏感 API",易引发资源 / 内存泄漏

    解决方案

    • Activity/Fragment 中 :使用lifecycleScope(自动绑定页面生命周期,页面销毁时协程自动取消)

      复制代码
      lifecycleScope.launch(Dispatchers.Main) {
          // 网络请求等操作
      }

      实际代码示例:

    • ViewModel 中 :使用viewModelScope(绑定 ViewModel 生命周期,ViewModel 销毁时协程自动取消)

      复制代码
      viewModelScope.launch(Dispatchers.Main) {
          // 网络请求等操作
      }
  • 语法知识点

    • val:Kotlin 关键字,声明不可变变量 (类似 Java 的 final

    • OkHttpClient:OkHttp 库的核心客户端类,负责管理网络请求的所有配置(如超时时间、拦截器、连接池等)、发起请求、处理响应;

      • OkHttpClient():调用 OkHttpClient无参构造函数 ,创建一个默认配置的客户端实例。
        • 通过无参构造创建的 OkHttpClient 会使用 OkHttp 的默认配置,核心默认值如下:

          配置项 默认值 作用
          连接超时时间 10 秒 客户端与服务器建立连接的最大等待时间
          读取超时时间 10 秒 连接建立后,读取服务器响应数据的最大等待时间
          写入超时时间 10 秒 向服务器写入请求数据的最大等待时间
          连接池 5 个并发连接,5 分钟空闲超时 复用 HTTP 连接(避免重复创建连接,提升性能)
          拦截器 无自定义拦截器(可后续通过 newBuilder() 添加,如日志、请求头拦截)
          重定向策略 允许自动重定向 遇到 3xx 状态码时,自动跳转至新地址
    • Request.Builder().url("$BASE_URL/test") .get() .build()

      • Request:OkHttp 中封装 HTTP 请求的核心类,包含请求的 URL、方法、头信息、请求体等所有参数;
      • Builder():调用 Request构建器构造函数;
      • .url()Request.Builder 的核心方法,用于设置请求的目标 URL;
      • .get():显式指定该请求为 HTTP GET 方法
      • .build()Request.Builder 的最终方法,根据前面配置的参数(URL、请求方法等),生成不可变的 Request 实例;
        • 调用后,构建器的配置会固化到 Request 对象中,无法再修改(如需调整,需重新创建 Builder)。
    • 启动协程处理网络请求

      • lifecycleScope :绑定 Activity/Fragment 生命周期的协程作用域(替代危险的 GlobalScope),页面销毁(onDestroy)时,该作用域下的所有协程会自动取消;

      • launch(Dispatchers.Main)

        • launch:启动一个新的协程(协程构建器);
        • Dispatchers.Main:指定协程的默认调度器为 "主线程(UI 线程)"------ 即协程的代码块默认在主线程执行,且最终结果会回到主线程(方便更新 UI)
      withContext(Dispatchers.IO)
      • withContext :协程的 "挂起函数",作用是切换到指定线程执行代码块,执行完成后切回原线程 ,并将代码块的返回值赋值给 responseResult
      • Dispatchers.IO :协程的 IO 调度器,专门用于处理 IO 密集型任务(网络请求、文件读写、数据库操作等),底层是线程池,自动管理线程复用,避免手动创建 Thread 的繁琐。
      • 核心逻辑:把耗时的网络请求 "丢到 IO 线程执行",执行完后自动切回 launch 指定的主线程。
      okHttpClient.newCall(request).execute()
      • okHttpClient.newCall(request) :将之前构建的 Request 对象包装为 OkHttp 的 Call 对象(表示一次可执行的请求);
      • execute() :OkHttp 的同步请求方法 (区别于 enqueue 异步回调):
        • 同步请求会 "阻塞当前线程",但这里运行在 Dispatchers.IO 线程,因此不会阻塞主线程;
      • response.body?.string()
        • response.body :OkHttp 的响应体对象(ResponseBody),封装服务器返回的数据;
        • ?.string() :安全调用响应体的 string() 方法(避免空指针),将响应体转为字符串(如 JSON 字符串);
          • ⚠️ 注意:string() 只能调用一次(调用后响应体流会关闭),如需多次使用需先保存为变量。
    • "请求成功:$responseBody",在 Kotlin 中,不需要显式写 return 就能返回结果

      • 在 Kotlin 中,带有代码块的 lambda 表达式、匿名函数、普通函数 ,如果没有显式写 return,会默认将代码块的「最后一行语句的结果」作为返回值(前提是代码块有返回类型约束)。
    复制代码
    Log.d(TAG, "后端返回:$responseResult"):在Logcat窗口查看输出的日志信息
步骤4.3:运行测试(验证连通性)
  1. 点击Android Studio顶部「Run」按钮(绿色三角形),选择自带模拟器或真机;

  2. 程序部署到模拟器或真机中,有相关部署提示,如图:

  3. 如果链接出现错误,会提示相关错误,如下图示例,提示失败:

  4. 修正错误:

    1. 10.0.2.2仅适用于「安卓自带模拟器(AVD)」
    第三方模拟器(如夜神、雷电),
    复制代码
      ##### 第三方模拟器不支持`10.0.2.2`,需替换为**模拟器的「桥接 IP」**:
    1. 打开模拟器的「设置→网络→WLAN」,查看模拟器的 IP(如192.168.1.101);

    2. 打开电脑的命令提示符(Win+R 输入cmd),输入ipconfig,找到电脑的「局域网 IP」(如192.168.1.100);

    3. 将url地址更换为本机真实地址(可先在浏览器上测试地址是否正常)

      复制代码
      BASE_URL = "http://192.168.1.100:3000"
    4. 连接「真机」

      1. 确保手机和电脑连接同一 WiFi(同一局域网)
      2. 查看电脑的「局域网 IP」,修改BASE_URL地址,步骤和第三方模拟器的方式相同
    5. 检查确保后端Express服务器启动

  5. 成功会提示:服务器端相应的访问信息如下:


第一部分学习总结(Kotlin版)

完成Kotlin版安卓项目搭建,解决"安卓访问后端"的3个核心问题:

  • 权限:配置INTERNET和明文HTTP允许;
  • 依赖:引入OkHttp3(网络)、Gson(JSON)、协程(异步);
  • 地址:模拟器访问电脑后端;

验证了Kotlin端与Express后端的连通性,为后续接口调用打下基础。


附录

Android权限划分

Android 官方将权限分为 普通权限(Normal)危险权限(Dangerous)特殊权限(Special) 三类,以下是按功能分类的常用权限及核心说明:

一、权限分类基础

类型 特点 申请方式
普通权限 低风险,不涉及用户隐私,系统自动授予 仅清单声明即可
危险权限 高风险,涉及用户隐私 / 设备安全,需动态申请(Android 6.0+ / API 23+) 清单声明 + 运行时动态申请
特殊权限 极高风险(如悬浮窗、后台定位),需通过系统设置单独申请 清单声明 + 引导用户到系统设置页授权

二、常用权限按功能分类详解

1. 网络相关权限(普通权限为主)
权限名称 类型 核心作用
android.permission.INTERNET 普通 允许应用访问互联网(HTTP/HTTPS/WS 等),访问后端必备
android.permission.ACCESS_NETWORK_STATE 普通 获取设备当前网络状态(是否联网、Wi-Fi / 移动数据)
android.permission.ACCESS_WIFI_STATE 普通 获取 Wi-Fi 详细信息(如 SSID、Wi-Fi 连接状态)
android.permission.CHANGE_NETWORK_STATE 普通 修改网络状态(如开启 / 关闭移动数据,部分设备需系统级权限)
android.permission.CHANGE_WIFI_STATE 普通 修改 Wi-Fi 状态(如开启 / 关闭 Wi-Fi、连接指定 Wi-Fi)
android.permission.ACCESS_NETWORK_INFO 普通 兼容旧版本,等效于 ACCESS_NETWORK_STATE(API 1 后废弃,建议用后者)
2. 存储相关权限(危险权限,Android 10+ 有特殊适配)
权限名称 类型 核心作用 适配说明
android.permission.READ_EXTERNAL_STORAGE 危险 读取外部存储(SD 卡 / 共享目录)文件 Android 10+(API 29+)需声明 android:requestLegacyExternalStorage="true" 兼容旧逻辑;Android 13+ 拆分为更细粒度权限
android.permission.WRITE_EXTERNAL_STORAGE 危险 写入文件到外部存储 Android 11+(API 30+)被废弃,推荐用 MediaStore/SAF 替代
android.permission.MANAGE_EXTERNAL_STORAGE 特殊 管理所有外部存储文件(仅系统应用 / 合规应用可申请,需谷歌审核) 需引导用户到系统设置页授权,普通应用不建议使用
android.permission.READ_MEDIA_IMAGES 危险 Android 13+ 读取图片 / 照片(替代 READ_EXTERNAL_STORAGE 仅需动态申请此权限,无需申请旧存储权限
android.permission.READ_MEDIA_VIDEO 危险 Android 13+ 读取视频文件 同上
android.permission.READ_MEDIA_AUDIO 危险 Android 13+ 读取音频文件 同上
3. 位置相关权限(危险 / 特殊权限)
权限名称 类型 核心作用
android.permission.ACCESS_FINE_LOCATION 危险 获取精确位置(GPS / 北斗,精度米级)
android.permission.ACCESS_COARSE_LOCATION 危险 获取粗略位置(基站 / Wi-Fi,精度千米级)
android.permission.ACCESS_BACKGROUND_LOCATION 特殊 应用在后台(非前台)时获取位置 Android 10+ 需单独申请,引导用户授权
android.permission.ACCESS_MOCK_LOCATION 特殊 模拟位置数据(仅调试 / 系统应用可用) 需在开发者选项中开启 "允许模拟位置"
4. 相机 / 媒体相关权限(危险权限)
权限名称 类型 核心作用
android.permission.CAMERA 危险 访问相机硬件(拍照 / 录像)
android.permission.RECORD_AUDIO 危险 录制音频(麦克风访问)
android.permission.USE_FINGERPRINT 普通 访问指纹传感器(指纹识别) Android 9+ 推荐用 USE_BIOMETRIC
android.permission.USE_BIOMETRIC 普通 访问生物识别(指纹 / 人脸 / 虹膜)
5. 电话 / 通讯相关权限(危险 / 普通)
权限名称 类型 核心作用
android.permission.READ_PHONE_STATE 危险 读取手机状态(IMEI / 手机号 / 网络类型 / 通话状态) Android 10+ 需申请 READ_PHONE_NUMBERS 单独读取手机号
android.permission.CALL_PHONE 危险 直接拨打电话(无需用户确认)
android.permission.READ_CALL_LOG 危险 读取通话记录
android.permission.WRITE_CALL_LOG 危险 写入 / 修改通话记录
android.permission.ANSWER_PHONE_CALLS 危险 接听来电(Android 8.0+)
android.permission.SEND_SMS 危险 发送短信
android.permission.READ_SMS 危险 读取短信内容
android.permission.RECEIVE_SMS 危险 接收短信(监听短信广播)
6. 系统 / 设备控制相关权限(普通 / 特殊)
权限名称 类型 核心作用
android.permission.SYSTEM_ALERT_WINDOW 特殊 显示悬浮窗(覆盖其他应用) 需引导用户到 "设置 - 应用 - 权限 - 悬浮窗" 授权
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 特殊 忽略电池优化(应用后台不被杀死) 需动态申请,用户确认后生效
android.permission.WAKE_LOCK 普通 唤醒屏幕 / 保持 CPU 运行(防止应用休眠) 如音乐播放、后台下载时使用
android.permission.VIBRATE 普通 控制设备振动
android.permission.SET_WALLPAPER 普通 设置系统壁纸
7. 日历 / 联系人 / 日程(危险权限)
权限名称 类型 核心作用
android.permission.READ_CONTACTS 危险 读取联系人列表
android.permission.WRITE_CONTACTS 危险 添加 / 修改 / 删除联系人
android.permission.READ_CALENDAR 危险 读取日历事件
android.permission.WRITE_CALENDAR 危险 添加 / 修改 / 删除日历事件
8. 传感器 / 硬件相关(普通权限为主)
权限名称 类型 核心作用
android.permission.BODY_SENSORS 危险 访问身体传感器(心率、步数、体温等)
android.permission.ACCESS_ACCELEROMETER 普通 访问加速度传感器
android.permission.ACCESS_GYROSCOPE 普通 访问陀螺仪传感器
android.permission.ACCESS_MAGNETIC_FIELD 普通 访问磁力计传感器

三、特殊权限声明注意事项

  1. 权限组机制 :危险权限按 "组" 管理,申请组内任一权限时,用户授权后组内所有权限均被授予(如申请 READ_CONTACTS,则 WRITE_CONTACTS 也会被授权);
  2. 权限声明位置 :所有 <uses-permission> 必须放在 <manifest> 根节点下、<application> 节点外;
  3. 版本适配
    • Android 6.0+(API 23):危险权限需动态申请,普通权限仍自动授予;
    • Android 13+(API 33):存储权限拆分为图片 / 视频 / 音频细粒度权限,无需申请旧存储权限;
    • 声明高版本权限时,可通过 android:maxSdkVersion 限制仅在指定版本生效(如 <uses-permission android:name="xxx" android:maxSdkVersion="32"/>);
  4. 权限优先级<uses-permission-sdk-23> 仅在 API 23+ 生效,优先级高于普通 <uses-permission>
  5. 权限拒绝处理:需处理用户拒绝权限的场景,避免应用崩溃,核心权限建议引导用户重新授权。

四、如何快速查询所有官方权限

  1. 安卓官方文档:Android 权限列表
  2. 开发工具:Android Studio 中输入 android.permission. 会自动提示所有系统权限;
  3. 设备层面:/system/etc/permissions/platform.xml 文件可查看设备支持的所有权限。

总结

清单文件中的权限声明需遵循 "最小权限原则"------ 仅声明应用必需的权限,避免过度申请隐私权限(否则会被应用商店审核拒绝,或降低用户信任)。普通权限只需清单声明,危险权限需动态申请,特殊权限需引导用户到系统设置授权,且所有权限需适配对应 Android 版本的行为变更。

相关推荐
老蒋新思维2 小时前
创客匠人峰会深度解析:知识变现的 “IP 资产化” 革命 —— 从 “运营流量” 到 “沉淀资产” 的长期增长逻辑
大数据·人工智能·网络协议·tcp/ip·创始人ip·创客匠人·知识变现
瀚岳-诸葛弩2 小时前
对比tensorflow,从0开始学pytorch(三)--自定义层
人工智能·pytorch·tensorflow
正经教主2 小时前
【Trae+AI】和Trae学习搭建App_1.2:第2章·App开发环境配置
android·学习·android studio
测试人社区-小明2 小时前
AI在金融软件测试中的实践
人工智能·测试工具·金融·pycharm·机器人·github·量子计算
小哲慢慢来2 小时前
机器学习基本概念
人工智能·机器学习
张较瘦_2 小时前
[论文阅读] AI + 软件工程 | 叙事的力量+专家智慧:解锁定性软件工程研究的过去、现在与未来
论文阅读·人工智能·软件工程
算法与编程之美2 小时前
机器学习测试模型的性能评估与探索
人工智能·机器学习
小毅&Nora2 小时前
【人工智能】【深度学习】 ⑩ 图神经网络(GNN)从入门到工业落地:消息传递、稀疏计算与推荐/风控实战
人工智能·深度学习·图神经网络gnn
zhangfeng11332 小时前
大语言模型Ll M 这张图的核心信息是:随着模型规模变大,注意力(attention)层消耗的 FLOPs 占比越来越高,而 MLP 层占比反而下降。
人工智能