• Android蓝牙自动配对Demo,亲测好使!!!(转)


    蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框。


    转载请注明出处http://blog.csdn.net/qq_25827845/article/details/52400782

     

    源码下载地址:https://github.com/chaohuangtianjie994/BlueTooth-AutoPair

    经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的Demo。

    说明如下:

    1、本Demo用来连接蓝牙设备HC-05,如果你要连接其他蓝牙设备,注意修改相关名字以及修改设备初试pin值。

    2、将Demo安装在Android手机上,点击按钮,可以实现与目标蓝牙设备的自动配对。

    3、若目标蓝牙设备为Android手机的蓝牙,则只能保证本设备不弹出配对框,对方还是会弹出配对框。但是!!不管目标蓝牙点击“确认”or“取消”,在本设备中都显示已经成功配对。实测表明,确实已经配对了,可以进行数据传输。

    4、由于使用了广播机制,所以需要在Androidmanifest.xml进行如下配置。

    先配置蓝牙使用权限:

         <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 

    然后配置action,将需要用到的广播进行注册

    <receiver android:name="com.ywq.broadcast.BluetoothReceiver" >
        <intent-filter android:priority="1000">
            <action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/>
            <action android:name="android.bluetooth.device.action.FOUND" />
        </intent-filter>
    </receiver>

    程序运行流程:

    1、点击按钮,判断蓝牙是否打开,,执行bluetoothAdapter.startDiscovery();由本地蓝牙设备扫描远程蓝牙设备,startDiscovery()方法是一个异步方法,调用后立即返回。该方法会进行蓝牙设备的搜索,持续12秒。

    2、搜索时,系统会发送3个广播,分别为:ACTION_DISCOVERY_START:开始搜索 、ACTION_DISCOVERY_FINISHED:搜索结束、 ACTION_FOUND:找到设备,该Intent中包含两个extra fields;         

    3、在广播接收类中BluetoothReceiver.java中,当设备找到之后会执行其onReceive方法。

    4、String action = intent.getAction(); //得到action,

    第一次action的值为BluetoothDevice.ACTION_FOUND,当找到的设备是我们目标蓝牙设备时,调用createBond方法来进行配对。ClsUtils.createBond(btDevice.getClass(), btDevice);该方法执行后,系统会收到一个请求配对的广播,即android.bluetooth.device.action.PAIRING_REQUEST。最后进行自动配对操作。

    5、配对操作借助工具类ClsUtils.java得到了Android蓝牙API中隐藏的方法,实现自动配对,不弹出配对框的功能。

    代码如下:

    MainActivity.java

    [java] view plain copy
     
    1. package com.example.mybuletooth;  
    2.   
    3. import android.app.Activity;  
    4. import android.bluetooth.BluetoothAdapter;  
    5. import android.os.Bundle;  
    6. import android.view.View;  
    7. import android.view.View.OnClickListener;  
    8. import android.widget.Button;  
    9.   
    10. public class MainActivity extends Activity implements OnClickListener{  
    11.       
    12.     /** Called when the activity is first created. */   
    13.     private Button autopairbtn=null;  
    14.     private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
    15.   
    16.     @Override  
    17.     protected void onCreate(Bundle savedInstanceState) {  
    18.         super.onCreate(savedInstanceState);  
    19.         setContentView(R.layout.activity_main);  
    20.           
    21.         autopairbtn=(Button) findViewById(R.id.button1);  
    22.         autopairbtn.setOnClickListener(this);  
    23.           
    24.     }  
    25.       
    26.     //设置按钮的监听方法  
    27.     @Override  
    28.     public void onClick(View arg0) {  
    29.           
    30.         if (!bluetoothAdapter.isEnabled())  
    31.         {  
    32.                 bluetoothAdapter.enable();//异步的,不会等待结果,直接返回。  
    33.         }else{  
    34.                 bluetoothAdapter.startDiscovery();  
    35.              }  
    36.           
    37.     }  
    38. }  

    BluetoothReceiver.java

    [java] view plain copy
     
    1. package com.ywq.broadcast;  
    2.   
    3. import com.ywq.tools.ClsUtils;  
    4. import android.bluetooth.BluetoothDevice;  
    5. import android.content.BroadcastReceiver;  
    6. import android.content.Context;  
    7. import android.content.Intent;  
    8. import android.util.Log;  
    9.   
    10.   
    11. public class BluetoothReceiver extends BroadcastReceiver{  
    12.   
    13.     String pin = "1234";  //此处为你要连接的蓝牙设备的初始密钥,一般为1234或0000  
    14.     public BluetoothReceiver() {  
    15.           
    16.     }  
    17.   
    18.     //广播接收器,当远程蓝牙设备被发现时,回调函数onReceiver()会被执行   
    19.     @Override  
    20.     public void onReceive(Context context, Intent intent) {  
    21.           
    22.         String action = intent.getAction(); //得到action  
    23.         Log.e("action1=", action);  
    24.         BluetoothDevice btDevice=null;  //创建一个蓝牙device对象  
    25.          // 从Intent中获取设备对象  
    26.         btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);   
    27.           
    28.         if(BluetoothDevice.ACTION_FOUND.equals(action)){  //发现设备  
    29.             Log.e("发现设备:", "["+btDevice.getName()+"]"+":"+btDevice.getAddress());  
    30.               
    31.             if(btDevice.getName().contains("HC-05"))//HC-05设备如果有多个,第一个搜到的那个会被尝试。  
    32.             {  
    33.                 if (btDevice.getBondState() == BluetoothDevice.BOND_NONE) {    
    34.                       
    35.                     Log.e("ywq", "attemp to bond:"+"["+btDevice.getName()+"]");  
    36.                     try {  
    37.                         //通过工具类ClsUtils,调用createBond方法  
    38.                         ClsUtils.createBond(btDevice.getClass(), btDevice);  
    39.                     } catch (Exception e) {  
    40.                         // TODO Auto-generated catch block  
    41.                         e.printStackTrace();  
    42.                     }  
    43.                 }  
    44.             }else  
    45.                 Log.e("error", "Is faild");  
    46.         }else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST  
    47.         {  
    48.             Log.e("action2=", action);  
    49.             if(btDevice.getName().contains("HC-05"))  
    50.             {  
    51.                 Log.e("here", "OKOKOK");  
    52.                   
    53.                 try {  
    54.                       
    55.                     //1.确认配对  
    56.                     ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);  
    57.                     //2.终止有序广播  
    58.                     Log.i("order...", "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast());  
    59.                     abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。  
    60.                     //3.调用setPin方法进行配对...  
    61.                     boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, pin);  
    62.                       
    63.                 } catch (Exception e) {  
    64.                     // TODO Auto-generated catch block  
    65.                     e.printStackTrace();  
    66.                 }  
    67.             }else  
    68.                 Log.e("提示信息", "这个设备不是目标蓝牙设备");  
    69.               
    70.         }  
    71.     }  
    72. }  


    工具类ClsUtils.java

    [java] view plain copy
     
    1. package com.ywq.tools;  
    2.   
    3. /************************************ 蓝牙配对函数 * **************/  
    4.   
    5. import java.lang.reflect.Method;    
    6. import java.lang.reflect.Field;    
    7. import android.bluetooth.BluetoothDevice;    
    8. import android.util.Log;    
    9.     
    10. public class ClsUtils     
    11. {    
    12.     /**  
    13.      * 与设备配对 参考源码:platform/packages/apps/Settings.git  
    14.      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java  
    15.      */    
    16.     static public boolean createBond(Class btClass, BluetoothDevice btDevice)    
    17.     throws Exception    
    18.     {    
    19.         Method createBondMethod = btClass.getMethod("createBond");    
    20.         Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);    
    21.         return returnValue.booleanValue();    
    22.     }    
    23.      
    24.     /**  
    25.      * 与设备解除配对 参考源码:platform/packages/apps/Settings.git  
    26.      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java  
    27.      */    
    28.     static public boolean removeBond(Class<?> btClass, BluetoothDevice btDevice)    
    29.             throws Exception    
    30.     {    
    31.         Method removeBondMethod = btClass.getMethod("removeBond");    
    32.         Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);    
    33.         return returnValue.booleanValue();    
    34.     }    
    35.      
    36.     static public boolean setPin(Class<? extends BluetoothDevice> btClass, BluetoothDevice btDevice,    
    37.             String str) throws Exception    
    38.     {    
    39.         try    
    40.         {    
    41.             Method removeBondMethod = btClass.getDeclaredMethod("setPin",    
    42.                     new Class[]    
    43.                     {byte[].class});    
    44.             Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,    
    45.                     new Object[]    
    46.                     {str.getBytes()});    
    47.             Log.e("returnValue", "" + returnValue);    
    48.         }    
    49.         catch (SecurityException e)    
    50.         {    
    51.             // throw new RuntimeException(e.getMessage());    
    52.             e.printStackTrace();    
    53.         }    
    54.         catch (IllegalArgumentException e)    
    55.         {    
    56.             // throw new RuntimeException(e.getMessage());    
    57.             e.printStackTrace();    
    58.         }    
    59.         catch (Exception e)    
    60.         {    
    61.             // TODO Auto-generated catch block    
    62.             e.printStackTrace();    
    63.         }    
    64.         return true;    
    65.      
    66.     }    
    67.      
    68.     // 取消用户输入    
    69.     static public boolean cancelPairingUserInput(Class<?> btClass,    
    70.             BluetoothDevice device)  throws Exception    
    71.     {    
    72.         Method createBondMethod = btClass.getMethod("cancelPairingUserInput");    
    73. //        cancelBondProcess(btClass, device);  
    74.         Boolean returnValue = (Boolean) createBondMethod.invoke(device);    
    75.         return returnValue.booleanValue();    
    76.     }    
    77.      
    78.     // 取消配对    
    79.     static public boolean cancelBondProcess(Class<?> btClass,    
    80.             BluetoothDevice device)    
    81.      
    82.     throws Exception    
    83.     {    
    84.         Method createBondMethod = btClass.getMethod("cancelBondProcess");    
    85.         Boolean returnValue = (Boolean) createBondMethod.invoke(device);    
    86.         return returnValue.booleanValue();    
    87.     }   
    88.       
    89.     //确认配对  
    90.       
    91.     static public void setPairingConfirmation(Class<?> btClass,BluetoothDevice device,boolean isConfirm)throws Exception   
    92.     {  
    93.         Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation",boolean.class);   
    94.         setPairingConfirmation.invoke(device,isConfirm);  
    95.     }  
    96.       
    97.      
    98.     /**  
    99.      *  
    100.      * @param clsShow  
    101.      */    
    102.     static public void printAllInform(Class clsShow)    
    103.     {    
    104.         try    
    105.         {    
    106.             // 取得所有方法    
    107.             Method[] hideMethod = clsShow.getMethods();    
    108.             int i = 0;    
    109.             for (; i < hideMethod.length; i++)    
    110.             {    
    111.                 Log.e("method name", hideMethod[i].getName() + ";and the i is:"    
    112.                         + i);    
    113.             }  
    114.             // 取得所有常量    
    115.             Field[] allFields = clsShow.getFields();    
    116.             for (i = 0; i < allFields.length; i++)    
    117.             {    
    118.                 Log.e("Field name", allFields[i].getName());    
    119.             }  
    120.         }    
    121.         catch (SecurityException e)    
    122.         {    
    123.             // throw new RuntimeException(e.getMessage());    
    124.             e.printStackTrace();    
    125.         }    
    126.         catch (IllegalArgumentException e)    
    127.         {    
    128.             // throw new RuntimeException(e.getMessage());    
    129.             e.printStackTrace();    
    130.         }    
    131.         catch (Exception e)    
    132.         {    
    133.             // TODO Auto-generated catch block    
    134.             e.printStackTrace();    
    135.         }    
    136.     }    
    137. }    


    Androidmanifest.xml

    [html] view plain copy
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     package="com.example.mybuletooth"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0" >  
    6.   
    7.     <uses-sdk  
    8.         android:minSdkVersion="8"  
    9.         android:targetSdkVersion="21" />  
    10.       
    11.     <uses-permission android:name="android.permission.BLUETOOTH"/>  
    12.     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>  
    13.   
    14.     <application  
    15.         android:allowBackup="true"  
    16.         android:icon="@drawable/ic_launcher"  
    17.         android:label="@string/app_name"  
    18.         android:theme="@style/AppTheme" >  
    19.         <activity  
    20.             android:name=".MainActivity"  
    21.             android:label="@string/app_name" >  
    22.             <intent-filter>  
    23.                 <action android:name="android.intent.action.MAIN" />  
    24.   
    25.                 <category android:name="android.intent.category.LAUNCHER" />  
    26.             </intent-filter>  
    27.         </activity>  
    28.           
    29.         <receiver android:name="com.ywq.broadcast.BluetoothReceiver" >  
    30.             <intent-filter android:priority="1000">  
    31.                 <action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/>  
    32.                 <action android:name="android.bluetooth.device.action.FOUND" />  
    33.             </intent-filter>  
    34.         </receiver>  
    35.     </application>  
    36.   
    37. </manifest>  



    布局配置文件activity_main.xml

    [html] view plain copy
     
    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent"  
    5.     android:paddingBottom="@dimen/activity_vertical_margin"  
    6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
    7.     android:paddingRight="@dimen/activity_horizontal_margin"  
    8.     android:paddingTop="@dimen/activity_vertical_margin"  
    9.     tools:context="com.example.mybuletooth.MainActivity" >  
    10.   
    11.     <Button  
    12.         android:id="@+id/button1"  
    13.         android:layout_width="wrap_content"  
    14.         android:layout_height="wrap_content"  
    15.         android:layout_alignParentLeft="true"  
    16.         android:layout_alignParentTop="true"  
    17.         android:layout_marginLeft="54dp"  
    18.         android:layout_marginTop="56dp"  
    19.         android:text="自动配对" />  
    20.   
    21.     <TextView  
    22.         android:id="@+id/textView1"  
    23.         android:layout_width="wrap_content"  
    24.         android:layout_height="wrap_content"  
    25.         android:layout_centerVertical="true"  
    26.         android:text="点击按钮,自动搜索蓝牙设备,并且进行配对" />  
    27.   
    28. </RelativeLayout>  



    针对网上其它帖子中的demo不好使的原因,在此给出一些我的看法,是不是这样不敢保证,至少部分是这些原因吧。。。

    1、出现一个一闪而过的配对框怎么办?

    答:那是因为广播没有停止,须得调用abortBroadcast();将广播停止。

    2、自动配对框还是会弹出来怎么办?

    答:网上好多帖子代码有误,或者没有说清楚。请注意相关配置和工具类中函数的使用。

    这是本人亲测好使的自动配对Demo,仅供参考,希望对大家有所帮助。有问题可以联系我。


     

    重要更新:********************************************************************************


    2016-10-20 ,今天和一个咨询我的小伙伴详细的聊了会儿天。他的问题是,下图所示的if语句块进不去。

    它的btDevice.getBondState( )=12,但是BluetoothDevice.BOND_NONE=10,这不是肯定进不去么。哭

    其中,查阅SDK,可以看到BluetoothDevice的这几个函数和数字的含义是什么。

    参考网址:http://www.cnblogs.com/over140/archive/2010/12/21/1912482.html

    如下所示:

    我一看,天呐,很明显的低级错误。我让他打开设置看看,是否显示已经配对。结果自然是已经配对了。

    产生原因:这个demo在跑之前,他已经在手机-设置-蓝牙中手动把目标蓝牙配对了。那还玩个毛呀大哭

    当手动取消配对后,程序运行正常,log打印和预期一样,自动配对实现。

    提示:

    通过这个小失误,可以看出,评论里好多说这也不行,那也不行的。既然好多人都说好使,那你为什么就不行呢?还是多从自身找问题吧,心思缜密点,避免这种低级失误。大哥,你是程序猿好不好。

                                             

    源码下载地址:https://github.com/chaohuangtianjie994/BlueTooth-AutoPair


    如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,有问题可以进群366533258讨论哈~

  • 相关阅读:
    C语言-结构体内存对齐
    Wireshark-配合tcpdump对Android(安卓)手机抓包
    Python-技巧
    矩阵白化
    非负矩阵分解(3):拉格朗日乘子法求解
    非负矩阵分解(2):算法推导与实现
    非负矩阵分解(1):准则函数及KL散度
    自适应滤波:递归最小二乘
    自适应滤波:最小二乘法
    自适应滤波:奇异值分解SVD
  • 原文地址:https://www.cnblogs.com/weizhxa/p/7825641.html
Copyright © 2020-2023  润新知