Android Studio gradle 技巧一 重要信息脱敏

Android Jenkins CI/CD流水线实战:Gradle+SDK+Jenkins三阶集成 持续集成(CI)是现代移动开发的基础能力,其核心在于构建过程的自动化、可复现与可审计。Android构建区别于传统Java项目,依赖Android SDK提供API编译支持,由Gradle作为构建‘操作系统’管理任务流与依赖,再通过Jenkins实现跨环境调度与流程编排。这一技术栈组合解决了手工打包易错、多设备适配混乱、签名与渠道包管理低效等高频痛点。实践中,JDK版本与AGP的兼容性、SDK命令行部署规范、Gradle Wrapper固化及参数注入机制,共同构成稳定流水线的底层支柱。本文聚焦Android 阅读详情

开个头

众所周知,android的签名文件(.jks 或者 .keystore)很重要。一般我们配置签名文件的写法是直接在app build.gradle文件里进行明文配置。不是很优雅。
还有我们对接第三方的时候,会申请一些appkey或者appSecret,一般也是会直接出现在代码里,不是很安全。

不优雅的配置签名信息
app build.gradle
android{
	...
	 signingConfigs {
        debug {
            storeFile file("xxx.jks") //签名文件路径
            storePassword "xxx"//仓库密码
            keyAlias "xxx"//别名
            keyPassword "xxx" //签名密码
        }
        release {
            storeFile file("xxx.jks") //签名文件路径
            storePassword "xxx"//仓库密码
            keyAlias "xxx" //别名
            keyPassword "xxx" //签名密码
        }
    }
	...
}

不优雅地设置第三方key
在某java文件中明文

    // APP_ID 替换为你的应用从官方网站申请到的合法appID
    private static final String APP_ID = "xxxxxx";

    // IWXAPI 是第三方app和微信通信的openApi接口
    private static IWXAPI api;

    //向微信注册 appId
    public static void registToWX() {
        // 通过WXAPIFactory工厂,获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(MyApp.getApplication(), APP_ID, false);
        // 将应用的appId注册到微信
        api.registerApp(APP_ID);
    }

或者在manifest.xml中明文

<!-- 高德地图START -->
<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="xxxxxxx" />
<!-- 高德地图END -->

解决方法

优雅地设置签名信息
1.创建keystore.properties

在项目根目录下,创建keystore.properties文件。文件里配置签名文件信息。
默认你已经在项目根目录下,创建了一个签名文件

# about keystore
storeFile=xxx.jks
storePassword=xxx
keyAlias=xxx
keyPassword=xxx
2.在build.gradle文件里引用.properties文件

在 app build.gradle文件里引用刚创建好的keystore.properties文件。

...
// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder.
def keystorePropertiesFile = rootProject.file("keystore.properties")

// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()

// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android{
	...
}
...
3.优雅地设置
...
android{
	...
	//开发中为了方便测试,debug的签名文件和release的签名文件,用的是一套。。。
	signingConfigs {
        release {
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
        }
        debug {
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
        }
    }
}
...

经过以上步骤,我们的签名文件已经脱敏。可以大胆的把项目上传到远程仓库(把签名文件 加入 .ignore)

优雅地设置第三方key

有了上面的基础,我们已经可以实现在build.gradle里面实现进行信息脱敏,所以,现在我们只要能实现在java文件和manifest文件中拿到build.gradle文件中的变量值,这样就可以实现将java文件和manifest文件中的第三方信息脱敏。

在Java文件和manifest文件中共享参数
BuildConfig

简单介绍下BuildConfig这个类,下面的代码块是BuildConfig默认的一些值。
1.这个类是编译时gradle帮我们自动生成的一个类(方便维护,或者说不需要我们维护)
2.这个类里面的值都是静态常量 (方便调用)
3.这个类会根据Build类型(debug/release)来给常量赋值 (这个功能比较厉害,下面单独说)

/**
 * Automatically generated file. DO NOT MODIFY
 */
