2017-01-04 15:56:55 zrf1335348191 阅读数 8264

本文已授权微信公众号  fanfan程序媛 上独家发布

刚好最近项目需求需要到这方面的知识,才发现这个有些欠缺,完善一下,记录下来,方便以后查阅

转载请注明出处

Android蓝牙配对弹出框过程分析


根据远程蓝牙设备(remote devices)的要求,手机端发起与远程蓝牙设备Bluetooth remote Device的配对有两种情况
第一种配对时需要pin码(pin request event)即有配对请求pairing request :所对应的action为 : BluetoothDevice.ACTION_PAIRING_REQUEST。

 根据远程设备所携带的type信息判断是否可以获取到pairingkey
     type值通过BluetoothDevice.EXTRA_PAIRING_VARIANT获取到

int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                    BluetoothDevice.ERROR);


     pairingkey通过BluetoothDevice.EXTRA_PAIRING_KEY获取到

 int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,
                        BluetoothDevice.ERROR);



如果type(int型数值)属于以下3种类型:
  • BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION(数值为2,远程设备为手机/scp860时为该类型),需要用户确认
  • BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY(数值为4),以前的一种配对方式,用在蓝牙2.1配对过程中,需要在本机(local device)输入显示在远程设备上的秘钥                passkey: enter the passkey displayed on remote device
  • BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN(数值为5),蓝牙2.0配对过程中,在本机输入显示在远程设备上的pin码:
     enter the PIN displayed on remote device
则表示远程设备(remote device)本身携带有配对码pairingkey,可以通过BluetoothDevice.EXTRA_PAIRING_KEY获取到配对码

如果type不属于以上3种类型,则表示远程设备不会携带pairingkey配对码,必须要用户自己手动输入:The user will be prompted to enter a pin or an app will enter a pin for user

第二种不需要pin码(create bond)没有配对请求(对应的设备有scp960,蓝牙耳机等),此时远程设备不需要鉴权,可以直接使用(just works)
所对应的action为:BluetoothDevice.ACTION_BOND_STATE_CHANGED

监听action的类为BluetoothPairingRequest.java,配对弹窗为BluetoothPairingDialog.java。字段信息存在于BluetoothDevice.java中


总结来说如果不以action为区分的话,配对分为三种情况

  • 直接配对连接不需要鉴权(just works):这种情况相当于手机发起配对时不需要请求远程设备,即不需要远程设备的认可
  • passkey/pin enter需要一方输入型:这种情况配对时会请求远程设备,然后远程设备会提供一个passk/pin码但不会通过代码的形式通知给用户,用户需要去查看远程设备显示的配对码并输入该pairingkey配对码(属于蓝牙2.0和2.1时的处理)
  • passkey/pin confirmmation无需输入密码只需确认型:这种情况配对时也会请求远程设备,远程会提供一个配对码并且通知给用户,此时代码中可以获取到pairingkey配对码,严格来说是用户需要查看远程设备上显示的配对码与当前手机上显示的配对码是否一致,进行比较(compare)确认后配对,所以属于确认型,对应于上述type的第一种类型
2019-06-07 13:56:34 qyvhome 阅读数 299
  • 简介

       随着物联网的趋势愈演愈烈,随之而来的产品升级,消费升级等等,一系列的需求就随之而来了。蓝牙这项古老而又生命力及其顽强的技术,也在不断的自我革命,自我升级,从而带给用户越来越多的惊喜,从2.1一直到现在的5.1版本,蓝牙的应用场景也是在不断的丰富,剑指物联网,大有一统终端的野心

大家都知道,物联网的无线部分,无非就是蓝牙、zigbee、wifi。小米的产品总监曾经有篇文章分析的很好,他的结论就是:

(1)、插电的设备,用WiFi;

(2)、需要和手机交互的,用BLE;

(3)、传感器用ZigBee。

 

  • 选型说明

回到蓝牙的选型问题上,我们大致可以分为以下的一些类别

 

  • 双模蓝牙介绍


 

  • BT401蓝牙模块介绍

 

2019-05-21 11:00:55 Lenzetech 阅读数 88

随着物联网渗透到各个行业领域,也使得各个领域对无线模块BLE蓝牙模块的需求激增。BLE蓝牙模块作为无线通信模块的一种,目前在智能家居、智能穿戴、智慧医疗、蓝牙室内定位等领域已经得到广泛应用。今天就来分析一下原因,浅析一下BLE蓝牙模块在智能家居的运用。
在这里插入图片描述
BLE5.0蓝牙在智能家居的运用
相比WiFi、ZigBee等技术,BLE蓝牙技术的优势就是低功耗、支持透明传输、性能稳定可靠,尺寸小巧,适合集成。这也使得BLE蓝牙技术在对于成本、体积、功耗有要求的市场中变得更为抢手,尤其在蓝牙5.0标准及蓝牙Mesh技术出来之后,解决了传输距离受限和组网的难题,更多智能照明及智能楼宇应用开始考虑使用BLE蓝牙解决方案。
伦茨蓝牙BLE5.0芯片支持主机、从机和主从一体的工作模式,PCB板载天线,工作电压1.7V~3.6V,由于可以采用电池供电,可以广泛适用于智能穿戴、移动设备、智能家居、物联网等场景。具体运用产品包括智能门禁智能门锁、智能机器人、智能台灯、智能垃圾桶、智能马桶、健康监控、智能手表、智能手环、智能照明等等。
(上述文章阐述归伦茨科技公司所有,转载请注明出处,更多相关信息欢迎关注微信公众号:lenze_tech或微信号:lenzetech)

