蓝牙从搜索到成功配对的全过程

真是应该值得庆祝一下,为了个毕设,本人真是呕心沥血啊!就在刚才,终于完成了蓝牙成功配对的工作,在此将全过程记录下来,以便日后查阅。

蓝牙通讯的全过程大多资料上都有介绍,无非就是先打开蓝牙、搜索设备、被设备搜索、进行配对,这里我就不在多说啦,将部分代码附上

现在Manifest.xml中添加两个权限:

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

开启本地蓝牙设备:

蓝牙关闭:

上面两步相对来说简单,至于蓝牙搜索问题,我新建了一个activity窗口,用于显示搜索到的蓝牙设备,并在新窗口中实现选中配对过程,首先,说一下设备搜索,

由主窗口调用adapter.startDiscovery();//adapter为本地蓝牙适配器;再调用startActivityForResult (new Intent(MainActivity.this, Device.class),  1);

开启新创建的Device.class。startDiscovery();是异步完成的,每次搜索到一个设备,便会向系统发送一个广播通知,所以这里要新创建一个广播接收对象,用来

接收所发现的设备信息。代码如下

--------------------------------------------------------------------------------------

其中广播接收的信息被保存到str中,再转存到lst_Devices中。

对于搜索过程中,屏幕实时显示,用了一个list_view来实现的,具体如下:

 ListView list_Devices;        //用于显示搜索到的设备参数
 List<String> lst_Devices = new ArrayList<String>();

 final ArrayAdapter<String> adt_Devices;      
 list_Devices = (ListView) this.findViewById(R.id.listview);
 adt_Devices = new ArrayAdapter<String>(this,
   android.R.layout.simple_list_item_1, lst_Devices);
 list_Devices.setAdapter(adt_Devices);

将list_view的数据源锁定到lst_Devices,至于adt_Devices我也不太清楚了,例子上面都是这么写的。

至于设备配对问题,看似简单,可总是抛出service discovery failed异常

后来在网上找到了解决办法,但是为什么这么做,我也不知道,代码如下:

至此蓝牙配对完成,下一步该是通讯了,有待研究,将代码附上,由于此项目尚未完成,所以部分代码还没有写完,此代码只实现了蓝牙搜索配对

package android.app;
import java.util.*;

import android.app.Activity;
import android.bluetooth.*;
import android.content.*;
//import android.net.Uri;
import android.os.*;
import android.view.View;
import android.widget.*;

