首先我们先说一下,在android操作系统中可对蓝牙做得工作。
对蓝牙的操作分两种,一种是系统操作,一种是应用操作。
系统可对蓝牙做所有外部操作,包括开启,关闭,设置可见性,扫描周围设备,匹配及取消等等;应用可以对蓝牙做以上大部分操作,除了匹配操作不能在应用中使用代码完成。换句话说,如果您的应用程序中使用到蓝牙,则要保证使用前,手动在android操作系统中完成目标机之间的匹配工作。
接下来说一下,介绍一下两部android手机,使用蓝牙通信的过程。
两部手机通过蓝牙通信,则一定要其中一台是服务器端,另一台是客户端。蓝牙设备在本地叫BluetoothAdapter,本地获取到的其他蓝牙设备叫BluetoothDevice。下面分别介绍在服务器端和客户端上程序的操作过程。为方便理解两者分开介绍,但在具体实现过程中有些代码可以融合。具体代码可下载http://download.csdn.net/detail/eric41050808/6614225,参阅。
在服务器端,注意如下几点:
1.一定要保证通信双方已经手动完成匹配;
2.服务端要开启可见性,以便客户端搜索到;
3.使用BluetoothServerSocket的方法listenUsingRfcommWithServiceRecord()获取ServerSocket对象,再使用ServerSocket的accept()方法阻塞接收请求者的连接请求,成功后该方法返回BluetoothSocket对象;
4.使用获取到的socket对象的输入输出流方法操作数据通信,接收到的数据一定要通过handler处理显示。
在客户端,注意如下几点:
1.同样,一定要保证蓝牙开启,且通信双方已经手动完成匹配;
2.通过广播扫描周围可用设备,并确定该设备已与本机完成匹配;
3.使用上步扫描到的device对象,调用createRfcommSocketToServiceRecord()方法,获取BluetoothSocket对象,并用该对象调用connect()方法想服务器提出连接请求。注意此连接请求过程要循环请求,直至完成连接。
对蓝牙的操作分两种,一种是系统操作,一种是应用操作。
系统可对蓝牙做所有外部操作,包括开启,关闭,设置可见性,扫描周围设备,匹配及取消等等;应用可以对蓝牙做以上大部分操作,除了匹配操作不能在应用中使用代码完成。换句话说,如果您的应用程序中使用到蓝牙,则要保证使用前,手动在android操作系统中完成目标机之间的匹配工作。
接下来说一下,介绍一下两部android手机,使用蓝牙通信的过程。
两部手机通过蓝牙通信,则一定要其中一台是服务器端,另一台是客户端。蓝牙设备在本地叫BluetoothAdapter,本地获取到的其他蓝牙设备叫BluetoothDevice。下面分别介绍在服务器端和客户端上程序的操作过程。为方便理解两者分开介绍,但在具体实现过程中有些代码可以融合。具体代码可下载http://download.csdn.net/detail/eric41050808/6614225,参阅。
在服务器端,注意如下几点:
1.一定要保证通信双方已经手动完成匹配;
2.服务端要开启可见性,以便客户端搜索到;
3.使用BluetoothServerSocket的方法listenUsingRfcommWithServiceRecord()获取ServerSocket对象,再使用ServerSocket的accept()方法阻塞接收请求者的连接请求,成功后该方法返回BluetoothSocket对象;
4.使用获取到的socket对象的输入输出流方法操作数据通信,接收到的数据一定要通过handler处理显示。
在客户端,注意如下几点:
1.同样,一定要保证蓝牙开启,且通信双方已经手动完成匹配;
2.通过广播扫描周围可用设备,并确定该设备已与本机完成匹配;
3.使用上步扫描到的device对象,调用createRfcommSocketToServiceRecord()方法,获取BluetoothSocket对象,并用该对象调用connect()方法想服务器提出连接请求。注意此连接请求过程要循环请求,直至完成连接。
4.使用此连接的socket对象的输入输出流方法操作数据通信,接收到的数据一定要通过handler处理显示。
程序界面:
文件名Bluetooth_MainActivity.java:
- package thu.wolf.bluetooth;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.UUID;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.bluetooth.BluetoothServerSocket;
- 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.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
- public class Bluetooth_MainActivity extends Activity {
- private Button conn = null;
- private Button server = null;
- private Button client = null;
- private Button send = null;
- private EditText msg = null;
- private BluetoothRev bluetoothRev = null;
- private BluetoothAdapter adapter = null;
- private BluetoothDevice device = null;
- private static final String S_NAME = "BluetoothChat";
- private static final UUID S_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
- private InputStream m_InputStream = null;
- private OutputStream m_OutputStream = null;
- private String address = null;
- boolean serverflag ;
- private String TAG = "catch";
- private static final String MESSAGE_READ = "Message_Read";
- private ArrayList<String> blueToothNames = null;
- private ArrayList<BluetoothDevice> blutToothDevices = null;
- private HandlerThread handlerThread = null;
- private MyHandler transHandler = null;
- boolean isfound = false;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_bluetooth__main);
- conn = (Button)findViewById(R.id.conn);
- server = (Button)findViewById(R.id.server);
- client = (Button)findViewById(R.id.client);
- // client.setEnabled(false);
- send = (Button)findViewById(R.id.send);
- msg = (EditText)findViewById(R.id.msg);
- conn.setOnClickListener(new connOnClickListener());
- server.setOnClickListener(new serverOnClickListener());
- client.setOnClickListener(new clientOnClickListener());
- send.setOnClickListener(new sendOnClickListener());
- blueToothNames = new ArrayList<String>();
- blutToothDevices = new ArrayList<BluetoothDevice>();
- //获取一个蓝牙适配器
- adapter = BluetoothAdapter.getDefaultAdapter();
- if( adapter != null)//判断是否为空
- {
- System.out.println("本机拥有蓝牙设备。");
- if(!adapter.isEnabled())//判断当前蓝牙设备是否可用
- {
- Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//创建一个Intent对象,用于启动一个activity,来提示用户开启蓝牙
- startActivity(intent);//开启一个activity提醒有应用要开启蓝牙
- }
- else
- Toast.makeText(this, "蓝牙已开启,可以启动服务", 50).show();
- }
- else
- System.out.println("没有蓝牙设备!");
- //生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供
- handlerThread = new HandlerThread("handler_thread");
- //在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();
- handlerThread.start();//只能在主线程中开启此线程
- transHandler = new MyHandler(handlerThread.getLooper());
- }
- class MyHandler extends Handler {
- public MyHandler() {
- }
- public MyHandler(Looper L) {
- super(L);
- }
- // 子类必须重写此方法,接受数据
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- Log.d("MyHandler", "handleMessage......");
- super.handleMessage(msg);
- // 此处可以更新UI
- byte[] buffer = new byte[1024];
- buffer = (byte[])msg.obj;
- String str = new String(buffer, 0, msg.arg1);
- System.out.println(str);
- }
- }
- class serverOnClickListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- serverflag = true;
- Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 350);
- startActivity(intent);
- client.setEnabled(false);
- conn.setEnabled(false);
- RequestAcceptThread ServerThread = new RequestAcceptThread();
- ServerThread.start();
- }
- }
- class clientOnClickListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- bluetoothRev = new BluetoothRev();
- //创建intentfilter及广播接收函数
- IntentFilter discoveryfilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
- registerReceiver(bluetoothRev, discoveryfilter);
- IntentFilter foundfilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- registerReceiver(bluetoothRev, foundfilter);
- adapter.startDiscovery();
- msg.setText("正在扫描");
- server.setEnabled(false);
- }
- }
- private class BluetoothRev extends BroadcastReceiver{
- @Override
- public void onReceive(Context context, Intent intent) {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (BluetoothDevice.ACTION_FOUND.equals(action))
- {
- // Get the BluetoothDevice object from the Intent
- //BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- //blutToothDevices.add(device);
- //blueToothNames.add(device.getName());
- isfound = true;
- Toast.makeText(Bluetooth_MainActivity.this, "已获取设备,可连接", 50).show();
- // When discovery is finished, change the Activity title
- }
- else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
- {
- if(isfound == false)
- msg.setText("未发现设备,重新搜索");//此action只表示发现结束,可以是发现了设备,也可以是没有发现到设备
- else
- {
- msg.setText("发现设备");
- }
- adapter.cancelDiscovery();
- Bluetooth_MainActivity.this.unregisterReceiver(this);
- }
- }
- }
- //获取bluetoothAdapter适配器
- class connOnClickListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- RequestThread ClientThread = new RequestThread( device );
- ClientThread.start();
- }
- }
- class sendOnClickListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- String data = "hello world!";
- try {
- m_OutputStream.write(data.getBytes());
- System.out.println(data);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println("数据发送失败!");
- }
- System.out.println("数据已发出");
- }
- }
- /*作为服务端应答socket请求,得到socket */
- public class RequestAcceptThread extends Thread{
- private BluetoothServerSocket m_BluetoothServersocket = null;
- public RequestAcceptThread(){
- BluetoothServerSocket tmpBluetoothServersocket = null;
- try{
- tmpBluetoothServersocket = adapter.listenUsingRfcommWithServiceRecord(S_NAME, S_UUID);
- }catch(IOException e){}
- m_BluetoothServersocket = tmpBluetoothServersocket;
- System.out.println("服务已开启");
- msg.setText("服务已开启");
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- super.run();
- //阻塞监听直到异常出现或者有socket返回
- BluetoothSocket socket = null;
- while(true)
- {
- try{
- //System.out.println("waiting。。。。");
- //msg.setText("等待请求");
- socket = m_BluetoothServersocket.accept();
- if(socket != null) break;
- }catch(IOException e){
- System.out.println("exception while waiting");
- break;
- }
- }
- System.out.println("接收到请求!");
- if(socket != null){
- System.out.println("连接已建立");
- ConnectedThread readthread = new ConnectedThread(socket);
- readthread.start();
- }
- }
- //取消socket监听,关闭线程
- public void cancel(){
- try{
- m_BluetoothServersocket.close();
- }catch(IOException e){}
- }
- }
- private class RequestThread extends Thread {
- private BluetoothSocket mmSocket = null;
- private BluetoothDevice mmDevice = null;
- public RequestThread(BluetoothDevice device) {
- // Use a temporary object that is later assigned to mmSocket,
- // because mmSocket is final
- BluetoothSocket tmp = null;
- //mmDevice = device;
- msg.setText("开始申请连接");
- // Get a BluetoothSocket to connect with the given BluetoothDevice
- try {
- // MY_UUID is the app's UUID string, also used by the server code
- //System.out.println("ask for connection");
- tmp = device.createRfcommSocketToServiceRecord(S_UUID);
- } catch (IOException e) { }
- if( tmp != null){
- mmSocket = tmp;
- Toast.makeText(Bluetooth_MainActivity.this, "socket is ok!", 100);
- }
- }
- public void run() {
- // Cancel discovery because it will slow down the connection
- while(true){//必须多次连接以保证成功连接
- try {
- // Connect the device through the socket. This will block
- // until it succeeds or throws an exception
- System.out.println("try to connection");
- mmSocket.connect();
- if(mmSocket != null)
- {
- //mSocketManage(mmSocket);
- ConnectedThread readthread = new ConnectedThread(mmSocket);
- readthread.start();
- break;
- }
- } catch (IOException connectException) {
- // Unable to connect; close the socket and get out
- System.out.println("unable to connection");
- try {
- mmSocket.close();
- } catch (IOException closeException) { }
- return;
- }
- }
- System.out.println("连接成功,可发送数据");
- }
- /** Will cancel an in-progress connection, and close the socket */
- public void cancel() {
- try {
- mmSocket.close();
- } catch (IOException e) { }
- }
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.bluetooth__main, menu);
- return true;
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- unregisterReceiver(bluetoothRev);
- super.onDestroy();
- }
- //
- private class ConnectedThread extends Thread {
- private final BluetoothSocket mmSocket;
- Message msg = transHandler.obtainMessage();
- public ConnectedThread(BluetoothSocket socket) {
- mmSocket = socket;
- InputStream tmpIn = null;
- OutputStream tmpOut = null;
- // Get the input and output streams, using temp objects because
- // member streams are final
- try {
- tmpIn = socket.getInputStream();
- tmpOut = socket.getOutputStream();
- } catch (IOException e) { }
- m_InputStream = tmpIn;
- m_OutputStream= tmpOut;
- }
- public void run() {
- byte[] buffer = new byte[1024]; // buffer store for the stream
- int bytes; // bytes returned from read()
- // Keep listening to the InputStream until an exception occurs
- while (true)
- {
- try {
- // Read from the InputStream
- bytes = m_InputStream.read(buffer);
- msg.obj = buffer;
- msg.arg1 = bytes;
- transHandler.sendMessage(msg);
- // Send the obtained bytes to the UI Activity
- //transHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
- } catch (IOException e) {
- break;
- }
- }
- }
- /* Call this from the main Activity to send data to the remote device */
- public void write(byte[] bytes) {
- try {
- //mmOutStream.write(bytes);
- m_OutputStream.write(bytes);
- } catch (IOException e) { }
- }
- /* Call this from the main Activity to shutdown the connection */
- public void cancel() {
- try {
- mmSocket.close();
- } catch (IOException e) { }
- }
- }
- }