Flutter:打包apk,详细图文介绍

困扰了一天,终于能正常打包apk安装了,记录下打包的流程。建议参考我这篇文章时,同时看下官网的构建说明。
官网构建并发布 Android 应用详情

1、AS创建Flutter项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、cmd执行命令
生成一个sunluyi.jks的文件,可以自行把sunluyi替换)
-alias sunluyi(别名),方便管理都用一个名字

keytool -genkey -v -keystore sunluyi.jks -keyalg RSA -keysize 2048 -validity 10000 -alias sunluyi

在这里插入图片描述
然后你会得到一个命名sunluyi.jks的文件
在这里插入图片描述

3、cmd执行命令,查看文件详情

keytool -list -v -keystore sunluyi.jks

在这里插入图片描述

4、把生成好的.jks文件放在Flutter项目android/app目录下
并在android目录下手动创建key.properties文件

在这里插入图片描述
key.properties文件内容就是第二步自己设置的口令密码和别名storeFile对应的文件路径./sunluyi.jks(app目录)

storePassword=sunluyi
keyPassword=sunluyi
keyAlias=sunluyi
storeFile=./sunluyi.jks

5、修改/android/app/build.gradle文件
下边代码中我标注了哪些是新增的内容,哪些是修改的内容

plugins {
    id "com.android.application"
    id "kotlin-android"
    // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
    id "dev.flutter.flutter-gradle-plugin"
}

// 新增内容 ↓
def localProperties = new Properties()
def localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader("UTF-8") { reader ->
        localProperties.load(reader)
    }
}

def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
    flutterVersionCode = "1"
}

def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
    flutterVersionName = "1.0"
}

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

// 新增内容↑

android {
    namespace = "com.sunluyi.app.flutter_sunluyi"
    compileSdk = flutter.compileSdkVersion
    ndkVersion = flutter.ndkVersion

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId = "com.sunluyi.app.flutter_sunluyi"
        // You can update the following values to match your application needs.
        // For more information, see: https://flutter.dev/to/review-gradle-config.
        minSdk = flutter.minSdkVersion
        targetSdk = flutter.targetSdkVersion
        // 修改内容 ↓
        versionCode = flutterVersionCode.toInteger()
        versionName = flutterVersionName
        // 修改内容 ↑
    }

    // 新增内容 ↓
    signingConfigs {
        release {
            keyAlias = keystoreProperties['keyAlias']
            keyPassword = keystoreProperties['keyPassword']
            storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword = keystoreProperties['storePassword']
        }
    }

    // 新增内容 ↑

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            // 修改内容 ↓
            signingConfig = signingConfigs.release
            // 修改内容 ↑
        }
    }
}

flutter {
    source = "../.."
}

6、最后你可能还需要配置应用的权限
/android/app/src/main/AndroidManifest.xml目录

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="[project]"
        ...
    </application>
    ...
    // 这里是新增的权限
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

最后根目录执行flutter build apk打包成apk文件。

打包时有个提示警告:

Warning: SDK processing. This version only understands SDK XML versions up to 3 but an SDK XML file of version 4 was encountered. This can happen if you use versions of Android Studio and the command-line tools that were released at different times.
记录下如何解决。

1cmd执行:flutter doctor -v

下图是我解决过警告的,最开始是Platform android-35, build-tools 34.0.0
在这里插入图片描述
百度了下解决方案:
设置/Android SDK中最开始我是勾选的35,换成下方的勾选之后,再次执行
flutter doctor -v得到:Platform android-35, build-tools 34.0.0
在这里插入图片描述
重新执行flutter build apk后没有警告,完成了打包流程。
在这里插入图片描述

关于混淆

自己还不清楚哪些插件需要混淆,也不太理解混淆的意思,先不记录。
这篇文章内容我是创建的新项目进行打包测试的。
后边把自己用到的第三方插件在pubspec.yaml配置后,也是可以正常打包安装的。

我的运行环境,希望这篇文章能对你有所帮助

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946548.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【电源专题】LDO关键DC参数——效率

在讲到电源的效率方面,很多时候网上最经常看到的是“LDO的效率低,开关电源效率高,所以LDO需要更大的散热器来帮助耗散热能”。 比如如下所示为网上找到的一些总结,一般也是大家所熟知的: 是的,这描述在一定的使用条件下是正确对的,但并不完全对,因为不同的工作…

互联网直播点播平台EasyDSS无人机视频推拉流技术实现工地远程监控巡检直播

在建筑行业&#xff0c;施工现场的安全管理和实时监控一直是项目管理中的重点。随着技术的进步&#xff0c;无人机工地直播技术成为了一种新兴的解决方案&#xff0c;它不仅能够提高施工透明度&#xff0c;还能够加强现场安全管理。EasyDSS作为一种先进的流媒体技术平台&#x…

9.若依-自定义表单构建

表单构建工具&#xff0c;开发者通过图形界面和拖拽等操作&#xff0c;可以快速构建复杂的表单。 需求&#xff1a;做一些复杂的功能提交&#xff0c;涉及到多张标的数据提交。 自定义一个特殊表单页面 1.拖拉一个布局组件中行容器&#xff0c;然后在组件属性中设置表单删格在…

芊芊测字,免费测字,ai测字(1.0)

纯娱乐 芊芊测字网站&#xff1a;芊芊测字-ai免费测字

【Leecode】Leecode刷题之路第98天之验证二叉搜索树

题目出处 98-验证二叉搜索树-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 98-验证二叉搜索树-官方解法 方法1&#xff1a;递归 思路&#xff1a; 代码示例&#xff1a;&#xff08;J…

[Qt] 信号和槽(1) | 本质 | 使用 | 自定义

