2、开发环境搭建:Android Studio配置、模拟器设置、项目创建与依赖管理、权限声明

好,咱们正式开始动手了。这一章我带你搭好开发环境。别小看这一步,我见过太多新手卡在环境上,代码写好了跑不起来,急得直跺脚。说白了,环境搭得顺,后面才能一路畅通。

2.1 Android Studio 配置:选对版本,少走弯路

我个人习惯用 Android Studio Hedgehog(2023.1.1) 或更新的版本。为什么?因为旧版本对 Gradle 和 AGP(Android Gradle Plugin)的支持不够好,你后面加依赖库时容易踩坑。

安装时注意几点:

  • SDK 路径不要有中文。我曾经帮一个学员排查问题,折腾了半天,最后发现他的 SDK 装在「D:\开发工具\Android」——那个「开发工具」里的中文导致编译报错。嗯,血的教训。
  • JDK 版本选 17。Android Studio 自带的 JDK 就是 17,别自己乱改。你非要用 JDK 11 也行,但有些新特性用不了,没必要。
  • 开启 Gradle JDK 自动下载。在 Settings → Build, Execution, Deployment → Build Tools → Gradle 里,把 Gradle JDK 设为「Download from 项目根目录」。这样项目会自动匹配 JDK 版本,省心。
小技巧:第一次启动 Studio 时,它会自动下载 SDK。如果你网络不好,可以手动从 https://developer.android.com/studio 下载 SDK Platform-Tools 和对应 API 级别的 system-images。我一般提前下好,省得等。

2.2 模拟器设置:别用默认配置

很多人直接点「Run」就跑模拟器,结果卡成幻灯片。你想想看,模拟器本质上是虚拟机,它要模拟 CPU、GPU、内存、传感器……默认配置往往只给 1.5GB 内存,跑个联系人应用还行,但如果你后面要测试大量联系人数据加载,肯定卡。

我的建议:

  • 创建 Pixel 6 或 Pixel 7 的 AVD。这些设备的 API 级别高(至少 API 33),而且屏幕比例主流。
  • 内存至少 2GB,最好 3GB。在 AVD 编辑界面 → Advanced Settings → Memory and Storage 里调。
  • 开启 Hardware - GLES 2.0 或 3.0。这样界面渲染更流畅,不会出现界面闪烁。
  • 如果电脑配置一般,用 x86 镜像。ARM 镜像虽然兼容性好,但慢。x86 镜像配合 Intel HAXM 或 Windows Hyper-V,启动速度能快 3 倍。
注意:模拟器里测试联系人权限时,记得在「设置 → 应用 → 你的应用 → 权限」里手动授予。模拟器默认不会弹权限申请框,我第一次做联系人项目时,代码里明明写了权限请求,但模拟器就是不弹,后来才发现是模拟器版本太老。建议用 API 33+ 的镜像。

2.3 项目创建:从模板到空项目

打开 Android Studio,点击「New Project」。我建议选 Empty Views Activity(不是 Empty Activity)。为什么?因为 Empty Activity 会默认生成 Compose 代码,而我们这个课程主要用传统的 XML 布局 + View 体系。你如果选了 Compose 模板,后面还得改一堆配置,没必要。

项目名我建议叫 ContactsSystem,包名用 com.example.contactssystem。注意包名要小写,不要用下划线。我见过有人写 com.example.contacts_system,结果在 AndroidManifest 里引用资源时各种报错——因为资源文件名不能有大写或下划线,但包名可以?其实包名可以,但容易混淆,干脆统一小写驼峰。

创建完成后,等 Gradle 同步完成。这时你会看到项目结构:

  • app/src/main/java/ — 你的 Kotlin/Java 代码
  • app/src/main/res/ — 布局、图片、字符串等资源
  • app/src/main/AndroidManifest.xml — 权限声明、Activity 注册
  • build.gradle.kts (项目级) — 仓库、插件版本
  • app/build.gradle.kts — 依赖管理、SDK 版本

2.4 依赖管理:加好库,少写代码

联系人系统开发,你不需要从零写 ContentProvider 查询。Android 已经提供了 ContactsContract 这个 API,但为了简化操作,我建议加两个依赖库:

