Android藍芽自動配對Demo,親測好使!!!

來源:互聯網
上載者:User

標籤:over   _id   tcl   equal   can   tor   ide   example   gif   


藍芽自動配對,即搜尋到其它藍牙裝置之後直接進行配對,不需要彈出配對確認框或者密鑰輸入框。


轉載請註明出處http://blog.csdn.net/qq_25827845/article/details/52400782

 

經過最近一段時間得研究,針對網上給出的案例。總結了一個親測好使的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,當繼續廣播時,action的值為android.bluetooth.device.action.PAIRING_REQUEST即進行配對操作。

5、配對操作藉助工具類ClsUtils.java得到了Android藍芽API中隱藏的方法,實現自動配對,不彈出配對框的功能。



代碼如下:

MainActivity.java

package com.example.mybuletooth;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener{/** Called when the activity is first created. */ private Button autopairbtn=null;private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);autopairbtn=(Button) findViewById(R.id.button1);autopairbtn.setOnClickListener(this);}//設定按鈕的監聽方法@Overridepublic void onClick(View arg0) {if (!bluetoothAdapter.isEnabled()){bluetoothAdapter.enable();//非同步,不會等待結果,直接返回。}else{bluetoothAdapter.startDiscovery(); }}}


BluetoothReceiver.java

