使用 Flutter 在 Windows 平台开发 Android 应用

以下是完整的开发流程,包括环境搭建、代码实现和应用发布,帮助你开发一个具有地图显示、TCP 通信功能的 Android 应用。

一、环境搭建

1. 安装 Flutter SDK
  • Flutter 官网 下载最新稳定版 SDK
  • 解压到本地目录(如 D:\flutter
  • 添加环境变量:
    • FLUTTER_ROOT = D:\flutter
    • PATH 中添加 %FLUTTER_ROOT%\bin
2. 安装 Android Studio
  • 官网 下载并安装 Android Studio
  • 安装过程中选择安装 Android SDKAndroid SDK Command-line ToolsAndroid Virtual Device
3. 配置 Android SDK
  • 打开 Android Studio → SDK Manager
  • 安装 Android 11 (R) 或更高版本
  • 安装 Google Play servicesGoogle Maps Android API
4. 安装 Flutter 和 Dart 插件
  • 在 Android Studio 中,打开 File → Settings → Plugins
  • 搜索并安装 FlutterDart 插件
  • 重启 Android Studio
5. 验证环境配置

bash

复制代码
flutter doctor

根据提示安装缺失的依赖(如 Android SDK 命令行工具、启用 USB 调试等)

二、创建 Flutter 项目

bash

复制代码
flutter create map_tcp_app
cd map_tcp_app

三、添加依赖

pubspec.yaml 中添加以下依赖:

yaml

复制代码
dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.4.0      # 地图组件
  location: ^5.0.4                 # 位置服务
  permission_handler: ^10.4.3      # 权限管理
  tcp_socket_connection: ^1.0.3    # TCP通信
  provider: ^6.0.5                 # 状态管理
  fluttertoast: ^8.2.2             # 消息提示

运行 flutter pub get 安装依赖。

四、配置 AndroidManifest.xml

android/app/src/main/AndroidManifest.xml 中添加:

xml

复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 添加权限 -->
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  
  <application
    android:label="map_tcp_app"
    android:icon="@mipmap/ic_launcher">
    
    <!-- 添加 Google Maps API 密钥 -->
    <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="YOUR_GOOGLE_MAPS_API_KEY"/>
      
    <activity
      android:name=".MainActivity"
      android:launchMode="singleTop"
      android:theme="@style/LaunchTheme"
      android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
      android:hardwareAccelerated="true"
      android:windowSoftInputMode="adjustResize">
      <!-- 确保应用可以处理深层链接 -->
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>
  </application>
</manifest>

注意 :需要替换 YOUR_GOOGLE_MAPS_API_KEY 为你在 Google Cloud Console 获取的 API 密钥。

五、实现地图与 TCP 通信功能

1. 状态管理(Provider)

创建 lib/providers/connection_provider.dart

dart

复制代码
import 'package:flutter/material.dart';
import 'package:tcp_socket_connection/tcp_socket_connection.dart';

class ConnectionProvider with ChangeNotifier {
  late TcpSocketConnection _socket;
  bool _isConnected = false;
  String _serverMessage = '';
  String _serverIP = '15.113.126.155';
  int _serverPort = 5001;

  ConnectionProvider() {
    _initSocket();
  }

  void _initSocket() {
    _socket = TcpSocketConnection(_serverIP, _serverPort);
    
    _socket.connect().then((status) {
      _isConnected = status;
      if (status) {
        _serverMessage = '已连接到服务器';
        _startListening();
      } else {
        _serverMessage = '连接失败';
      }
      notifyListeners();
    });
  }

  void _startListening() {
    _socket.onMessageReceived((data) {
      _serverMessage = '服务器: $data';
      notifyListeners();
    });
  }

  void sendMessage(String message) {
    if (_isConnected) {
      _socket.sendMessage(message);
    }
  }

  void disconnect() {
    if (_isConnected) {
      _socket.disconnect();
      _isConnected = false;
      _serverMessage = '已断开连接';
      notifyListeners();
    }
  }

  void reconnect(String ip, int port) {
    _serverIP = ip;
    _serverPort = port;
    disconnect();
    _initSocket();
  }

  bool get isConnected => _isConnected;
  String get serverMessage => _serverMessage;
  String get serverIP => _serverIP;
  int get serverPort => _serverPort;
}
2. 主页面实现

修改 lib/main.dart

dart

复制代码
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'providers/connection_provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ConnectionProvider()),
      ],
      child: const MyApp(),
    ),
  );
}

