Android集成 #

一、环境要求 #

1.1 开发环境 #

工具 版本要求
JDK 17+
Android Studio Flamingo (2022.2.1)+
Android SDK API 22+
Gradle 7.x+

1.2 安装JDK #

bash
# macOS
brew install openjdk@17

# 配置环境变量
echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc

1.3 安装Android Studio #

  1. 下载Android Studio
  2. 安装Android SDK
  3. 配置环境变量
bash
# ~/.zshrc 或 ~/.bashrc
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin

二、添加Android平台 #

2.1 添加平台 #

bash
# 添加Android平台
npx cap add android

# 同步更新
npx cap sync android

2.2 打开Android Studio #

bash
npx cap open android

三、项目结构 #

3.1 目录结构 #

text
android/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/company/app/
│   │   │   │   └── MainActivity.java
│   │   │   ├── res/
│   │   │   │   ├── values/
│   │   │   │   │   ├── strings.xml
│   │   │   │   │   └── styles.xml
│   │   │   │   ├── mipmap-*/
│   │   │   │   │   └── ic_launcher.png
│   │   │   │   └── xml/
│   │   │   │       └── network_security_config.xml
│   │   │   └── AndroidManifest.xml
│   │   ├── debug/
│   │   └── release/
│   └── build.gradle
├── gradle/
├── build.gradle
├── settings.gradle
├── gradle.properties
└── local.properties

四、Gradle配置 #

4.1 项目级build.gradle #

groovy
// android/build.gradle
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.1.0'
        classpath 'com.google.gms:google-services:4.3.15'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

4.2 应用级build.gradle #

groovy
// android/app/build.gradle
apply plugin: 'com.android.application'

android {
    namespace "com.company.myapp"
    compileSdkVersion rootProject.ext.compileSdkVersion
    
    defaultConfig {
        applicationId "com.company.myapp"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

repositories {
    flatDir {
        dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
    implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
    implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
    
    implementation project(':capacitor-android')
    
    testImplementation "junit:junit:$junitVersion"
    androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
    androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
    implementation project(':capacitor-cordova-android-plugins')
}

apply from: 'capacitor.build.gradle'

4.3 变量定义 #

groovy
// android/build.gradle
ext {
    minSdkVersion = 22
    compileSdkVersion = 33
    targetSdkVersion = 33
    androidxAppCompatVersion = '1.6.1'
    androidxCoordinatorLayoutVersion = '1.2.0'
    androidxCoreVersion = '1.10.0'
    androidxFragmentVersion = '1.5.6'
    coreSplashScreenVersion = '1.0.0'
    junitVersion = '4.13.2'
    androidxJunitVersion = '1.1.5'
    androidxEspressoCoreVersion = '3.5.1'
}

五、AndroidManifest.xml #

5.1 基本配置 #

xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.myapp">

    <!-- 基本权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    
    <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/AppTheme"
        android:usesCleartextTraffic="true"
        android:networkSecurityConfig="@xml/network_security_config">

        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

    </application>

</manifest>

5.2 权限配置 #

xml
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />

<!-- 存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- Android 13+ 媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

<!-- 位置权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<!-- 网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- 震动 -->
<uses-permission android:name="android.permission.VIBRATE" />

<!-- 录音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- 蓝牙 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

<!-- 通知 (Android 13+) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<!-- 开机启动 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<!-- 前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

5.3 深度链接 #

xml
<activity android:name=".MainActivity" ...>
    
    <!-- 自定义Scheme -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="myapp" />
    </intent-filter>
    
    <!-- App Links -->
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="example.com" />
    </intent-filter>
    
</activity>

六、MainActivity配置 #

6.1 基本MainActivity #

java
package com.company.myapp;

import android.os.Bundle;
import com.getcapacitor.BridgeActivity;

public class MainActivity extends BridgeActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

6.2 注册自定义插件 #

java
package com.company.myapp;

import android.os.Bundle;
import com.getcapacitor.BridgeActivity;
import com.company.myapp.plugins.MyCustomPlugin;

public class MainActivity extends BridgeActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // 注册自定义插件
        registerPlugin(MyCustomPlugin.class);
        
        super.onCreate(savedInstanceState);
    }
}

6.3 处理Intent #

java
package com.company.myapp;

import android.content.Intent;
import android.os.Bundle;
import com.getcapacitor.BridgeActivity;

public class MainActivity extends BridgeActivity {
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        
        // 处理深度链接
        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            String data = intent.getDataString();
            handleDeepLink(data);
        }
    }
    
    private void handleDeepLink(String url) {
        // 处理深度链接
    }
}