2019-07-17 17:53:28 wende32 阅读数 55

1.目前的现象:蓝牙名称=设备名称(ro.product.model)

2.需求蓝牙名称 = (SN第一位)+型号(ro.product.model)4位+SN后三位//SN序列号是变化的,由写号工具烧写

例如:ro.product.model = TEST

SN:123456789ABCD

那么蓝牙名称 = 1TESTBCD

3.分析:在网上查找默认蓝牙名称都是固定的ro.product.model,应该是有调用的地方。经过网上搜索,确定是在system/bt/btif/src/btif_dm.cc调用

查看代码

#define NUM_TIMEOUT_RETRIES 5

#define PROPERTY_PRODUCT_MODEL "ro.product.model"
#define DEFAULT_LOCAL_NAME_MAX 31

......

static char* btif_get_default_local_name() {
  if (btif_default_local_name[0] == '\0') {
    int max_len = sizeof(btif_default_local_name) - 1;
    if (BTM_DEF_LOCAL_NAME[0] != '\0') {
      strncpy(btif_default_local_name, BTM_DEF_LOCAL_NAME, max_len);
    } else {
      char prop_model[PROPERTY_VALUE_MAX];
      osi_property_get(PROPERTY_PRODUCT_MODEL, prop_model, "");
      strncpy(btif_default_local_name, prop_model, max_len);
    }
    btif_default_local_name[max_len] = '\0';
  }
  return btif_default_local_name;
}

在btif_get_default_local_name中,把ro.product.model中的值给btif_default_local_name,那么在这里就可以修改,客制化。

+//add for bt name 
+#define PROPERTY_SERIALNO "ro.serialno"

static char* btif_get_default_local_name() {
  if (btif_default_local_name[0] == '\0') {
    int max_len = sizeof(btif_default_local_name) - 1;
    #if 0 //remove
    if (BTM_DEF_LOCAL_NAME[0] != '\0') {
      strncpy(btif_default_local_name, BTM_DEF_LOCAL_NAME, max_len);
    } else {
      char prop_model[PROPERTY_VALUE_MAX];
      osi_property_get(PROPERTY_PRODUCT_MODEL, prop_model, "");
      strncpy(btif_default_local_name, prop_model, max_len);
    }
    #endif //remove
    //add for bt name 
    char prop_model[PROPERTY_VALUE_MAX];
    char prop_serialno[PROPERTY_VALUE_MAX];
    osi_property_get(PROPERTY_PRODUCT_MODEL, prop_model, "");
    osi_property_get(PROPERTY_SERIALNO, prop_serialno, "");
    int len_model = strlen(prop_model);
    int len_serialno = strlen(prop_serialno);
    strncpy(btif_default_local_name, prop_model, max_len);
    if((len_serialno > 4) && (len_model > 3)){
         btif_default_local_name[0] = prop_serialno[0];
         for(int a = 1;a < 4; a = a + 1){
             btif_default_local_name[a] = prop_model[a - 1];
              btif_default_local_name[len_model + a] = prop_serialno[len_serialno - 4 + a];
         }
    }else{
        strncpy(btif_default_local_name, prop_model, max_len);
    } 
    btif_default_local_name[max_len] = '\0';
  }
  return btif_default_local_name;
}

修改编译,没有生效,查看开机log,提示蓝牙权限avc。不允许bluetooth去获取系统属性ro.serialno。

在网上搜索添加权限,由于不是很熟悉,所以基本在所有的bluetooth.te都添加了。

device/mediatek/sepolicy/basic/non_plat/bluetooth.te

system/sepolicy/prebuilts/api/26.0/private/bluetooth.te

system/sepolicy/private/bluetooth.te

+allow bluetooth serialno_prop:file { read open getattr};

编译报错,不允许添加,继续修改添加例外。

在system/sepolicy/prebuilts/api/26.0/public/domain.te

system/sepolicy/public/domain.te

# Do not allow reading device's serial number from system properties except form
# a few whitelisted domains.
neverallow {
  domain
  -adbd
  -dumpstate
  -hal_drm
  -hal_cas
  -init
  -mediadrmserver
  -recovery
  -shell
  -system_server
+ -bluetooth
} serialno_prop:file r_file_perms;

以上做个记录,如有更好的方式,欢迎交流。

 

 

 

2019-08-07 16:58:59 jakezhang1990 阅读数 318


最近在做一个手柄蓝牙连接手机,通过手柄控制手机的焦点需求,这里简单总结记录下。

先分析一下需求:

