前言
关于Android的低功耗蓝牙,我做了很多介绍了,那么对于Harmony来说这一块我没有做过介绍,而实际中我确实做过一个Harmony的BLE项目,所以这里分享一些内容出来。
正文
在Harmony中进行Ble的蓝牙开发实际上和Android中类似,但是又有一些不同,因为Harmony的SDK还在不断的完善。而这里我们使用的是API 6进行项目开发,使用的语言是Java,至于为什么使用API 6而不是最新的API 9,因为我买不起遥遥领先,所以只能用API 6的HUAWEI P30进行真机测试。蓝牙这种APP一定是要使用真机测试的,你用虚拟机是不行的,话不多说,我们开始吧。
一、创建工程
下面开始创建工程。
选择Empty Ability
,点击Next。我们创建一个名为HarmonyBle
的项目,语言为Java。
点击Finish
完成创建。
默认的工程就是这个样子的,是不是很像Android创建的工程呢?
二、工程配置
① 权限配置
Harmony中同样有权限这个概念,也需要配置静态权限和动态权限,只不过配置静态权限的地方不一样。Harmony是在config.json
中,里面的代码如下:
{ "app": { "bundleName": "com.llw.ble", "vendor": "example", "version": { "code": 1000000, "name": "1.0.0" } }, "deviceConfig": { }, "module": { "package": "com.llw.ble", "name": ".MyApplication", "mainAbility": "com.llw.ble.MainAbility", "deviceType": [ "phone", "tablet", "tv", "wearable", "car" ], "distro": { "deliveryWithInstall": true, "moduleName": "entry", "moduleType": "entry", "installationFree": false }, "abilities": [ { "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "action.system.home" ] } ], "name": "com.llw.ble.MainAbility", "description": "$string:mainability_description", "icon": "$media:icon", "label": "$string:entry_MainAbility", "launchType": "standard", "orientation": "unspecified", "visible": true, "type": "page" } ] } }
你阅读一下,你就会发现,这和Android的AndroidManifest.xml
配置文件好像差不多啊。只不过一个用的是json,一个用的是xml。
所以我们配置权限也是在config.json
中,例如扫描蓝牙时我们需要定位权限。可以在里面增加如下代码:
"reqPermissions": [ { "name": "ohos.permission.LOCATION" }, { "name": "ohos.permission.USE_BLUETOOTH" }, { "name": "ohos.permission.DISCOVER_BLUETOOTH" }, { "name": "ohos.permission.MANAGE_BLUETOOTH" } ]
如下图所示,注意json中标点符号。
② Debug配置
然后我们就应该要来写代码了,不过在此之前,我们先了解一下Ability和Slice的区别,Ability就像一个画框,而Slice就像一个画布。我们可以在一个画框里面加载多个画布,就好像多个页面之前的跳转,我们可以用Slice来进行,下面我们增加一个扫描的Slice,我们复制一下MainAbilitySlice,再粘贴一下,出现的弹窗中改名字
为什么要通过这种方式来创建Java文件呢?因为DevEco Studio我创建不了Java文件,可能是这个版本的DS没有这个选项亦或是我没有找到。
下面我们需要创建对应layout文件,再resources/base/layout下创建一个slice_scan.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <ListContainer ohos:id="$+id:lc_device" ohos:height="match_parent" ohos:width="match_parent"/> </DirectionalLayout>
然后我们再修改ScanSlice中的内容,让它加载我们刚写好的slice_scan.xml。修改onStart()方法,代码如下所示:
@Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_slice_scan); }
现在App打开之后默认会运行MainAbility,我们看一下这个里面。
public class MainAbility extends Ability { @Override public void onStart(Intent intent) { super.onStart(intent); super.setMainRoute(MainAbilitySlice.class.getName()); } }
可以看到,在setMainRoute()方法中,默认加载的是MainAbilitySlice
,将它改为我们刚写好的ScanSlice
,代码:super.setMainRoute(ScanSlice.class.getName());
然后我们先运行一下看看,通过USB链接到鸿蒙手机上。
这里会提示报错,浏览一下错误信息。
这里是说我们需要配置Signing。点击Run下面或者右侧弹窗的Open signing configs
,会打开一个配置窗口,如下图所示:
我们点击Signing Configs
选项,需要你进行登录,如下图所示:
这里就需要你登录华为的帐号了,我们当前在本地运行所以是Debug模式,旁边有一个Release表示发布版本,它里面配置的东西和Debug模式一致,区别在于Debug模式下的配置信息只要我们登录之后,DevEco Studio会帮助我们自动生成,而Release中的信息则需要开发者去华为开发者官网上去创建应用并申请配置文件和证书,比较麻烦,但是如果你要上架应用则必须做这一步,在国内,华为应用市场上架应用是最严格的。华为的你搞得定,其他的都是小趴菜,不值一提。
下面我们先登录,会打开一个网页,登录成功之后,你会看到这样的页面。
然后我们回到DS,就会自动配置Debug模式下的证书和配置文件,如下图所示:
点击OK,会在DS中进行一个配置,配置好之后你可以在工程目录下的build.gradle
中看到debug的相关信息,如下图所示。
然后我们再运行一下看看,这一次毫无疑问是可以运行成功的。如下图所示:
③ UI配置
可以看到默认的标题栏就如同Android
默认的ActionBar
,丑的很特别,我们去掉它,在config.json中添加如下代码:
"metaData": { "customizeData": [ { "extra": "", "name": "hwc-theme", "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar" } ] },
添加位置如下所示:
下面我们再运行一下看看。
是不是Unbelievable!
同样为了标题好看,我们在element下创建一个color.json
,里面的代码如下所示:
{ "color": [ { "name": "white", "value": "#FFF" }, { "name": "black", "value": "#000" }, { "name": "blue", "value": "#FFA7D3FF" }, { "name": "bg_color", "value": "#F8F8F8" }, { "name": "gray", "value": "#989898" } ] }
我们再修改一下scan_slice.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:background_element="$color:bg_color" ohos:orientation="vertical"> <DirectionalLayout ohos:height="50vp" ohos:width="match_parent" ohos:alignment="vertical_center" ohos:background_element="$color:blue" ohos:orientation="horizontal" ohos:start_padding="12vp"> <Text ohos:id="$+id:title" ohos:height="match_content" ohos:width="match_content" ohos:text="选择设备" ohos:text_color="#FFF" ohos:text_font="HwChinese-medium" ohos:text_size="18fp" ohos:weight="1"/> <Text ohos:id="$+id:tx_scan_status" ohos:height="match_content" ohos:width="match_content" ohos:end_margin="6vp" ohos:padding="8vp" ohos:text="搜索" ohos:text_color="#FFF" ohos:text_size="14fp"/> </DirectionalLayout> <ListContainer ohos:id="$+id:lc_device" ohos:height="match_parent" ohos:width="match_parent"/> </DirectionalLayout>
这个DirectionalLayout
布局就是线性布局,我们可以点击右侧导航栏的Previewer
进行布局预览,如下图所示。
右上角的T图标,点击之后可以查看当前布局的层级。
这里说明一下,有时候在通过资源使用颜色值的时候会无法生效,所以就会直接使用#FFF
,在代码里也是如此,这应该属于编译器的Bug。
标题栏就写好了,还有状态栏我们没有改,状态栏我们在MainAbility中进行修改,代码如下所示:
@Override public void onStart(Intent intent) { Window window = WindowManager.getInstance().getTopWindow().get(); window.setStatusBarColor(Color.getIntColor("#A7D3FF")); super.onStart(intent); super.setMainRoute(ScanSlice.class.getName()); }
还是修改onStart()
方法,然后我们运行一下看看。
好了,下面我们来写扫描需要的内容代码。
Harmony Ble 蓝牙App (一)扫描(下)https://developer.aliyun.com/article/1407942