Android Bluetooth编程

http://blog.csdn.net/yuejingjiahong/article/details/6630250


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不完整



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值