Android

分类下相关文章

android AppCompatButton 设置背景图片

遇到一个奇怪的问题,在 Android 项目中给 Button 设置背景图片,总是不生效。 <Button android:background="@drawable/normal" android:text="OK"> </Button> 改用 androidx.appcompat.widget.AppCompatButton <androidx.appcompat.widget.AppCompatButton android:background="@drawable/normal" and ...

阅读全文...

Android APP 设置版本号,并显示在界面上

由于给客户定制的 Android APP 不需要发布到应用商店,没有一套统一的版本控制渠道。 只能先通过人肉查看版本号的方式,将版本号显示在界面上。 设置版本号 app build.gradle 文件: 通过 versionCode 和 versionName 来配置 App 的版本号。 android { namespace 'com.sunzhongwei.app' compileSdk 33 defaultConfig { applicationId "com.sunzhongwei.app" minSdk 2 ...

阅读全文...

Android Kotlin 对字节 byte 中的某一位 bit 取反

Android Kotlin 中,需要对字节 byte 中的某一位 bit 取反 取反代码 fun toggleBit(byteValue: Byte, bitIndex: Int): Byte { // Convert the Byte to an Int to perform bitwise operations val intValue = byteValue.toInt() // Create a mask with the bit at the specified index set to 1 val mask = 1 shl bitIndex ...

阅读全文...

Android Studio 中修改 App 的包名

需求背景 一套 Android 蓝牙控制硬件设备的程序,每个客户端界面和逻辑都有比较大的差异,所以想分成 N 个 git 代码仓库进行管理。 为了方便测试,例如在一个 Android 平板上安装多套不用版本的 App 进行测试,就需要区分开每个 App 的包名。 修改流程: 改包名 Android 视图下,右键点击 java 目录下的 com.sunzhongwei.app,选择 refactor - rename , 修改成新的名称。 例如:com.sunzhongwei.app2 app build.gradle namespace, 及 applicationId 修改包名。 其他文件 ...

阅读全文...

Android LiveData 实战总结

这周在重构一个 Android 平板蓝牙控制的 App,之前为了赶工期,代码写的比较乱, 正好这段时间赶上多个客户的定制要求,发现要一套代码实现多套差异化的需求,如果代码不好好规整根本改不动。 自己欠的技术债,总归是要还的。 在改造的过程中,发现之前使用 LiveData 的方式有不少问题,总结一下: 逻辑不要放在 Fragment 中 能在 ViewModel 中处理的,尽量在 ViewModel 中处理。 Activity / Fragment 尽量只监听 LiveData, 然后直接显示,不做任何复杂的逻辑判断。 集中在 ViewModel 处理,逻辑更清晰。 多个 Fragment ...

阅读全文...

Android Fragment 实现对蓝牙设备的参数配置页面

新建 fragment 新建一个 Blank Fragment。会自动创建对应的 layout xml 文件,但是 binding 需要自己手写。 layout binding package com.sunzhongwei.ble.settings import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import com.sunzhongw ...

阅读全文...

NordicSemiconductor/Android-BLE-Library 监听连接状态变化

监听的目的 Android App 界面显示当前的蓝牙连接状态:断开/连接中/已连接 在断开时,自动重连 如何监听连接状态 (已废弃) 在 NordicSemiconductor/Android-BLE-Library 官方文档中没有找到相关的说明。 只能在 github 中搜索 no.nordicsemi.android.ble.BleManager 的 kotlin 代码。 确实找到不少参考项目。 例如: https://github.com/fbiego/ESP32_BLE_OTA_Android/blob/d10f6546f4371dd811767b5b4958c2aa891697 ...

阅读全文...

Android BLE 蓝牙操作设备三方库 NordicSemiconductor/Android-BLE-Library

为何要使用三方库 起因是我写的 Android 低功耗蓝牙 App 有几个现存的问题: 写操作的并发问题导致写入失败,需要一个队列。iOS 内置了这个实现,甚至连微信小程序都实现了,但是 Android 官方没有实现,渣渣。 信号不稳定,蓝牙断开连接,需自动重连 未来需要连接多个蓝牙设备,但是我目前的架构不支持 如果设备信息进一步增多,就要涉及到数据包的拆分,组合 我去自己实现,非常耗费时间,在我看来都是非常基础的功能。不如找个三方稳定的实现。 NordicSemiconductor/Android-BLE-Library 介绍 https://github.com/NordicSemic ...

阅读全文...

android gradle 依赖版本号统一管理

在项目级 build.gradle 文件中 在 ext 代码块中定义 room_version。 ext { kotlin_version = "1.6.20" nav_version = "2.4.1" room_version = '2.4.2' } 在应用级 build.gradle 文件中 在依赖项列表末尾添加以下依赖项。 implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compi ...

阅读全文...

The project is using an incompatible version (AGP x.x.x) of the Android Gradle plugin

今天在编译一个 github 上的 Android 项目时,报错 The project is using an incompatible version (AGP 8.1.0) of the Android Gradle plugin. Latest supported version is AGP 8.0.1 AGP 是什么 Android Gradle Plugin。 AGP(Android Gradle Plugin)是一个用于构建 Android 应用程序的 Gradle 插件。AGP 可以将 Android 项目中的源代码、资源和依赖项编译成可安装的 APK 文件,并提供了许多 ...

阅读全文...

Android Foreground Service 中,提示音循环播放及停止

需求背景 Android App 收到蓝牙推送的消息之后,播放提示音,且一直播放,直到收到停止的指令。 TODO [X] fragment 界面上增加两个按钮:开始,停止。方便测试 [X] 提取出播放和停止功能,封装成两个函数。便于测试 [X] 接收到停止指令后,关闭音频 [X] Foreground Service 中定义 LiveData,方便 fragment 点击按钮后操作。实际不需要,直接在 service 中定义成静态方法即可。 [X] 下载报警提示音 [X] 支持自定义音频文件。这个以后播放引导提示音频也能用到,只不过是只用一次 [X] 测试无误后,去掉开始按钮(隐藏),只保留 ...

阅读全文...

台电 Android 平板上无法手势关闭 App

在开发的一个 Android App 在台电平板上出现了诡异的现象,无法手势上滑关闭。 其他 app 都没有这个问题,均可以成功关闭,只有我开发这个 app 有这个现象。。。 我一开始以为是我每秒一次的循环任务,在进入后台时也在执行导致了 app 无法杀掉,所以把这个循环操作注释掉,再次测试还是无法杀掉。这就诡异了。。。 这个说不通啊,要是这样就能防止 app 被杀掉,那国内各大厂商的 app 还不纷纷这样搞,但现实是没有那个 app 是不能杀掉的,只有本 android 高手开发的 app 会这样。。。 早上无意发现 app 概览页有个小锁标识: 变成 lock 状态时,无法杀掉 变成 u ...

阅读全文...

Android 使用 ViewPager2 实现手势侧滑翻页

需求 由于 Android 平板控制硬件设备,控制界面要展示的数据太多,一屏装不下。 所以需要新增一个界面,用于展示次要的信息。 交互方式是,在首屏,通过手势滑动,切换到次屏。 找到一个官方的组件 ViewPager2,看上去非常合适。 官方文档只说明了在 Activity 中使用 ViewPager2 的方式,并没有提及是否可以在 Fragment 中使用。 所以需要测试一下。 最终实现效果 ViewPager2 ViewPager2 是 Android Jetpack 中的一个库,它提供了一种以滑动方式浏览多个页面的方式。支持垂直和水平方向的滑动,并且具有更好的性能和更灵活的 API。 ...

阅读全文...

Android LiveData 实现列表勾选

界面功能 界面功能是禁忌症确认,只有不存在任何一项的时候,才能进入使用。 每一项是一个 Switch 按钮,代表是否勾选。 记录目的 感觉我对 LiveData 的理解还是不够充分。也许经历越多的实战,才能理解更多吧。 修改其中一个 item 的 field class ViewHolder(private val binding: ConfirmRowItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(item: ConfirmationItem) { binding.name.text = item.ti ...

阅读全文...

Android BLE 蓝牙监听 STM32WB 上的自定义特性

要给 Android 平板蓝牙语音对讲 APP 上增加一个报警推送功能,即监听蓝牙控制板上的一个信号,来显示报警信息。实际上就是监听一个自定义的特性即可。 STM32 芯片的 Android SDK 封装的太猛了,捋一遍代码脑子爆炸。 所以记录一下看 SDK 源码的过程。 特性扫描 BlueSTSDK/BlueSTSDK/src/main/java/com/st/BlueSTSDK/Node.java 增加了调试日志,方便查看新增特性的 UUID mCharFeatureMap.clear(); for(BluetoothGattService service : nodeServices){ ...

阅读全文...