package com.example.xxxx;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.example.xxx";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
}
1在keystore.properties里面定义参数

在这个文件中#表示注释。
在这个文件里面字符串不要用双引号""包裹。

# about keystore
storeFile=xxx.jks
storePassword=xxx
keyAlias=xxx
keyPassword=xxx
##################################################
# about custom value
#------------------高德地图apiKey------------------
aMapApiKey=xxxxxxxxxx
#------------------   微信分享   ------------------
weChatAppId=xxxxxxxx
2在build.gradle里拿到.properties里的值

app build.gradle

// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder.
def keystorePropertiesFile = rootProject.file("keystore.properties")

// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()

// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android{
	...
	 //获取 高德地图apiKey
     def aMapApiKey = keystoreProperties['aMapApiKey']
     //获取 微信分享appId
     def weChatAppId = keystoreProperties['weChatAppId']
     //给BuildConfig类里面添加自定义参数
     buildConfigField("String", "weChatAppId", "\"${weChatAppId}\"")
     //创建一个可以在manifest中使用的参数
     manifestPlaceholders = [
                aMapApiKey : "${aMapApiKey}",
     ]
     signingConfigs {
     ...
	 }
}

设置完了后,编译一下我们的项目然后进入BuildConfig类里看一下。gradle已经帮我们把值设置进去了。

/**
 * Automatically generated file. DO NOT MODIFY
 */
 //如果你的项目中依赖了多个library注意看这个包路径。找到app对应的BuildConfig。每个library都会生成自己的BuildConfig
package com.example.xxxx;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.example.xxx";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from default config.
  public static final String weChatAppId = "xxx";
}
3在.java代码中使用
 	// APP_ID 替换为你的应用从官方网站申请到的合法appID
 	//这里就直接用BuildConfig.weChatAppId 来获取我们设置在.properties文件中微信的AppId
    private static final String APP_ID = BuildConfig.weChatAppId;

    // IWXAPI 是第三方app和微信通信的openApi接口
    private static IWXAPI api;

    //向微信注册 appId
    public static void registToWX() {
        // 通过WXAPIFactory工厂,获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(MyApp.getApplication(), APP_ID, false);
        // 将应用的appId注册到微信
        api.registerApp(APP_ID);
    }
4在manifest中使用
 <!-- 高德地图 apiKey -->
        <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="${aMapApiKey}" />

我们看下manifest文件编译前后的对比。比较一目了然。
在这里插入图片描述

BuildConfig厉害的功能

我在开发中,测试和上线的时候,经常会改一些配置项。有时候打完包了正式包才发现一些配置忘了修改。我之前是在配置项之前加上TODO,每次打包之前都看下TODO,然后修改对象的配置项,比较的麻烦。如下图。
在这里插入图片描述
有了BuildConfig之后,就方便多辣

app build.gradle

...
android{
	...
	buildTypes {
        release {
            buildConfigField("boolean", "IS_DEBUG", "false")
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            buildConfigField("boolean", "IS_DEBUG", "true")
        }
    }
}
...

然后我们直接在代码中根据BuildConfig.IS_DEBUG的值来判断是debug版本还是release版本就好了。
比如,这个bugly,我们开发过程中生成的bug,真的不用上传上去给主管看到。。。

//TODO bugly 配置是否上传崩溃日志
//之前每次测试和发布产品的时候都要手动改这个boolean值,很麻烦。
CrashReport.initCrashReport(getApplicationContext(), appId, false);

//TODO bugly 配置是否上传崩溃日志
//以后测试和发布的时候,再也不用管辣
CrashReport.initCrashReport(getApplicationContext(), appId, !BuildConfig.IS_DEBUG);

下图可以看到debug 和 release 下BuildConfig里面的值得变化。
在这里插入图片描述
这个只是作为一个例子来理解BuildConfig的妙用,其实可以看到BuildConfig自带一个BUILD_TYPE来区分编译类型。不需要我们额外自定义参数。
在我们的开发中还会遇到多版本或者多渠道打包(就是多flavors的时候),这时候如果渠道区分版本或者渠道,这时候BuildConfig就派上大用场辣。这个也不是本篇的重点,先轻描淡写。想了解多渠道打包的可以google官方开发者文档介绍