// app/build.gradle.kts
dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.11.0")
    
    // 联系人相关:用于简化权限处理和联系人查询
    implementation("androidx.activity:activity-ktx:1.8.2")
    implementation("androidx.fragment:fragment-ktx:1.6.2")
    
    // 如果你需要异步加载联系人数据,可以加协程
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
}

这里我特别提一下 activity-ktxfragment-ktx。它们提供了 registerForActivityResult 这个 API,用来处理权限请求。以前我们用 onRequestPermissionsResult 回调,代码又臭又长。现在一行代码就能搞定。嗯,Google 终于干了件好事。

核心要点:依赖库版本要统一。比如 core-ktx 1.12.0 和 appcompat 1.6.1 是兼容的。你如果混用 1.9.0 和 1.5.0,编译时可能报「Duplicate class」错误。我建议去 AndroidX 版本页面 查看兼容矩阵。

2.5 权限声明:READ_CONTACTS / WRITE_CONTACTS

这是本章的重头戏。联系人数据属于用户隐私,Android 从 6.0(API 23)开始引入了运行时权限。也就是说,你光在 AndroidManifest 里声明还不够,还得在代码里动态请求。

首先,在 AndroidManifest.xml 里添加:

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

注意顺序:READ_CONTACTS 和 WRITE_CONTACTS 是两个独立的权限。如果你只读不写,可以只声明 READ_CONTACTS。但我们的系统要支持增删改联系人,所以两个都要。

然后,在 Activity 或 Fragment 里请求权限。我用 registerForActivityResult 的方式:

class MainActivity : AppCompatActivity() {
    
    private val requestPermissionLauncher = 
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
            val allGranted = permissions.values.all { it }
            if (allGranted) {
                // 权限已授予,开始加载联系人
                loadContacts()
            } else {
                // 权限被拒绝,可以提示用户去设置里手动开启
                Toast.makeText(this, "需要联系人权限才能使用此功能", Toast.LENGTH_LONG).show()
            }
        }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 检查权限
        if (checkSelfPermission(android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED &&
            checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
            loadContacts()
        } else {
            requestPermissionLauncher.launch(
                arrayOf(
                    android.Manifest.permission.READ_CONTACTS,
                    android.Manifest.permission.WRITE_CONTACTS
                )
            )
        }
    }
    
    private fun loadContacts() {
        // 这里先留空,下一章我们实现具体查询
    }
}
避坑指南:我曾经在项目里遇到一个诡异的问题——权限明明已经授予了,但查询联系人时还是返回空。后来发现是因为我在 onCreate 里直接调用了 loadContacts(),但那时 Activity 还没完全初始化,ContentResolver 还没准备好。解决方案:把加载逻辑放到 onResume 里,或者用 lifecycleScope.launchWhenResumed

2.6 知识体系总览

下面这张图帮你理清本章的知识结构。别被吓到,其实就四个模块:

开发环境搭建 Android Studio 配置 模拟器设置 项目创建与依赖 权限声明 SDK路径无中文 JDK 17 内存≥2GB x86镜像 Empty Views Activity 包名小写驼峰 Manifest声明 运行时请求

这张图里,四个分支最终都指向「开发环境搭建」这个核心。你按这个顺序来:先配好 Studio,再建模拟器,然后创建项目并加依赖,最后声明权限。一步都不能跳。

2.7 验证环境:跑一个空应用

配置完成后,别急着写代码。先跑一个空应用,验证环境是否正常。

  1. 点击工具栏的绿色三角形「Run」。
  2. 选择你刚才创建的模拟器。
  3. 等待 Gradle 构建、安装、启动。
  4. 如果看到模拟器上出现一个空白界面(带「Hello World!」),说明环境搭建成功。

如果遇到「INSTALL_FAILED_INSUFFICIENT_STORAGE」错误,别慌。这是模拟器存储空间不够。在 AVD 编辑界面里,把「Internal Storage」调到 2GB 以上就行。我一般设 4GB,省得后面装几个应用就满了。

总结一下:环境搭建就三步——装 Studio、建模拟器、配项目。权限声明是联系人系统的第一道门槛,别嫌麻烦。下一章我们就要真正开始读取联系人数据了,到时候你会感谢现在认真配环境的自己。

公众号:蓝海资料掘金营,微信deep3321