Android Bluetooth编程
Android蓝牙编程需要权限,在AndroidManifest.xml中加入两行代码才可以使用蓝牙(红色部分为加入的)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="3" />
    <!-- 允许使用和管理蓝牙 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        ……
    </application>
</manifest>
 
蓝牙编程操作:
第一步:获得BluetoothAdapter对象
第二步:判断当前设备中是否拥有蓝牙设备
第三步:判断当前设备中的蓝牙设备是否已经打开
第四步:得到所有已经配对的蓝牙设备对象
 
1.BluetoothAdapter 顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它
     BluetoothAdapter里的方法很多,常用的有以下几个:
     cancelDiscovery() 根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索
      disable()关闭蓝牙
      enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:
Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
startActivityForResult(enabler,reCode);  //同startActivity(enabler);
      getAddress() 获取本地蓝牙地址
      getDefaultAdapter() 获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter
      getName() 获取本地蓝牙名称
      getRemoteDevice(String address) 根据蓝牙地址获取远程蓝牙设备
      getState() 获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)
      isDiscovering() 判断当前是否正在查找设备,是返回true
      isEnabled() 判断蓝牙是否打开,已打开返回true,否则,返回false
     listenUsingRfcommWithServiceRecord(String name,UUID uuid) 根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步
      startDiscovery() 开始搜索,这是搜索的第一步
    2.BluetoothDevice(远程的Bluetooth)看名字就知道,这个类描述了一个蓝牙设备
       createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket
        这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket
        这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter    3.BluetoothServerSocket如果去除了Bluetooth相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多,
 这个类一种只有三个方法
 两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!
 还有一点需要注意的是,这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接      close()这个就不用说了吧,翻译一下——关闭!
 
   4.BluetoothSocket,跟BluetoothServerSocket相对,是客户端。一共5个方法,不出意外,都会用到
      close(),关闭
      connect()连接
      getInptuStream()获取输入流
      getOutputStream()获取输出流
      getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备
实例:
这是一个搜索蓝牙设备,用ListView显示出来的实例
<?xml version="1.0" encoding="utf-8" ?> 
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
- <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content">
  <Button android:layout_height="wrap_content" android:text="开启蓝牙" android:onClick="bluetooth" android:id="@+id/btn_openBlutooth" android:layout_width="150dip" /> 
  <Button android:layout_height="wrap_content" android:text="关闭蓝牙" android:onClick="bluetooth" android:id="@+id/btn_closeBlutooth" android:layout_width="150dip" /> 
  </LinearLayout>
  <Button android:layout_height="wrap_content" android:text="扫描远程蓝牙设备" android:onClick="bluetooth" android:id="@+id/btn_smiaoBlutooth" android:layout_width="160dip" /> 
  <ListView android:id="@+id/result_ListView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 
  </LinearLayout>
 
Java代码:
package com.android;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
 
public class BluetoothActivity extends Activity{
 
    private BluetoothAdapter bluetooth;
    List<String> lstDevices = new ArrayList<String>();
    private static final int  REQUEST_DISCOVERABLE_BLUETOOTH = 3;
    private static final String tag = "蓝牙";
    private static final int REQUEST_ENABLE_BT = 0;
    