参考资料

google官方开发者文档
还有默默无闻的大佬们

如有错误,欢迎指正!

Claude+Android Studio联动开发:我是如何用AI助手10分钟搞定WebView项目模板的 本文分享了如何利用AI助手Claude与Android Studio联动,快速生成Android WebView项目模板的实战经验。通过精准的自然语言指令,Claude能高效生成包括Activity、布局、Gradle配置及AndroidManifest在内的完整代码,并处理权限、网络配置等细节,将原本数小时的开发工作缩短至10分钟,极大提升了Android开发效率。 阅读详情

相关推荐

2026安卓毕业设计源码解析:Kotlin与Jetpack最佳实践

移动应用开发中,分层架构设计与现代Android技术栈的结合已成为提升工程质量的行业标准。Kotlin协程配合Jetpack组件可实现线程安全的状态管理,而Room+Retrofit的数据层方案能有效平衡本地缓存与网络请求需求。在毕业设计场景下,采用MQTT协议实现设备通信、使用Sealed Class封装网络状态等技术决策,既体现了技术深度又符合学术规范。通过分析智能家居控制平台等典型项目的架构图和技术选型表,开发者可以学习到如何将性能监控、安全加固等工程实践融入项目,同时掌握Gradle配置优化、数据库

weixin_34396902的博客 410

keystore.properties 配置

秘钥丢失或泄漏: 1.无法发布已有应用的更新,签名文件不同导致无法覆盖安装 2,被人重新打包,添加私活,偷偷获取用户数据等 从编译文件中移除签名信息 android 保障密钥的安全 keystore.properties - Welcome My Blog! - OSCHINA - 中文开源技术交流社区 关于签名文件的知识总结 - zhangmiao14 - 博客园 在您创建签名配置时,Android Studio 会以纯文本形式将您的签名信息添加到模块的build.gradl...

hpp_1225的博客 4698

Grok Bot安卓应用预注册指南:移动端构建任务与API接入

随着移动端AI应用生态的成熟,智能对话与任务构建已成为工程实践中的核心能力。这类应用通常基于云端推理与API接口,通过结构化指令实现从问答到自动化执行的跨越。对于开发者而言,理解其技术原理与资源占用模型,有助于快速搭建可靠的移动端工作流。Grok Bot安卓应用近日开放预注册,支持Build功能并可能集成API调用,为普通用户和开发者提供了新的入口。本文从预注册流程、环境准备、功能测试到API接入要点,系统梳理移动端Bot应用的落地路径,帮助读者规避常见坑点。

weixin_30572613的博客 359

key文件信息等隐藏设置(keystore.properties)