public class MainActivity extends Activity 
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        final TextView text = (TextView)this.findViewById(R.id.textview);//用一个textview来提示使用者
          
        //获取本地蓝牙适配器
        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        
        if(adapter == null)
            text.setText("本机器没有蓝牙适配器");
        else
        {             
            if(adapter.isEnabled())
                text.setText("蓝牙适配器已开启");
            else
                text.setText("请开启蓝牙适配器");
            //此按钮用于关闭电灯
            Button button_Close = (Button)this.findViewById(R.id.button1);
            button_Close.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                }
            });
            //此按钮用于打开电灯
            Button button_Open = (Button)this.findViewById(R.id.button4);
            button_Open.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                }
            });
            //此按钮用于调节灯光的亮度
            Button button_Up = (Button)this.findViewById(R.id.button2);
            button_Up.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                }
            });
            //此按钮用于调节灯光的暗度
            Button button_Down = (Button)this.findViewById(R.id.button3);
            button_Down.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                }
            });
            //此按钮仅负责打开蓝牙适配器
            Button button_OpenBluetooth = (Button)this.findViewById(R.id.button5);
            button_OpenBluetooth.setOnClickListener(new View.OnClickListener()
            {
                public void onClick(View v) 
                {
                    if(!adapter.isEnabled())
                    {
                        //创建一个intent对象,调用系统信息提示用户打开蓝牙
                        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        //启动系统调用开始启动蓝牙(打开的过程是异步完成的)
                        startActivity(intent);                  
                    }
                    else
                    {
                        text.setText("蓝牙适配器已启动");
                    }
                }
            });
            //此按钮仅负责关闭蓝牙适配器
            Button button_CloseBluetooth = (Button)this.findViewById(R.id.button6);
            button_CloseBluetooth.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                    if(adapter.isEnabled())
                    {
                        //text.setText(adapter.getAddress());
                        adapter.disable();
                        text.setText("蓝牙适配器已关闭");
                    }
                }
            });
            //此按钮负责在已建立的配对中,选择要进行通讯的设备,并建立通讯连接,尚未完成
            Button button_Socket = (Button)this.findViewById(R.id.button7);
            button_Socket.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    // Perform action on click
                    if(adapter.isEnabled())
                    {
                        Set<BluetoothDevice> devices = adapter.getBondedDevices();
                        if(devices.size() > 0)
                        {
                            //利用迭代,将与本机连接的蓝牙设备输出给bluetoothDevice,并且打印其MAX地址
                            for(Iterator iterator = devices.iterator(); iterator.hasNext();)
                            {
                                BluetoothDevice bluetoothDevice = (BluetoothDevice) iterator.next();
                                text.setText(bluetoothDevice.getName());
                            }
                        } 
                        else
                            text.setText("没有已配对的连接,请先配对!");
                    }
                    else
                        text.setText("请先开启蓝牙适配器!");
                }
            });
            //此按钮的最初想法是用于扫描周围设备,并进行配对,已完成搜索并提取地址,配对还未实现
            Button button_Search = (Button)this.findViewById(R.id.button8);
            button_Search.setOnClickListener(new View.OnClickListener() 
            {
                public void onClick(View v) 
                {
                    if(adapter.isEnabled())
                    {
                        if(!adapter.isDiscovering())
                        {
                        // Perform action on click
                            //开启本地蓝牙搜索功能
                            adapter.startDiscovery();
                            //开启Device窗口
                            //startActivity(new Intent(MainActivity.this, Device.class));
                            //启动一个新的窗口用于显示搜索到的设备,并且实现设备配对
                            //上面那个函数用于无参数无返回值的调用新class,下面这个调用时用于有返回值的调用
                            startActivityForResult (new Intent(MainActivity.this, Device.class),  1);

                        }
                        else
                            adapter.cancelDiscovery();
                    }
                    else
                        text.setText("请先开启蓝牙适配器!");
                }
            });       
        }   
    }
    //重写此函数,android平台会自动调用此函数,用于处理新窗口返回的参数
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        String result = data.getExtras().getString("result");//得到新Activity 关闭后返回的数据
    }
}
MainActivity
package android.app;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.webkit.URLUtil;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class Device extends Activity 
{
    String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    BluetoothSocket btSocket;
    String con_Device = new String();//用于存储已配对的设备参数
    ListView list_Devices;                                //用于显示搜索到的设备参数
    List<String> lst_Devices = new ArrayList<String>();     
    int i = 0;
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.device);
        
        final TextView text_device = (TextView)this.findViewById(R.id.text_device); 
        final ArrayAdapter<String> adt_Devices; 
        
        list_Devices = (ListView) this.findViewById(R.id.listview);
        adt_Devices = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, lst_Devices);
        list_Devices.setAdapter(adt_Devices);
        
        //注册一个广播接收器,因为MainActivity启动蓝牙扫描的时候,会异步进行,没检查到一个设备就会发送一个广播,注册的广播接收器用于接收扫描是发出的信号
        IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        BroadcastReceiver mReceiver = new BroadcastReceiver() 
        {
            public void onReceive(Context context, Intent intent) 
            {
                String action = intent.getAction();
                // When discovery finds a device
                if (BluetoothDevice.ACTION_FOUND.equals(action)) 
                {
                    // Get the BluetoothDevice object from the Intent
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    // Add the name and address to an array adapter to show in a ListView
                  
                    String str= device.getName() + "|" +device.getAddress();
                    if (lst_Devices.indexOf(str) == -1)// 防止重复添加
                        lst_Devices.add(str); // 获取设备名称和mac地址
                    adt_Devices.notifyDataSetChanged();
                    
                    System.out.println(device.getName());                
                    
                }
            }
        };
        registerReceiver(mReceiver,intentFilter);
        
        Button button_StopSearch = (Button)this.findViewById(R.id.button_1);
        button_StopSearch.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v) 
            {
                // Perform action on click
                if(!adapter.isDiscovering())
                {
                // Perform action on click
                    adapter.startDiscovery();
                }
                else
                    adapter.cancelDiscovery();
            }
        });
        
        Button button_Return = (Button)this.findViewById(R.id.button_2);
        button_Return.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v) 
            {
                // Perform action on click
                Intent intent = new Intent();//数据是使用Intent返回
                intent.putExtra("result", con_Device);//把选择的数据存放在str_data中,供使用
                Device.this.setResult(RESULT_OK, intent);//设置返回数据
                Device.this.finish();//关闭Activity
            }
        });
        list_Devices.setOnItemClickListener(new Connection_Build());   
    }
    //此类用于实现listview的OnItemClickListener,用于处理选中的设备进行配对,尚未完成
    public class Connection_Build implements OnItemClickListener
    {
        UUID uuid;
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) 
        {
            // TODO Auto-generated method stub
            adapter.cancelDiscovery();
            System.out.println(lst_Devices.get(arg2));
            String str = lst_Devices.get(arg2);
            String[] values = str.split("\|");
            String address=values[1];
            System.out.println(address);
            //Log.e("address",values[1]);
            uuid = UUID.fromString(SPP_UUID);
            BluetoothDevice btDev = adapter.getRemoteDevice(address); 
            BluetoothSocket tmp = null;
            // Get a BluetoothSocket to connect with the given BluetoothDevice  
            try 
            {  
                // MY_UUID is the app's UUID string, also used by the server code  
                Method m = btDev.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                tmp = (BluetoothSocket) m.invoke(btDev, 1); 
            } 
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
            
            btSocket = tmp; 
            try 
            {  
                // Connect the device through the socket. This will block  
                // until it succeeds or throws an exception  
                btSocket.connect();  
            } 
            catch (IOException e) 
            {  
                // Unable to connect; close the socket and get out  
                try 
                {  
                    btSocket.close();  
                    System.out.println("  1" + e);
                } 
                catch (IOException closeException) { }    
            }  
        }    
    }
}
Device
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <AbsoluteLayout
 8         android:id="@+id/AbsoluteLayout1"
 9         android:layout_width="match_parent"
