为了账号安全,请及时绑定邮箱和手机立即绑定

蓝牙自动配对demo讲解

标签:
Android

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


源码下载地址:http://www.apkbus.com/thread-306762-1-1.html

 

经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的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打印和预期一样,自动配对实现。

       

原文链接:http://www.apkbus.com/blog-822415-68511.html

点击查看更多内容
3人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消