Android

分类下相关文章

Android 项目中 compileSdkVersion targetSdkVersion minSdkVersion buildToolsVersion 的区别

之前用 Android Studio 开发小工具 APP 的时候,没有在意 compileSdkVersion targetSdkVersion minSdkVersion buildToolsVersion 这几个 gradle 配置参数,使用默认的值即可。但是最近遇到一个需要用到三方 SDK 的项目,发现默认配置有问题,需要了解一下这几个参数的区别。 compileSdkVersion compileSdkVersion 是编译 app 使用的 api 版本。这意味着: 开发阶段:使用了更高的 compileSdkVersion 版本,就可以使用最新的 API。也方便知道哪些 API 即 ...

阅读全文...

Android 项目如何从 github 引用三方模块

在引用 STM32 SDK 的时候,遇到了麻烦: 这个 SDK 模块在 github 上: https://github.com/STMicroelectronics/BlueSTSDK_Android 现有的方式 As a git submodule 1. Add the repository as a submodule: \$ git submodule add <https://github.com/STMicroelectronics/BlueSTSDK_Android.git> BlueSTSDK 2. Add the SDK as a project ...

阅读全文...

STM32 蓝牙模块对应的 Android 列表页源码梳理

BlueST SDK BlueST is a multi-platform library (Android and iOS supported) that permits easy access to the data exported by a Bluetooth Low Energy (BLE) device that implements the BlueST protocol. 相关名词 Manager:singleton class 用于启动/停止蓝牙设备扫描。发现节点之后,会通过 Manager.ManagerListener Class 异步通知。 Node:代表一个远端 ...

阅读全文...

Android API 无法获取蓝牙 BLE Attribute Handle 值

最近写了一个 Android APP 用于快速配置蓝牙网关(已上架 Google Play),但是基本功能完成后, 发现无法获取指定特性 (characteristic) / 描述符 (descriptor) 的 handle 值。 handle 存在的意义 Handle 的全称是 Attribute Handle。 在用 Android API 实现这个 BLE 扫描 APP 的过程中,我发现无论是服务,还是特性、描述符其 UUID 都是可能重复的。 举个例子,如果一个蓝牙设备包含两个电池模块,则存在两个相同服务的 UUID 是合理的。 那么用 UUID 来标识一个服务/特性/描述符就不合理 ...

阅读全文...

BLE Scan: Privacy policy

Welcome to the BLE Scan app for Android! This is an Android app developed by Zhongwei Sun. The app is available on Google Play. As an avid Android user myself, I take privacy very seriously. I know how irritating it is when apps collect your data without your knowledge. I hereby state, to the best o ...

阅读全文...

Material dialogs MaterialAlertDialogBuilder 中添加文本编辑框

setView 官方 Material Design 3 的文档中并没有详细的 MaterialAlertDialogBuilder 使用说明。 https://github.com/material-components/material-components-android/blob/master/docs/components/Dialog.md 找不到如何在里面添加文本编辑框。 但是在接口文档中可以看到有一个 setView 的方法 https://developer.android.com/reference/com/google/android/material/dialog/Ma ...

阅读全文...

Android 哪些操作应该放到 ViewModel 中

权限申请是否应该放到 ViewModel 中 有此疑问的原因是,我看到权限相关的操作,需要传入 Context 参数。 private fun isLocationPermissionGranted(): Boolean { return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED } 而 Context 只能在 Activity / Fragment / View 中得到。 ...

阅读全文...

Android RecyclerView Adapter ViewHolder 中获取 Activity

之前记录过如何在 Fragment 中获取父级 Activity,这次发现需要在 RecyclerView Adapter ViewHolder 中获取 Activity。 简单来说,就是: get Context from the view 例如,ViewHolder 中包含一个 text view 用来显示姓名,可以借此获取 context,从而得到 Activity. (binding.name.context as ItemDetailHostActivity).stopSomething() 实际应用场景 例如,在各种嵌套的 RecyclerView Adapter 中想访 ...

