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


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


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

     

    源码下载地址:http://download.csdn.net/download/qq_25827845/9757403

    经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的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

    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

    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

    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

    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

    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://download.csdn.net/download/qq_25827845/9757403


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

  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6514751.html
Copyright © 2020-2023  润新知