六、自定义协议实现

lib/utils/protocol.dart 中添加:

复制代码
import 'dart:convert';
import 'dart:typed_data';

class Protocol {
  // 协议头标识
  static const int headerFlag = 0x55AA;
  
  // 构建消息包
  static Uint8List buildMessage(String content) {
    final contentBytes = utf8.encode(content);
    final buffer = ByteData(8 + contentBytes.length);
    
    // 设置协议头标识
    buffer.setUint16(0, headerFlag, Endian.big);
    
    // 设置消息长度
    buffer.setUint32(2, contentBytes.length, Endian.big);
    
    // 设置消息类型 (1: 文本消息)
    buffer.setUint16(6, 1, Endian.big);
    
    // 设置消息内容
    for (int i = 0; i < contentBytes.length; i++) {
      buffer.setUint8(8 + i, contentBytes[i]);
    }
    
    return buffer.buffer.asUint8List();
  }
  
  // 解析消息包
  static String? parseMessage(Uint8List data) {
    if (data.length < 8) return null;
    
    final buffer = ByteData.view(data.buffer);
    
    // 验证协议头
    final flag = buffer.getUint16(0, Endian.big);
    if (flag != headerFlag) return null;
    
    // 获取消息长度
    final length = buffer.getUint32(2, Endian.big);
    
    // 验证数据长度
    if (data.length < 8 + length) return null;
    
    // 获取消息内容
    final contentBytes = data.sublist(8, 8 + length);
    return utf8.decode(contentBytes);
  }
}

更新 ConnectionProvider 中的消息处理:

dart

复制代码
// 在 ConnectionProvider 类中更新
void _startListening() {
  _socket.onMessageReceived((data) {
    final message = Protocol.parseMessage(Uint8List.fromList(data.codeUnits)) ?? data;
    _serverMessage = '服务器: $message';
    notifyListeners();
  });
}

void sendMessage(String message) {
  if (_isConnected) {
    final packet = Protocol.buildMessage(message);
    _socket.sendMessage(String.fromCharCodes(packet));
  }
}

七、编译与发布

1. 调试运行

bash

复制代码
flutter run
2. 生成 Android APK

bash

复制代码
flutter build apk --release

APK 文件将生成在 build/app/outputs/apk/release/app-release.apk

3. 生成 App Bundle(推荐)

bash

复制代码
flutter build appbundle --release

App Bundle 文件将生成在 build/app/outputs/bundle/release/app-release.aab,可上传至 Google Play 商店。

八、应用优化建议

  1. 错误处理

    • 添加网络异常捕获和重连机制
    • 实现超时处理(如连接超时、发送超时)
  2. UI 优化

    • 添加加载状态指示器
    • 优化地图标记样式和信息窗口
  3. 性能优化

    • 使用 ListView.builder 优化消息显示
    • 实现消息缓存机制,避免频繁刷新
  4. 安全性

    • 考虑使用 TLS 加密 TCP 通信
    • 实现消息校验和认证机制

通过以上步骤,你可以在 Windows 平台使用 Android Studio 和 Flutter 开发一个完整的 Android 应用,实现地图显示、TCP 通信和自定义协议功能。

相关推荐
小锋学长生活大爆炸4 分钟前
【教程】Windows安全中心扫描设置排除文件
windows·安全·系统·扫描·病毒·安全中心
移动开发者1号27 分钟前
Android 多 BaseUrl 动态切换策略(结合 ServiceManager 实现)
android·kotlin
移动开发者1号29 分钟前
Kotlin实现文件上传进度监听:RequestBody封装详解
android·kotlin
এ᭄画画的北北30 分钟前
力扣-279.完全平方数
数据结构·算法·leetcode
抽风的雨6101 小时前
【python深度学习】Day53 对抗生成网络
python·深度学习
技术蔡蔡1 小时前
从Google IO学习Flutter
flutter·google·google io
Elastic 中国社区官方博客1 小时前
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
大数据·开发语言·javascript·elasticsearch·搜索引擎·全文检索·apache
程序小武1 小时前
Python 面向对象编程基础-类的创建与__init__实例化
python
Qyee161 小时前
【算法】基于中位数和MAD鲁棒平均值计算算法
python·算法
GalaxyPokemon1 小时前
LeetCode - 69. x 的平方根
java·数据结构·算法