在当前目录下创建keystore.properties文件 storePassword=123456 keyPassword=123456 keyAlias=。。。 storeFile=E:/mul.jks 在build.gradle中加入: signingConfigs { config { keyAlias keystoreProperties['

m0_37678565的博客 5032

智能体+Android实用工具:出海应用开发的高效组合实践

移动应用开发领域,AI智能体正逐步改变传统编码模式。基于大语言模型的智能体能够理解代码上下文,辅助开发者高效完成重复性任务,例如生成项目骨架、编写UI代码、批量处理多语言资源等。在Android开发中,结合Gradle、adb、APK Analyzer等实用工具,可将智能体输出快速转化为可运行的工程。针对出海应用场景,多语言、多渠道及合规要求高,智能体在生成国际化资源和准备上架材料方面表现尤为突出。通过清晰的提示词设计和人机协作流程,开发者能显著提升开发效率。以汇率换算工具为例,完整展示从环境准备、智能体辅

weixin_34082854的博客 433

Android Internal Storage 核心机制与生产级实践指南

Internal Storage 是 Android 应用数据隔离与持久化的底层基石,其本质是基于 Linux UID 的沙盒化文件系统,通过 /data/data/<package>/ 路径实现进程级私有访问。它不依赖 Manifest 权限声明,天然具备数据私有性、生命周期一致性与跨版本兼容性,是 Scoped Storage 时代最稳定可靠的存储通道。相比外部存储的权限碎片化与 OEM 行为差异,Internal Storage 支持 getFilesDir、getCacheDir、getDataba

a1311010193的博客 394

Android个人信息脱敏操作

刚步入工作在项目中学到的,记录一下防止以后忘掉,毕竟好记性不如烂笔头。 // Android个人信息脱敏操作 String phone = 1111111111; String FORMAT_PHONE_NUMBER_REGEX = "(\\d{3})\\d{4}(\\d{4})"; String REPLACEMENT = "$1****$2";//$代表()$后边的数字代表第几个() private String formMatPhoneNumber(String number) {

Pain的博客 2700

Android应用日志泄露隐私实证:从Logcat安全到自动化检测挑战

在移动应用开发中,日志系统是关键的调试与排错工具,它记录了应用的运行状态和事件流。其工作原理是通过集中式管道(如Android的Logcat)输出不同级别的信息。然而,这一技术价值背后潜藏着巨大的隐私风险:若未妥善处理,日志可能成为敏感数据的泄露漏斗。特别是在处理用户个人身份信息(PII)、会话令牌和位置数据等场景时,明文或弱保护的日志输出会直接违反隐私政策承诺,构成严重的安全隐患。当前,自动化检测此类泄露面临诸多挑战,包括静态分析(SAST)在数据流追踪上的局限,以及动态分析(DAST)在场景覆盖与日志归

weixin_33735077的博客 386

日志里的敏感信息还在打明文?3 种日志脱敏方案任你选

背景我们打的日志中经常包含姓名、手机号、银行卡号等敏感信息,如果不做任何处理,就会以明文的形式展示在日志中,存在安全风险。像下面这样:我们需要一种能自动帮我们脱敏的工具,效果如下:方案1 - 基于 logback我们得先搞清楚消息内容是在哪里处理的,也就是配置文件中这个占位符的内容:对应到源码是这里 ch.qos.logback.classic.PatternLayout :这里可以看出来都是通...

JiuQianWan的博客 1万+

Android开发学习链路和教程规划

这是一套系统化的Android开发教程,采用全新链路式教学法,从Linux内核到应用上线全流程解析。教程特色在于每个知识点都涵盖底层原理、源码链路、使用方法和工程治理四大维度,确保开发者获得完整认知体系。课程分为三个阶段:底层运行环境(Linux内核、Binder、Zygote等)、项目构建与运行时(Gradle、APK安装、资源系统等)、四大组件与UI开发(Activity、View、Jetpack等)。

9年Android老兵,专注车载系统与移动架构。深耕Java/Kotlin,玩转Lua/Python。擅长百度/高德地图深度定制,分享拒绝浅尝辄止的硬核干货。 66

Android高分作业工程化实践:从环境配置到Room架构

Android开发不仅是写UI和逻辑,更是构建可复现、可维护、可扩展的工程体系。理解Android Studio环境配置原理、Gradle构建生命周期与build.gradle DSL语义,是规避编译失败、真机闪退等基础问题的前提;掌握Room持久化框架的编译期校验、类型安全DAO与数据库迁移机制,则直接决定数据层健壮性与评审得分。这些能力共同支撑起备忘录类App的工业级实现——从gradle.properties性能调优到ContentProvider文件共享规范,每一步都体现现代Android工程思维。

weixin_29161785的博客 300

Flutter Android 打包保姆式全流程 2023 版

这是一份 2023 完整的最新版的 Flutter Android 新手打包全流程介绍,包含完整示例项目,从此 android 打包不求人。

17 的博客 5888

FOC实战笔记:RC吸收电路的设计考量与参数调优

本文深入探讨了FOC驱动器中RC吸收电路的设计与调优。针对MOS管开关过程中的电压尖峰问题,详细阐述了RC电路的钳位与能量吸收原理,并提供了从参数计算、实验调试到布局布线的完整实战指南,旨在帮助工程师有效提升系统可靠性与稳定性。

weixin_29219539的博客 276

Unity 2022.3 打包 Android 失败:AAPT2 error failed to load resources table in android-35/android.jar

WARNING:We recommend using a newer Android Gradle plugin to use compileSdk = 35This Android Gradle plugin (7.1.2) was tested up to compileSdk = 32This warning can be suppressed by adding android.suppressUnsupportedCompileSdk=35 to this project's gradle

好好学习天天向上 1349

开源分享:苹果群控手机源代码解析与实战

本文介绍了苹果设备群控的基本原理和实现方法,重点解析了基于Python+Appium的群控系统构建。主要内容包括:1)设备连接管理技术(USB/Wi-Fi);2)自动化控制方式(WDA/AppleScript/Appium);3)实战演示了通过Python脚本实现多设备同时控制,涵盖环境配置、代码解析和功能说明;4)提出了多线程、图像识别等优化方向。文章为开发者提供了快速上手的群控方案,适用于自动化测试、批量管理等场景,并推荐了相关开源项目参考。