    //显示搜索到的远程蓝牙设备
    private static ListView listView;
    //保存搜索到的远程蓝牙设备
    private static ArrayAdapter<String> adtDevices;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.bluetooth);
       //获得BluetoothAdapter对象
       bluetooth = BluetoothAdapter.getDefaultAdapter();
       
       // ListView及其数据源 适配器
       listView = (ListView)findViewById(R.id.result_ListView);
       adtDevices = new ArrayAdapter<String>(BluetoothActivity.this, android.R.layout.simple_list_item_1, lstDevices);
       listView.setAdapter(adtDevices);
       //给ListView添加点击事件
       listView.setOnItemClickListener(itemClickListener);
    }
 
    /**
     * 按钮的点击事件
     * @param view
     */
    public void bluetooth(View view) {
       switch (view.getId()) {
       case R.id.btn_openBlutooth:
           //判断是否有Bluetooth设备
           if (bluetooth == null) {
              Toast.makeText(this, "没有检测到蓝牙设备", Toast.LENGTH_LONG).show();
              Log.v(tag , "没有检测到蓝牙设备");
              finish();
              return;
           }
           Log.v(tag , "检测到蓝牙设备!");
 
           //判断当前设备中的蓝牙设备是否已经打开(调用isEnabled()来查询当前蓝牙设备的状态,如果返回为false,则表示蓝牙设备没有开启)
           boolean originalBluetooth = (bluetooth != null && bluetooth.isEnabled());
           if(originalBluetooth){
              Log.v(tag , "蓝牙设备已经开启!");
              setTitle("蓝牙设备已经开启!");
              return;
           }else if (originalBluetooth == false) {
              //打开Bluetooth设备 这个无提示效果
              //bluetooth.enable();
              //也可以这样,这个有提示效果
              Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivity(intent);
           }
           //得到所有蓝牙已经配对的适配器对象(不打开蓝牙也可以得到已经配对的地址)
           Set<BluetoothDevice> btDevice = bluetooth.getBondedDevices();
           if(btDevice.size() > 0){
              for (Iterator iterator = btDevice.iterator(); iterator.hasNext();) {
                  BluetoothDevice bluetoothDevice = (BluetoothDevice) iterator.next();
                  //得到已经配对的远程蓝牙设备的地址
                  System.out.println("远程蓝牙设备的地址:" + bluetoothDevice.getAddress());
                  Log.v(tag, "远程蓝牙设备的地址:" + bluetoothDevice.getAddress());
              }
           }
           
           /*确保蓝牙被发现*/
           Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
           //设置可见状态的持续时间为500秒,但是最多是300秒
           discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 500);
           startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BLUETOOTH);
           break;
       case R.id.btn_closeBlutooth:
           if(bluetooth == null){
              Log.v(tag , "蓝牙没有!");
              setTitle("蓝牙没有!");
              return;
           }else if(bluetooth.isEnabled()){
              //清空搜索的列表
              lstDevices.clear();
              //起到更新的效果
              adtDevices.notifyDataSetChanged();
              //关闭蓝牙
              bluetooth.disable();
              Log.v(tag , "蓝牙已经关闭!");
              setTitle("蓝牙已经关闭!");
           }
           break;
       case R.id.btn_smiaoBlutooth:
           if(bluetooth == null){
              Log.v(tag , "蓝牙没有!");
              setTitle("蓝牙没有!");
              return;
           }else{
              Log.v(tag, "扫描蓝牙设备");
              if (bluetooth.getState() == BluetoothAdapter.STATE_OFF) {// 如果蓝牙还没开启
                  Toast.makeText(BluetoothActivity.this, "请先打开蓝牙", 1000).show();
                  return;
              }
              // 注册Receiver来获取蓝牙设备相关的结果 将action指定为:ACTION_FOUND
              IntentFilter intent = new IntentFilter();
              intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果
              intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
              intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
              intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
              //注册广播接收器
              registerReceiver(searchDevices, intent);
              setTitle("本机蓝牙地址:" + bluetooth.getAddress());
              //防止重复添加的数据
              lstDevices.clear();
              //扫描蓝牙设备 最少要12秒,功耗也非常大(电池等) 是异步扫描意思就是一调用就会扫描
              bluetooth.startDiscovery();
           }
           break;
       default:
           break;
       }
    }
    /**调用startActivityForResult后触发*/
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
       switch (requestCode) {
       case REQUEST_DISCOVERABLE_BLUETOOTH: 
           if (resultCode > 0) {
              
              Toast.makeText(this, "蓝牙已启用", Toast.LENGTH_LONG).show();
              Log.v(tag, "蓝牙已启用,程序运行");
              setTitle("蓝牙已启用,程序运行");
 
           } else {
              Toast.makeText(this, "蓝牙未启用", Toast.LENGTH_LONG).show();
              finish();
              ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);   
              manager.restartPackage(getPackageName()); 
           }
           break;
       }
    }
    /**
     * 广播
     */
    private BroadcastReceiver searchDevices = new BroadcastReceiver() {
       public void onReceive(Context context, Intent intent) {
           String action = intent.getAction();
           Bundle b = intent.getExtras();
           Object[] lstName = b.keySet().toArray();
           // 显示所有收到的消息及其细节
           for (int i = 0; i < lstName.length; i++) {
              String keyName = lstName[i].toString();
              Log.v(tag + "|" + keyName, String.valueOf(b.get(keyName)));
           }
          //搜索远程蓝牙设备时,取得设备的MAC地址
           if (BluetoothDevice.ACTION_FOUND.equals(action)) {
              //代表远程蓝牙适配器的对象取出
              BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
              String str= device.getName() + "|" + device.getAddress();
              if (lstDevices.indexOf(str) == -1){// 防止重复添加
                  lstDevices.add(str); // 获取设备名称和mac地址
                  System.out.println(str);
              }
              //起到更新的效果
              adtDevices.notifyDataSetChanged();
           }
       }
    };
    
    protected void onDestroy() {
       //销毁广播
       this.unregisterReceiver(searchDevices);
       super.onDestroy();
    }
}
 
这是我从项目中copy过来的源码,如有错误可能是copy不完整