阅读全文...

Android 使用 LiveData 显示实时状态变化

例如加载数据时, 显示转圈提示。或者显示 connecting / finding data ... 也可以加上动态图标: https://github.com/material-components/material-components-android/blob/master/docs/components/ProgressIndicator.md 用最下面的转圈图标非常直观。 注意还有失败的情况,比如列表中蓝牙设备消失或关闭。 状态放在哪里 还是存储在 ViewModel 中最合适。 同时在 activity / fragment 中对状态 LiveData 进行监听。 LiveData ...

阅读全文...

Android RecyclerView 嵌套显示 BLE 蓝牙 Service 的 Characteristic 子项

例如,外层 RecyclerView 显示的是一个 BLE 蓝牙设备的 Service 列表; 内存嵌套的 RecyclerView 显示的各个 Service 所包含的 Characteristic 特性列表。 点击展开 Service,显示其所包含的特性。 RecyclerView 嵌套 首先在父级 RecyclerView 的 Item Layout 中定义一个子 RecyclerView 控件 嵌套的 RecyclerViewAdapter 绑定逻辑,在父级 RecyclerViewAdapter 的 onBindViewHolder 中实现 item:BluetoothGattC ...

阅读全文...

Android Kotlin 中获取 context 的几种方法

Fragment 中获取 context 调用 getActivity 获取父级 activity 的 context, Kotlin 中简化为 fragment.activity: 例如: Toast.makeText( activity, "Start Scanning", Toast.LENGTH_SHORT ).show() RecyclerViewAdapter 中获取 context 使用 layout 中 view (每个小控件就是一个 view) 的 getContext 方法, Kotlin 中即简化为 view.context: 例如: recyc ...

阅读全文...

Android Primary/Detail Flow 模板的 fragment 点击跳转逻辑

TODO 看懂原有 primary/detail 模板的跳转逻辑 新建 snippet list fragment override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val itemDetailFragmentContainer: View? = view.findViewById(R.id.item_detail_nav_container) setupRecyclerView(recyclerView, itemDetailFragmentContainer) } private ...

阅读全文...

Android 复制文本到系统剪切板

需求 我正在开发的一个 Android App,其主要功能就是将扫描出来的蓝牙设备信息,自动复制到手机剪切板。 然后复制到其他需要配置的地方。 例如,点击蓝牙设备的 Mac 地址,自动写入剪切板。 复杂的实现 看了官方文档,发现要实现这么个简单的功能,远比想象中复杂。 https://developer.android.com/develop/ui/views/touch-and-input/copy-paste 操作反馈。Android 13 之后,在写入剪切板之后,会有自动的提示。而低版本就需要自己去实现提示,Toasts 或者 Snackbars。 fragment 与 activit ...

阅读全文...

android fragment 中调用父级 activity 中定义的方法

需求场景 一个 list / detail 的小 android app,分为两个 fragment 置于一个 activity 中。 list fragment 底部一个按钮,点击需要调用 activity 中的一个方法。 解决方法 (activity as YourActivityClassName).methodName() 实际上这个问题可以简化为,如何在 fragment 中获取其父级 activity。 由于 fragment 必然寄生于一个宿主 activity,所以可以直接通过 getActivity() 方法来得到宿主 activity,而 Kotlin 中则可以简写为 a ...

阅读全文...

registerForActivityResult 解决 startActivityForResult(Intent!, Int): Unit is deprecated. Deprecated in Java

举两个例子 例子一:开启蓝牙 废弃的 startActivityForResult 写法: const val ENABLE_BLUETOOTH_REQUEST_CODE = 1 val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) startActivityForResult(enableBtIntent, ENABLE_BLUETOOTH_REQUEST_CODE) 新的 registerForActivityResult 写法: val enableBtIntent = Intent(Bluetooth ...

阅读全文...