通过手柄摇杆或者十字按键控制手机的焦点,控制一个左侧箭头是减按钮,中间是显示数量的TextView文本,右侧箭头是增加按钮,当向左摇动摇杆或者按十字按键的左按键进行减少操作,当向右摇杆或者按十字按键的右按键进行增加操作。
最后,当选中某一列的时候,底部要给一个选中的反馈效果。
demo地址:https://github.com/jakezhang1990/BluetoothHandleDemo
看一效果图:
在这里插入图片描述
也就是说期望的效果是:
按十字按键的左按键或者左摇杆,数字减少;
按十字按键的右按键或者右摇杆,增加;
按十字按键的向下十字按键或者向下摇杆到最后一个条目,吐司提示,是最后一个条目了,焦点停留在这里。

首先,手柄设备蓝牙连接到手机,这没什么说的,直接按照手柄的说明书进行连接即可。

其次,就是拦截,在onKeyDown方法中进行拦截。

KeyEvent.KEYCODE_DPAD_LEFT 左摇杆或者十字按键左按键按下事件。
KeyEvent.KEYCODE_DPAD_RIGHT 右摇杆或者十字按键右按键按下事件。
KeyEvent.KEYCODE_DPAD_UP 向上摇杆或者十字按键向上按键按下事件。
KeyEvent.KEYCODE_DPAD_DOWN 向下摇杆或者十字按键向下按键按下事件

这么多按钮,必须得根据目前焦点在哪个按钮上来判断出现在会触发哪个按钮的事件。

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    //item2
        if (keyCode==KeyEvent.KEYCODE_DPAD_LEFT&&item2_leftBtn.hasFocus()){
            //码率左摇杆
            bitRatLeftRock();
            return true;
        }else if (keyCode==KeyEvent.KEYCODE_DPAD_RIGHT&&item2_rightBtn.hasFocus()){
            //码率右摇杆
            bitRatRightRock();
            return true;
   		 }
   		 return super.onKeyDown(keyCode, event);
 }

第三,反馈背景的设置问题。

可以通过焦点监听来设置。setOnFocusChangeListener
但是这样之后会有一个问题,左右箭头的按钮点击事件被拦截掉了,无法触发了,只能通过手柄的控制才能进行设置了,所以需要给箭头按钮加上点击事件监听setOnClickListener

最后,在android9.0上的bug解决。

在不同的状态下显示不同的图片,使用的是在drawable中通过state_focused属性和state_enable来进行4种状态的图片展示。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_enabled="false" android:state_focused="false" android:drawable="@drawable/triangle_left_disable"/>
    <item android:state_enabled="true" android:state_focused="false" android:drawable="@drawable/triangle_left_enable"/>
    <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/triangle_left_focus_enable"/>
    <item android:state_enabled="false" android:state_focused="true" android:drawable="@drawable/triangle_left_focus_disable"/>

</selector>

在8.0及以下的系统中是没问题的,使用手柄正常展示。但是在9.0系统上会出现bug,焦点乱跑,也就是说,当向左一直按十字按键或者向左摇杆,当选择成了最小值的时候,再向左侧按键或者二摇杆,就会出现焦点乱跑到其他地方的bug,而且,左侧如果是最小值的时候,左侧按键,使用手柄上下移动焦点的时候,这个按键也无法获取焦点,会直接跳过去,导致焦点错乱。

解决:

仔细想想这里应该使用state_focusstate_selected两个属性进行控制。state_enableandroid9.0上会直接将焦点给过滤掉,将当前所在的焦点转义到下一个可以获得焦点的控件上。
step1:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item  android:state_focused="false" android:state_selected="false" android:drawable="@drawable/triangle_left_disable"/>
    <item android:state_focused="false" android:state_selected="true" android:drawable="@drawable/triangle_left_enable"/>
    <item android:state_focused="true" android:state_selected="true" android:drawable="@drawable/triangle_left_focus_enable"/>
    <item android:state_focused="true" android:state_selected="false" android:drawable="@drawable/triangle_left_focus_disable"/>

    <!--
    <item android:state_enabled="false" android:state_focused="false" android:drawable="@drawable/triangle_left_disable"/>
    <item android:state_enabled="true" android:state_focused="false" android:drawable="@drawable/triangle_left_enable"/>
    <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/triangle_left_focus_enable"/>
    <item android:state_enabled="false" android:state_focused="true" android:drawable="@drawable/triangle_left_focus_disable"/>
-->
</selector>

step2:
将activity中,左右按键切换时,控制左右按钮的state_enable的设置item2_leftBtn.setEnabled(xxx);这类似的按钮的可点不可点状态的设置代码全部注释掉,或者全部替换成item2_leftBtn.setSelected(xxx);进行设置。

这样就解决了,在android9.0上焦点乱跑的问题。

参考链接:
https://www.jianshu.com/p/c0a76cc496fb
Google官方文档:https://developer.android.google.cn/reference/android/view/MotionEvent.html#AXIS_LTRIGGER
亚马逊也是做类似的产品,有一片参考文档:https://developer.amazon.com/zh/docs/fire-tv/getting-started-developing-apps-and-games.html

没有更多推荐了,返回首页