標籤: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,親測好使!!!