10         android:layout_height="480dp" >
11 
12 
13 
14 
15         <ListView
16             android:id="@+id/listview"
17             android:layout_width="wrap_content"
18             android:layout_height="300dp"
19             android:layout_y="70dp" >
20 "
21             
22         </ListView>
23 
24         <Button
25             android:id="@+id/button_1"
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:layout_x="14dp"
29             android:layout_y="14dp"
30             android:text="停止搜索" />
31 
32         <Button
33             android:id="@+id/button_2"
34             android:layout_width="84dp"
35             android:layout_height="wrap_content"
36             android:layout_x="220dp"
37             android:layout_y="18dp"
38             android:text="返回" />
39 
40         <TextView
41             android:id="@+id/text_device"
42             android:layout_width="match_parent"
43             android:layout_height="107dp"
44             android:layout_y="372dp" 
45             android:text="tiaoshi">
46 
47         </TextView>"
48 
49     </AbsoluteLayout>
50 
51 </LinearLayout>
Device
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:id="@+id/AbsoluteLayout1"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:background="@drawable/myimg" >
 7 
 8     <TextView
 9         android:id="@+id/textview"
10         android:layout_width="289dp"
11         android:layout_height="72dp"
12         android:layout_x="12dp"
13         android:layout_y="18dp"
14         android:gravity="center"
15         android:text="提示信息"
16         android:textSize="20dp"
17         android:textColor="@color/red"/>
18 
19     <Button
20         android:id="@+id/button3"
21         android:layout_width="wrap_content"
22         android:layout_height="wrap_content"
23         android:layout_x="134dp"
24         android:layout_y="276dp"
25         android:text="调暗" />
26 
27     <Button
28         android:id="@+id/button2"
29         android:layout_width="wrap_content"
30         android:layout_height="wrap_content"
31         android:layout_x="136dp"
32         android:layout_y="115dp"
33         android:text="调亮" />
34 
35     <Button
36         android:id="@+id/button1"
37         android:layout_width="wrap_content"
38         android:layout_height="wrap_content"
39         android:layout_x="208dp"
40         android:layout_y="181dp"
41         android:text="关灯" />
42 
43     <Button
44         android:id="@+id/button4"
45         android:layout_width="wrap_content"
46         android:layout_height="wrap_content"
47         android:layout_x="62dp"
48         android:layout_y="184dp"
49         android:text="开灯" />
50 
51     <Button
52         android:id="@+id/button5"
53         android:layout_width="wrap_content"
54         android:layout_height="wrap_content"
55         android:layout_x="28dp"
56         android:layout_y="382dp"
57         android:text="打开蓝牙" />
58 
59     <Button
60         android:id="@+id/button8"
61         android:layout_width="wrap_content"
62         android:layout_height="wrap_content"
63         android:layout_x="121dp"
64         android:layout_y="344dp"
65         android:text="收索设备" />
66 
67     <Button
68         android:id="@+id/button7"
69         android:layout_width="wrap_content"
70         android:layout_height="wrap_content"
71         android:layout_x="120dp"
72         android:layout_y="417dp"
73         android:text="建立通讯" />
74 
75     <Button
76         android:id="@+id/button6"
77         android:layout_width="wrap_content"
78         android:layout_height="wrap_content"
79         android:layout_x="218dp"
80         android:layout_y="380dp"
81         android:text="关闭蓝牙" />
82 
83 </AbsoluteLayout>
84 
85 
86     
main
原文地址:https://www.cnblogs.com/s-hk/p/3437225.html