目录 一、信号和槽概述 二、本质 底层实现 1. 函数间的相互调用 2. 类成员中的特殊角色 三、使用 四. 自定义信号和槽 1. 基本语法 (1) 自定义信号函数书写规范 (2) 自定义槽函数书写规范 (3) 发送信号 (4) 示例 A. 示例一 B. 示例二 —— 老师说“上课了”&…

高效使用 cursor

设置 cursor 基础规则&#xff1a; 在 settings > General > Rules for AI 中设置自定义规则&#xff0c;以后 cursor 生成代码会基于该规则生成&#xff1b; 如果要编写复杂代码&#xff0c;可以在项目根目录创建一个 .cursorrules 文件&#xff0c;设置复杂的规则&…

【Kafka 消息队列深度解析与应用】

Kafka 消息队列深度解析与应用 一、Kafka 概述 &#xff08;一&#xff09;产生背景 Kafka 最初是由 LinkedIn 开发&#xff0c;旨在解决其内部海量数据的实时传输问题。在现代大数据环境下&#xff0c;企业需要处理海量的数据流入和流出&#xff0c;包括用户的行为数据、系…

【无线传感网】无线传感器网络覆盖技术

文章目录 覆盖算法设计思路及性能评价标准覆盖感知模型布尔感知模型概率感知模型 无线传感网络覆盖算法分类按照配置方式确定性覆盖随机性覆盖 根据覆盖目标面覆盖点覆盖栅栏覆盖 典型的WSN覆盖算法与协议基于网格的覆盖定位传感器配置算法圆周覆盖连通传感器覆盖轮换活跃/休眠…

canvas+fabric实现时间刻度尺(二)

前言 我们前面实现了时间刻度尺&#xff0c;鼠标移动显示时间&#xff0c;接下来我们实现鼠标点击某个时间进行弹框。 效果 实现 1.监听鼠标按下事件 2.编写弹框页面 3.时间转换 <template><div><canvas id"rulerCanvas" width"1200"…

Python-MNE-源空间和正模型04:头模型和前向计算

我们知道&#xff0c;在MNE分析中坐标是很重要的&#xff0c;这个前面也提及过了配准的一些方法&#xff0c;总的来说&#xff0c;MNE和freesurfer中使用的配准系统以及他们之间的关系如下图所示&#xff1a;除了传感器坐标之外&#xff0c;所有的坐标系都是笛卡尔坐标系&#…

Linux 内核调试

系列文章目录 Linux内核学习 Linux 知识 QEMU 虚拟机 Linux 调试视频 近阶段补充知识 WSL Ubuntu 文章目录 系列文章目录一、WSL二、QEMU1、安装2、退出 三、构建根文件系统1、下载 BusyBox2、编译3、构建文件目录&#xff1a;Makefileinit 四、内核编译1、下载2、构建 五、调试…

SpringBoot 事务

前情提要 飞书的文档不好转移,可以直接看我的飞书:Docs 什么是事务 是一组操作的集合,是一个不可分割的操作 事物会将所有操作当作一个整体,同时对数据库进行操作请求,这些操作要么全部成功,要么全部失败 总会有一些操作,需要同步进行,这个时候就需要使用事务 数据库中,自…

汇川Easy系列正弦信号发生器(ST源代码)

正弦余弦信号发生器CODESYS和MATLAB实现请参考下面文章链接: 正弦余弦信号发生器应用(CODESYS ST源代码+MATLAB仿真)_st语言根据输入值,形成正弦点-CSDN博客文章浏览阅读410次。本文介绍了如何在CODESYS编程环境中创建正弦和余弦信号发生器。通过详细的PLC梯形图和SCL语言代码…

【JMeter详解】

JMeter详解 Apache JMeter 是一个开源的、100%纯Java应用程序&#xff0c;设计用于负载测试和性能测量。它最初是为测试Web应用程序而设计的&#xff0c;但后来扩展到其他测试功能。JMeter可以用来对静态和动态资源&#xff08;如静态文件、Servlets、Perl脚本、Java对象、数据…

uniapp:微信小程序文本长按无法出现复制菜单

一、问题描述 在集成腾讯TUI后&#xff0c;为了能让聊天文本可以复制&#xff0c;对消息组件的样式进行修改&#xff0c;主要是移除下面的user-select属性限制&#xff1a; user-select: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms…

查看 GitHub 仓库的创建时间

查看 GitHub 仓库的创建时间 1. https://api.github.com/repos/{owner}/{repository}2. curl -s https://api.github.com/repos/{owner}/{repository} | jq .created_atReferences 1. https://api.github.com/repos/{owner}/{repository} REST API endpoints for repositories…

VScode怎么重启

原文链接&#xff1a;【vscode】vscode重新启动 键盘按下 Ctrl Shift p 打开命令行&#xff0c;如下图&#xff1a; 输入Reload Window&#xff0c;如下图&#xff1a;

【无线传感网】WSN数据管理技术

文章目录 WSN数据管理的基本概念以数据为中心的WSN数据库与分布式数据库相比具有的特殊性WSN数据管理技术的研究热点 WSN数据管理的关键技术无线传感器网络数据存储结构网外集中式存储方案网内分层存储方案网内本地存储方案以数据为中心的网内存储方案 数据查询处理技术查询类型…

python调用gemini2.0接口识别图片文字

import os import base64 import google.generativeai as genai# 配置 Google API Key # 可以在系统环境变量设置 GOOGLE_API_KEY GOOGLE_API_KEY os.getenv("GOOGLE_API_KEY", "AIzaSXXXXXXXXXXXXXX") # 替换成你的 API Key# 设置 Gemini 模型名称 mode…