2403_88540309的博客 1347

Hcaptcha验证码的‘免浏览器’破解思路:协议分析与N值算法逆向

本文深入解析Hcaptcha验证码的‘免浏览器’破解思路,通过协议分析与N值算法逆向,实现高效自动识别。文章详细拆解Hcaptcha的API交互流程,揭示关键参数`req`和`n`的生成机制,并提供轻量级实现方案,显著降低资源消耗,适用于大规模数据采集等场景。

weixin_30838873的博客 535

Android Studio集成本地AI模型:打造私有化智能代码生成助手

在软件工程领域,代码生成技术通过自动化编程任务显著提升开发效率。其核心原理是利用机器学习模型理解自然语言意图并转化为结构化代码。本地AI代理接口技术将大语言模型(LLM)服务化,通过HTTP API提供私有化代码生成能力,解决了云端服务的隐私泄露和网络依赖问题。在Android开发场景中,开发者可通过Ollama部署本地模型,结合IntelliJ Platform SDK开发IDE插件,构建安全可控的智能编程环境。本文以Android Studio插件开发为例,详解如何集成本地AI模型实现“描述即开发”的智

weixin_30723433的博客 396

【2022KaliLinux】openvas/gvm 没有scan configs 或者是 scan config error “XXXXXXXXXXX”

gvm/openvas的configuration的scan config为空

zbossz的学习小分队 3607

Gemini 3.5 Flash企业落地实战:智能体如何嵌入Android Studio与工作流

智能体(Agent)是当前AI工程化的核心范式,其本质是将大模型能力封装为可调度、可审计、可编排的自动化执行单元。Gemini 3.5 Flash并非参数缩减版模型,而是专为高可靠、低延迟、强工具集成的生产级任务执行而设计的异构推理引擎。它通过选择性上下文路由、原生工具调用(Tool Calling)和可追溯推理轨迹(Reasoning Trace),显著降低企业部署门槛。技术价值体现在三方面:大幅压缩多步骤任务耗时(实测从47秒降至11秒)、将API调用简化为max_execution_steps/too

coolmsn8786的博客 519

Starlink vs Kuiper vs OneWeb:三大低轨卫星网络架构对比与实战应用场景解析

本文对比分析了Starlink、Kuiper和OneWeb三大低轨卫星网络架构的技术差异与商业应用场景。从轨道设计、通信性能到商业落地,详细解析了各系统在近地卫星网络领域的独特优势与挑战,为未来全球宽带服务格局提供专业见解。

weixin_29255731的博客 809

用WorkBuddy和ima搭建本地知识库:从概念到实操