七、网络安全配置 #

7.1 创建配置文件 #

xml
<!-- android/app/src/main/res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- 允许明文HTTP -->
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    
    <!-- 或限制特定域名 -->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="true">192.168.1.100</domain>
    </domain-config>
</network-security-config>

7.2 在Manifest中引用 #

xml
<application
    android:networkSecurityConfig="@xml/network_security_config"
    ...>

八、应用图标 #

8.1 图标尺寸 #

密度 尺寸 目录
mdpi 48x48 mipmap-mdpi
hdpi 72x72 mipmap-hdpi
xhdpi 96x96 mipmap-xhdpi
xxhdpi 144x144 mipmap-xxhdpi
xxxhdpi 192x192 mipmap-xxxhdpi

8.2 使用cordova-res #

bash
npm install -g cordova-res

# 生成图标
cordova-res android --skip-config --copy

8.3 使用Android Studio #

  1. 右键res目录
  2. New → Image Asset
  3. 配置图标

九、签名配置 #

9.1 创建签名密钥 #

bash
keytool -genkey -v -keystore my-release-key.jks \
    -keyalg RSA -keysize 2048 -validity 10000 \
    -alias my-alias

9.2 配置签名 #

groovy
// android/app/build.gradle
android {
    ...
    
    signingConfigs {
        release {
            storeFile file('my-release-key.jks')
            storePassword 'your-store-password'
            keyAlias 'my-alias'
            keyPassword 'your-key-password'
        }
    }
    
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

9.3 使用环境变量 #

groovy
signingConfigs {
    release {
        storeFile file(System.getenv("KEYSTORE_FILE") ?: 'my-release-key.jks')
        storePassword System.getenv("KEYSTORE_PASSWORD")
        keyAlias System.getenv("KEY_ALIAS")
        keyPassword System.getenv("KEY_PASSWORD")
    }
}

十、构建和发布 #

10.1 构建APK #

bash
# 通过Android Studio
Build → Build Bundle(s) / APK(s) → Build APK(s)

# 通过命令行
cd android
./gradlew assembleDebug
./gradlew assembleRelease

10.2 构建AAB #

bash
# 通过Android Studio
Build → Generate Signed Bundle / APK

# 通过命令行
./gradlew bundleRelease

10.3 上传到Google Play #

  1. 打开Google Play Console
  2. 创建应用
  3. 上传AAB文件
  4. 填写商店信息
  5. 发布

十一、调试技巧 #

11.1 使用Chrome调试 #

  1. 打开 chrome://inspect
  2. 选择设备和WebView
  3. 开始调试

11.2 Logcat日志 #

bash
# 查看日志
adb logcat

# 过滤日志
adb logcat | grep "MyApp"

# 清除日志
adb logcat -c

11.3 断点调试 #

在Android Studio中设置断点,进行原生代码调试。

十二、总结 #

12.1 关键配置 #

配置项 文件
应用信息 AndroidManifest.xml
权限声明 AndroidManifest.xml
构建配置 build.gradle
主Activity MainActivity.java
网络安全 network_security_config.xml

12.2 下一步 #

了解Android集成后,让我们学习 Web平台

最后更新:2026-03-28