package com.ywq.broadcast;import com.ywq.tools.ClsUtils;import android.bluetooth.BluetoothDevice;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class BluetoothReceiver extends BroadcastReceiver{String pin = "1234";  //此處為你要串連的藍牙裝置的初始密鑰,一般為1234或0000public BluetoothReceiver() {}//廣播接收器,當遠程藍牙裝置被發現時,回呼函數onReceiver()會被執行 @Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction(); //得到actionLog.e("action1=", action);BluetoothDevice btDevice=null;  //建立一個藍芽device對象 // 從Intent中擷取裝置對象btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(BluetoothDevice.ACTION_FOUND.equals(action)){  //發現裝置Log.e("發現裝置:", "["+btDevice.getName()+"]"+":"+btDevice.getAddress());if(btDevice.getName().contains("HC-05"))//HC-05裝置如果有多個,第一個搜到的那個會被嘗試。{if (btDevice.getBondState() == BluetoothDevice.BOND_NONE) {  Log.e("ywq", "attemp to bond:"+"["+btDevice.getName()+"]");try {//通過工具類ClsUtils,調用createBond方法ClsUtils.createBond(btDevice.getClass(), btDevice);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}                }}elseLog.e("error", "Is faild");}else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,會等於PAIRING_REQUEST{Log.e("action2=", action);if(btDevice.getName().contains("HC-05")){Log.e("here", "OKOKOK");try {//1.確認配對ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);//2.終止有序廣播Log.i("order...", "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast());abortBroadcast();//如果沒有將廣播終止,則會出現一個一閃而過的配對框。//3.調用setPin方法進行配對...boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, pin);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}elseLog.e("提示資訊", "這個裝置不是目標藍牙裝置");}}}

工具類ClsUtils.java

package com.ywq.tools;/************************************ 藍芽配對函數 * **************/import java.lang.reflect.Method;  import java.lang.reflect.Field;  import android.bluetooth.BluetoothDevice;  import android.util.Log;    public class ClsUtils   {      /**      * 與裝置配對 參考源碼:platform/packages/apps/Settings.git      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java      */      static public boolean createBond(Class btClass, BluetoothDevice btDevice)      throws Exception      {          Method createBondMethod = btClass.getMethod("createBond");          Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);          return returnValue.booleanValue();      }         /**      * 與裝置解除配對 參考源碼:platform/packages/apps/Settings.git      * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java      */      static public boolean removeBond(Class<?> btClass, BluetoothDevice btDevice)              throws Exception      {          Method removeBondMethod = btClass.getMethod("removeBond");          Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);          return returnValue.booleanValue();      }         static public boolean setPin(Class<? extends BluetoothDevice> btClass, BluetoothDevice btDevice,              String str) throws Exception      {          try          {              Method removeBondMethod = btClass.getDeclaredMethod("setPin",                      new Class[]                      {byte[].class});              Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,                      new Object[]                      {str.getBytes()});              Log.e("returnValue", "" + returnValue);          }          catch (SecurityException e)          {              // throw new RuntimeException(e.getMessage());              e.printStackTrace();          }          catch (IllegalArgumentException e)          {              // throw new RuntimeException(e.getMessage());              e.printStackTrace();          }          catch (Exception e)          {              // TODO Auto-generated catch block              e.printStackTrace();          }          return true;         }         // 取消使用者輸入      static public boolean cancelPairingUserInput(Class<?> btClass,              BluetoothDevice device)  throws Exception      {          Method createBondMethod = btClass.getMethod("cancelPairingUserInput");  //        cancelBondProcess(btClass, device);        Boolean returnValue = (Boolean) createBondMethod.invoke(device);          return returnValue.booleanValue();      }         // 解除配對      static public boolean cancelBondProcess(Class<?> btClass,              BluetoothDevice device)         throws Exception      {          Method createBondMethod = btClass.getMethod("cancelBondProcess");          Boolean returnValue = (Boolean) createBondMethod.invoke(device);          return returnValue.booleanValue();      }         //確認配對        static public void setPairingConfirmation(Class<?> btClass,BluetoothDevice device,boolean isConfirm)throws Exception     {    Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation",boolean.class);     setPairingConfirmation.invoke(device,isConfirm);    }           /**      *      * @param clsShow      */      static public void printAllInform(Class clsShow)      {          try          {              // 取得所有方法              Method[] hideMethod = clsShow.getMethods();              int i = 0;              for (; i < hideMethod.length; i++)              {                  Log.e("method name", hideMethod[i].getName() + ";and the i is:"                          + i);              }            // 取得所有常量              Field[] allFields = clsShow.getFields();              for (i = 0; i < allFields.length; i++)              {                  Log.e("Field name", allFields[i].getName());              }        }          catch (SecurityException e)          {              // throw new RuntimeException(e.getMessage());              e.printStackTrace();          }          catch (IllegalArgumentException e)          {              // throw new RuntimeException(e.getMessage());              e.printStackTrace();          }          catch (Exception e)          {              // TODO Auto-generated catch block              e.printStackTrace();          }      }  }  

Androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.mybuletooth"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />        <uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>                <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>    </application></manifest>


布局設定檔activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.mybuletooth.MainActivity" >    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:layout_marginLeft="54dp"        android:layout_marginTop="56dp"        android:text="自動配對" />    <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:text="點擊按鈕,自動搜尋藍牙裝置,並且進行配對" /></RelativeLayout>


針對網上其它文章中的demo不好使的原因,在此給出一些我的看法,是不是這樣不敢保證,至少部分是這些原因吧。。。

1、出現一個一閃而過的配對框怎麼辦?

答:那是因為廣播沒有停止,須得調用abortBroadcast();將廣播停止。

2、自動配對框還是會彈出來怎麼辦?

答:網上好多文章代碼有誤,或者沒有說清楚。請注意Androidmanifest中的相關配置。



這是本人親測好使的自動配對Demo,僅供參考,希望對大家有所協助。有問題可以聯絡我。

附上github上Demo的: https://github.com/chaohuangtianjie994/BlueTooth-AutoPair


 

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


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列印和預期一樣,自動配對實現。

 

 

 

提示:

通過這個小失誤,可以看出,評論裡好多說這也不行,那也不行的。既然好多人都說好使,那你為什麼就不行呢?還是多從自身找問題吧,心思縝密點,避免這種低級失誤。大哥,你是程式猿好不好。

                                         

 





Android藍芽自動配對Demo,親測好使!!!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.