在AI应用普及的今天,私有知识的高效管理与调用成为痛点。RAG(检索增强生成)技术通过将外部知识库与语言模型耦合,为精准问答提供了技术底座。然而,传统RAG方案往往涉及向量数据库、文本切分等复杂环节。一种更轻量的路径应运而生:借助WorkBuddy与ima的组合,将知识收集、语义检索与智能体工作流整合,让本地知识库真正服务于日常办公和研发场景。从概念到实操,系统解析这套轻量级方案的核心逻辑与配置方法,并对比重方案适用边界,帮助读者快速搭建属于自己的AI知识助手。

weixin_32830601的博客 424

Flutter与Firebase实现儿童出行隐私保护:动态身份脱敏与地理围栏

在移动应用开发中,用户隐私保护和实时位置共享是LBS(基于位置的服务)应用的核心技术挑战。其原理在于通过动态身份脱敏技术,在特定场景下对用户敏感信息(如头像、昵称)进行实时替换,同时结合地理围栏(Geofencing)实现基于位置的精细化权限控制。这项技术的价值在于平衡了社交分享的需求与个人隐私安全,尤其适用于儿童监护、匿名社交等场景。本文以Flutter跨平台框架和Firebase后端服务为例,深入解析了如何构建一个具备“动态身份脱敏”和“实时位置共享”功能的儿童安全出行应用,完整呈现了从状态管理、实时数

298

uniapp实战:5分钟搞定PDA激光扫码功能(附完整代码)

本文详细介绍了在Uniapp应用中快速集成工业PDA激光扫码功能的实战方案。通过解析PDA硬件扫码与手机摄像头扫码的核心机制差异,提供了完整的广播监听封装类代码,并演示了在Vue页面中的集成使用方法,帮助开发者高效解决仓储、零售等行业的条码扫描需求。

weixin_29239661的博客 457

Android智能体实战:出海应用集成指南与开发工具

智能体(Agent)是能够感知环境、做出决策并执行动作的AI程序,它以大语言模型为核心,结合工具调用与记忆模块,将复杂任务拆解为可执行的子流程。相比传统问答机器人,智能体更能理解用户真实意图,推动应用从被动响应转向主动服务。在出海Android应用中,智能体可落地为智能客服、语音助手、本地生活服务等场景,通过多语言适配与本地化策略显著提升海外用户体验。本文基于工程实践,完整拆解了Android端接入智能体的技术选型、环境配置、网络层封装、语音输入与多轮对话实现,并整理了开发过程中高频使用的调试与效率工具,为

weixin_34080951的博客 285

electron:解决打包后报错Cannot find module ‘X‘ 运行报错各种模块缺失问题(解决electron build打包后运行应用报错启动失败或白屏,无论模块名称是什么都能解决!)

Electron app打包后启动报错:“Cannot find module 'X'”解决方案,electron-builder 打包出现 cannot find module,electron 打包后找不到module问题,electron打包运行白屏、Can not find modules ‘x‘,electron项目打包报错,electron打包后,点击生成的exe应用程序出现Cannot find module,解决electron-build打包后运行app报错:cannot find mod

✅ 精选推荐文章 4386

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

小红书Android秋招笔试复盘:四大模块核心考点与避坑策略

Android开发涉及从应用层到系统框架的完整链路,Activity启动流程、Handler消息机制、Binder IPC等基础原理,构成了客户端工程师的必备知识体系。理解这些原理不仅有助于解析系统行为,更能在性能优化、架构设计等实践中发挥作用。在移动应用开发中,从UI渲染到数据存储,处处体现着对这些底层机制的应用。随着技术演进,Kotlin协程、MVVM架构、R8混淆等新工具链也逐步成为面试与工程中的高频考点。针对近年大厂校招笔试,以小红书Android秋招为例,考察范围覆盖语言基础、系统框架、算法与工程

weixin_34208283的博客 306

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: ViewPager实现画廊效果
下一篇: Canvas画文本时设置某些文本颜色与其他不同
Come丶On
博客等级 码龄11年 18粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值