小程序 蓝牙连接

小程序 蓝牙连接,第1张

//初始化蓝牙

initBlue() {

var that = this;

wxopenBluetoothAdapter({ //调用微信小程序api 打开蓝牙适配器接口

success: function (res) {

consolelog('1初始化蓝牙成功')

},

//监听手机蓝牙的开关

monitorTheBlue:function(){

var that =this;

wxonBluetoothAdapterStateChange(function(res){

})

},

//开始获取附近的蓝牙设备

// 获取到附近的蓝牙数组 通过蓝牙特定的名称获取自己想要连接的蓝牙设备

// 获取附近蓝牙设备的数组

findBlue() {

consolelog(new Date())

var that = this

wxstartBluetoothDevicesDiscovery({

allowDuplicatesKey: false,

interval: 0,

success: function (res) {

consolelog('2正在搜索设备')

if (thatdataisFirestShow) {

wxshowLoading({

title: '正在搜索设备'

})

}

},

//搜索获取附近的所有蓝牙设备 获取附近所有的蓝牙设备的相关信息 获取需要连接蓝牙设备的deviceID

// 通过bluetoothDeviceName 和 localName 来确定制定蓝牙

// 一般根据制定设备的名字去连接 设备的名字 是出产厂家设定

getBlue() {

var that = this

wxgetBluetoothDevices({

success: function (res) {

consolelog('3找到设备列表')

wxhideLoading()

// return false

var index = 10

for (var i = 0; i < resdeviceslength; i++) {

if (resdevices[i]name && resdevices[i]localName) {

var arr = resdevices[i]namesplit("-")

var secArr = resdevices[i]localNamesplit("-")

if (arr[0] == thatdatabluetoothDeviceName || secArr[0] == thatdatabluetoothDeviceName) {

},

//连接蓝牙设备

//通过deviceId 连接蓝牙

/

},

//6 连接上需要的蓝牙设备之后,获取这个蓝牙设备的服务uuid

//获取设备的uuid

getServiceId() {

var that = this

wxgetBLEDeviceServices({

// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接

deviceId: thatdatadeviceId,

success: function (res) {

var model = resservices[1]

thatsetData({

servicesUUID: modeluuid

})

consolelog('7获取设备 uuid 成功')

thatgetCharacteId() //60

}

})

},

//7 如果一个蓝牙设备需要进行数据的写入以及数据传输,就必须具有某些特征值,所以通过上面步骤获取的id可以查看当前蓝牙设备的特征值

//notify write read 当只有 notify为true的时候才能 接收蓝牙设备传来的数据,

//write 为true 才能传入数据

//read 为true 才能读取设备数据

getCharacteId() {

var that = this

wxgetBLEDeviceCharacteristics({

// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接

deviceId: thatdatadeviceId,

// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取

serviceId: thatdataservicesUUID,

success: function (res) {

for (var i = 0; i < rescharacteristicslength; i++) { //2个值

var model = rescharacteristics[i]

if (modelpropertiesnotify == true) {

thatsetData({

characteristicId: modeluuid //监听的值

})

consolelog('8modelpropertiesnotify == true')

thatstartNotice(modeluuid) //70

}

// if (modelpropertiesread == true) {

// thatreadData(modeluuid)

// }

// if (modelpropertieswrite == true) {

// thatsetData({

// writeId: modeluuid//用来写入的值

// })

// }

}

}

})

},

fordateTime1(){

let now = new Date(),hour = nowgetHours()

consolelog(hour)

let str = ''

if(hour < 7){str = '早餐前'}

else if ((7< hour) && (hour<= 9)){str = '早餐后'}

else if ((9< hour) && (hour<= 11)){str = '午餐前'}

else if ((11< hour) && (hour<= 13)){str = '午餐后'}

else if ((13< hour) && (hour<= 17)){str = '晚餐前'}

else if ((17< hour) && (hour<= 19)){str = '晚餐后'}

else if ((19< hour) && (hour<= 24)){str = '睡觉前'}

return str

},

//8 如果一个蓝牙设备需要进行数据的写入以及数据传输,就必须具有某些特征值,所以通过上面步骤获取的id可以查看当前蓝牙设备的特征值

//开启设备数据监听 监听蓝牙设备返回来的数据

startNotice(uuid) {

var that = this;

wxnotifyBLECharacteristicValueChanged({

state: true, // 启用 notify 功能

deviceId: thatdatadeviceId,

serviceId: thatdataservicesUUID,

characteristicId: uuid, //第一步 开启监听 notityid 第二步发送指令 write

success: function (res) {

// thatcloseConnect(thatdatadeviceId)

// 设备返回的方法

let tip = 0

wxonBLECharacteristicValueChange(res1 => {

},

/

//监听蓝牙设备是否会异常断开

getTheBlueDisConnectWithAccident() {

},

// 断开设备连接

closeConnect: function(v) {

var that = this

if (v) {

wxcloseBLEConnection({

deviceId: v,

success: function(res) {

consolelog("蓝牙断开连接")

thatcloseBluetoothAdapter()

},

fail(res) {

}

})

} else {

thatcloseBluetoothAdapter()

}

},

// 关闭蓝牙模块

closeBluetoothAdapter:function () {

wxcloseBluetoothAdapter({

success: function(res) {

consolelog("关闭蓝牙模块")

},

fail: function(err) {

}

})

},

DEVICE_ID

这是Android系统为开发者提供的用于标识手机设备的串号,也是各种方法中普适性较高的,可以说几乎所有的设备都可以返回这个串号,并且唯一性良好。

这个DEVICE_ID可以同通过下面的方法获取:

TelephonyManager tm = (TelephonyManager)getSystemService(ContextTELEPHONY_SERVICE); String DEVICE_ID = tmgetDeviceId();

它会根据不同的手机设备返回IMEI,MEID或者ESN码,但在使用的过程中有以下问题:

非手机设备:最开始搭载Android系统都手机设备,而现在也出现了非手机设备:如平板电脑、电子书、电视、音乐播放器等。这些设备没有通话的硬件功能,系统中也就没有TELEPHONY_SERVICE,自然也就无法通过上面的方法获得DEVICE_ID。

权限问题:获取DEVICE_ID需要READ_PHONE_STATE权限,如果只是为了获取DEVICE_ID而没有用到其他的通话功能,申请这个权限一来大才小用,二来部分用户会怀疑软件的安全性。

厂商定制系统中的Bug:少数手机设备上,由于该实现有漏洞,会返回垃圾,如:zeros或者asterisks

MAC ADDRESS

可以使用手机Wifi或蓝牙的MAC地址作为设备标识,但是并不推荐这么做,原因有以下两点:

硬件限制:并不是所有的设备都有Wifi和蓝牙硬件,硬件不存在自然也就得不到这一信息。

获取的限制:如果Wifi没有打开过,是无法获取其Mac地址的;而蓝牙是只有在打开的时候才能获取到其Mac地址。

获取Wifi Mac地址:

获取蓝牙 Mac地址:

Sim Serial Number

装有SIM卡的设备,可以通过下面的方法获取到Sim Serial Number:

TelephonyManager tm = (TelephonyManager)getSystemService(ContextTELEPHONY_SERVICE); String SimSerialNumber = tmgetSimSerialNumber();

注意:对于CDMA设备,返回的是一个空值!

ANDROID_ID

在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置。可以通过下面的方法获取:

import androidproviderSettings; String ANDROID_ID = SettingsSystemgetString(getContentResolver(), SettingsSystemANDROID_ID);

ANDROID_ID可以作为设备标识,但需要注意:

厂商定制系统的Bug:不同的设备可能会产生相同的ANDROID_ID:9774d56d682e549c。

厂商定制系统的Bug:有些设备返回的值为null。

设备差异:对于CDMA设备,ANDROID_ID和TelephonyManagergetDeviceId() 返回相同的值。

Serial Number

Android系统23版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。

String SerialNumber = androidosBuildSERIAL;

有很多场景和需求你需要用到手机设备的唯一标识符。例如,略。

在Android中,有以下几种方法获取这样的ID。

1 The IMEI: 仅仅只对Android手机有效:

TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);

String szImei = TelephonyMgrgetDeviceId(); // Requires READ_PHONE_STATE

采用此种方法,需要在AndroidManifestxml中加入一个许可:androidpermissionREAD_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 359881030314356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0000000000000)。

2 Pseudo-Unique ID, 这个在任何Android手机中都有效

有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及Rom 镜像)。但应当明白的是,出现类似情况的可能性基本可以忽略。要实现这一点,你可以使用Build类:

String m_szDevIDShort = "35" + //we make this look like a valid IMEI

BuildBOARDlength()%10+ BuildBRANDlength()%10 + BuildCPU_ABIlength()%10 + BuildDEVICElength()%10 + BuildDISPLAYlength()%10 + BuildHOSTlength()%10 + BuildIDlength()%10 + BuildMANUFACTURERlength()%10 + BuildMODELlength()%10 + BuildPRODUCTlength()%10 + BuildTAGSlength()%10 + BuildTYPElength()%10 + BuildUSERlength()%10 ; //13 digits

大多数的Build成员都是字符串形式的,我们只取他们的长度信息。我们取到13个数字,并在前面加上“35”。这样这个ID看起来就和15位IMEI一样了。

3 The Android ID , 通常被认为不可信,因为它有时为null。开发文档中说明了:这个ID会改变如果进行了出厂设置。并且,如果某个Andorid手机被Root过的话,这个ID也可以被任意改变。

String m_szAndroidID = SecuregetString(getContentResolver(), SecureANDROID_ID);

Returns: 9774d56d682e549c 无需任何许可。

4 The WLAN MAC Address string, 是另一个唯一ID。但是你需要为你的工程加入androidpermissionACCESS_WIFI_STATE 权限,否则这个地址会为null。

WifiManager wm = (WifiManager)getSystemService(ContextWIFI_SERVICE);

String m_szWLANMAC = wmgetConnectionInfo()getMacAddress();

Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。)WLan不必打开,就可读取些值。

5 The BT MAC Address string, 只在有蓝牙的设备上运行。并且要加入androidpermissionBLUETOOTH 权限

BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter

m_BluetoothAdapter = BluetoothAdaptergetDefaultAdapter();

String m_szBTMAC = m_BluetoothAdaptergetAddress();

Returns: 43:25:78:50:93:38 蓝牙没有必要打开,也能读取。

Combined Device ID

综上所述,我们一共有五种方式取得设备的唯一标识。它们中的一些可能会返回null,或者由于硬件缺失、权限问题等获取失败。

但你总能获得至少一个能用。所以,最好的方法就是通过拼接,或者拼接后的计算出的MD5值来产生一个结果。

String m_szLongID = m_szImei + m_szDevIDShort

+ m_szAndroidID+ m_szWLANMAC + m_szBTMAC;

// compute md5

MessageDigest m = null;

try {

m = MessageDigestgetInstance("MD5");

} catch (NoSuchAlgorithmException e) {

eprintStackTrace();

}

mupdate(m_szLongIDgetBytes(),0,m_szLongIDlength());

// get md5 bytes

byte p_md5Data[] = mdigest();

// create a hex string

String m_szUniqueID = new String();

for (int i=0;i<p_md5Datalength;i++) {

int b = (0xFF & p_md5Data[i]);

// if it is a single digit, make sure it have 0 in front (proper padding)

if (b <= 0xF)

m_szUniqueID+="0";

// add number to string

m_szUniqueID+=IntegertoHexString(b);

} // hex string to uppercase

m_szUniqueID = m_szUniqueIDtoUpperCase();

通过以上算法,可产生32位的16进制数据:

9DDDF85AFF0A87974CE4541BD94D5F55

现在你就可以对其进行你的应用了。

我实现的小程序模块自动连接(根据需要,可改手动),是在小程序初始化完成时开始自动调用执行。

大致流程:

开启蓝牙适配;

获取蓝牙适配器状态,判断设备蓝牙是否可用;

判断蓝牙适配器可用时开启扫描蓝牙设备和开启获取已连接的蓝牙设备;

如果开启扫描蓝牙设备失败 5 s 后,自动再次开启扫描;

开启扫描蓝牙设备成功后,开启监听已扫描的设备;

如果已扫描到的新设备,包含特定名称规律,则开始连接该设备;

开启获取已连接蓝牙设备,成功后,连接包含特定名称规律的设备;

两者都无法搜索到相应设备,则等待 5 s,重新搜索;

开始连接某设备时停止扫描设备,停止循环获取已连接设备;

连接成功后停止扫描设备,停止循环获取已连接设备。

​下面,我们一步步来完成这个流程。

开始连接蓝牙设备

1 开启连接

appjs的onLaunch()方法里中,我们调用thisstartConnect();来开启连接,d出提示框,进行配对。如果失败,则提示设备蓝牙不可用,同时开启蓝牙适配器状态监听。

2 获取本机蓝牙状态

调用thisgetBluetoothAdapterState()获取本机蓝牙适配器状态,判断是否可用。若available为false,则为用户没有开启系统蓝牙。

同时,判断程序还没有开始搜索蓝牙设备,调用thisstartBluetoothDevicesDiscovery()开始扫描附近的蓝牙设备,以及thisgetConnectedBluetoothDevices(),获取本机已配对的蓝牙设备。

3 开始搜索新设备

开始搜索蓝牙设备startBluetoothDevicesDiscovery(),提示蓝牙搜索。

4 获取已配对的蓝牙设备

需要注意的是,参数services(Array)是必填的,但是官方示例中以及各种坑爹 demo 里从没见过有谁填写。不填写这个属性此方法,将无法获取到任何已配对设备。

如果要调用此方法,则代表需要连接特定设备,并且知道该设备的一个主服务serviceId。

如暂时不知道这个 ID,可以先手动连接一次想要连接的设备,然后获取service列表,记录属性primary为true的值至少一个。5 处理搜索功能开启失败的情况

如果搜索功能启动失败,回到第 2 步,重新检查蓝牙适配器。如果可用,开启蓝牙搜索功能并开启发现附近蓝牙设备事件监听:thisonBluetoothDeviceFound()。

此方法可自定义过滤一些无效的蓝牙设备,比如name为空的,或是产品开发中,需要过滤设备名称不含有特定规律字符串的设备。

6 自动配对设备

在第 5 步中发现了某个想配对的设备,则获取到该设备的deviceId,然后用thisstartConnectDevices()接口,开始配对该设备。

开启连接后,为了避免出现冲突,一旦开启连接,则需要终止扫描附近蓝牙设备、终止读取本机已配对设备

7 连接成功后握手

连接成功后,使用thisgetService(deviceId)接口,获取设备的所有服务。

8 读取服务的特征值

9 意外处理

如果扫描到的设备中没有想要连接的设备,可以尝试使用系统蓝牙手动配对,然后再小程序中调用getConnectedBluetoothDevices()获取本机已配对的蓝牙设备,然后过滤设备(可能获取多个已配对的蓝牙设备)。

然后,将已获取的蓝牙设备deviceId列表放入到一个数组中,然后调用自定义方法thisloopConnect();

思路:通过递归调用获取已配对蓝牙设备的,如果获取到了就去连接,如果devicesId[x]为空,说明上传调用时,获取到的已配对设备全部连接失败了。

这时候,我们需要则开启重新获取已配对蓝牙设备,并开启扫描附近蓝牙设备。

10 自动循环重试

startConnectDevices('loop', array)方法,是当获取已配对蓝牙设备进行连接时调用。

其中的处理逻辑上文已经贴出,意思就是在连接失败后fail方法里累加一个全局变量,然后回调loopConnect(array)方法。

11 手动连接

上文介绍的方法是为了直接自动连接,如果不需要自动连接,可使用方法getBluetoothDevices(),获取已扫描到的蓝牙设备的列表。

开发者可以做个页面显示出设备名,用户点击某个设备后,才开始连接。

需要注意的事项

thatserviceId是在初始化时设置的,由于对需要连接设备的主服务serivceId和各种特征值都是已知的,因此可以这样做。如果不可知,可以做一个扫描方法自己检查特征值的用途。

连接成功后的writeBLECharacteristicValue和openNotifyService *** 作需要注意,如果同时开启这两项 *** 作要先调用wirte再开启notify(原因未知,个人心得)。

3、经提醒,我发现还可以再完善一下在onBlueToothAdapterStateChange()监听蓝牙适配器状态,以此判断连接过程中、连接后用户开关了设备蓝牙。如果判断到关了蓝牙,发出开启蓝牙的提示;如果监听到开启了,就重新回到第 1 步。

安卓系统手机的DEVICE ID只要很简单的一个命令就可以查看:

1、点击电话,启动拨号界面,然后输入“##8255##”即可进入GTalk Service Monitor界面了。

GTalk Service Monitor界面

2、红圈圈便是Device ID了。

以上就是关于小程序 蓝牙连接全部的内容,包括:小程序 蓝牙连接、如何获取Android设备唯一识别码、如何获取Android唯一标识等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9455582.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存