http://blog.csdn.net/xiang_j2ee/article/details/7041615
我们知道,Android从2.0版本后的sdk开始才支持蓝牙开发,现在一般都不用蓝牙,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发,Demo在国内更是少之又少。技术来源于网络,也要归属于网络,所以此次放置上来供大家共享学习。由于我这里只有一台支持android的手机(google nexus s),但我的电脑是支持蓝牙的,所以就利用电脑和手机进行蓝牙通信,利用电脑测试借助于小工具:串口调试小助手。上网下载。
原理:android的蓝牙通信类似java的socket编程,一端发送,一端接收,发送点相当于服务器,接收端相当于客户端,也就是说,如果有类库可以帮我们产生服务器和客户端的API接口实例,接下来问题就简单很多,就可以通过JavaIO操作实现数据传输。
代码实现必备知识点:
1、要操作蓝牙,先要在AndroidManifest.xml里加入权限,否则不能操作蓝牙。
<uses-permissionandroid:name="android.permission.BLUETOOTH" />
2、认识几个重要的蓝牙操作类
a) BluetoothAdapter(借助此类可以获得本机上的蓝牙设备)
b) BluetoothServerSocket(由名字可以看出,是蓝牙的服务端的操作类)
OK,需要蓝牙通信的重要类就两个,其他的自己去查看相关文档。
3、各种状态通过Handler来动态显示。
4、布局就是一个非常简单的layout.xml文件,一个textedit和一个button。
代码演示:
1、布局文件main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText android:layout_height="wrap_content" android:id="@+id/edtMessage"
android:layout_width="match_parent">
<requestFocus></requestFocus>
</EditText>
<Button android:text="send message" android:id="@+id/btnSend"
android:layout_width="match_parent" android:layout_height="wrap_content"></Button>
</LinearLayout>
2、蓝牙核心代码
package cn.com.leon.bluetooth;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class BusiessBlueToothChat {
private static final String s_Tag = "BusniessBluetooth";
private BluetoothAdapter m_BluetoothAdapter;
private Context m_Context;
private InputStream m_InputStream;
private OutputStream m_OutputStream;
private int m_State;
private int m_StateConnected = 0;
private int m_StateDisConnect = 1;
private boolean m_IsNormalClose = false;
private Message m_Message = new Message();
private PortListenThread m_PortListenThread;
private OnPortListener m_OnPortListener;
private Handler m_Handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Toast.makeText(m_Context, "蓝牙设备不存在或被关闭,打开后重新启动服务",
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
private static final String S_NAME = "BluetoothChat";
private static final UUID S_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
public interface OnPortListener {
public abstract void OnReceiverData(String p_Message);
}
public BusiessBlueToothChat(Context p_context) {
m_Context = p_context;
m_Message.what = 1;
m_OnPortListener = (OnPortListener) p_context;
}
public void CreatePortListen() {
try {
// 获得一个本机蓝牙设备
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 判断是否不存在蓝牙设备或没有打开
if (m_BluetoothAdapter != null || m_BluetoothAdapter.isEnabled()) {
// 已开启蓝牙,创建一个无线射频通信(RFCOMM)蓝牙端口
BluetoothServerSocket _BluetoothServerSocket = m_BluetoothAdapter
.listenUsingRfcommWithServiceRecord(S_NAME, S_UUID);
if (m_PortListenThread == null) {
// 启动端口监听线程
m_PortListenThread = new PortListenThread(
_BluetoothServerSocket);
m_PortListenThread.start();
}
} else {
m_Handler.sendMessage(m_Message);
}
} catch (Exception e) {
Log.i(s_Tag, e.getMessage());
CreatePortListen();
}
}
public class PortListenThread extends Thread {
private BluetoothServerSocket m_BluetoothServerSocket;
BluetoothSocket _BluetoothSocket;
public PortListenThread(BluetoothServerSocket p_BluetoothServerSocket) {
// 初始化Socket
m_BluetoothServerSocket = p_BluetoothServerSocket;
}
@Override
public void run() {
try {
// 调用accept接收对方数据请求
BluetoothSocket _BluetoothSocket = m_BluetoothServerSocket
.accept();
// 获得输出流
m_OutputStream = _BluetoothSocket.getOutputStream();
// 修改连接状态,表示已连接
m_State = m_StateConnected;
// 建立一个长连接持续接收对方数据
while (m_State == m_StateConnected) {
// 获得输入流
m_InputStream = _BluetoothSocket.getInputStream();
ReceiverData();
}
} catch (Exception e) {
Log.i(s_Tag, e.getMessage());
if (!m_BluetoothAdapter.isEnabled()) {
m_Handler.sendMessage(m_Message);
}
}
}
public void Close() {
try {
m_BluetoothServerSocket.close();
if (_BluetoothSocket != null) {
_BluetoothSocket.close();
}
if (m_OutputStream != null) {
m_OutputStream.close();
}
if (m_InputStream != null) {
m_InputStream.close();
}
} catch (Exception e) {
Log.i(s_Tag, e.getMessage());
}
}
}
public void ReceiverData() {
try {
/*
// 初始化字节数组
byte[] _Byte = new byte[8];
// 读取前8个字节获取数据长度
m_InputStream.read(_Byte);
// 将字节转换为String字符
String _Msg = new String(_Byte);
// 将String字符转换为int数字
int _Length = Integer.parseInt(_Msg);
// 按得到的长度再初始化一个字节数组
_Byte = new byte[_Length];
// 继续读取剩余的数据
m_InputStream.read(_Byte);
// 将两次数据合并为一个完整的数据
_Msg += new String(_Byte);
*/
byte[] _Byte = new byte[1024];
int len = 0;
int t_temp = 0;
while((t_temp=m_InputStream.read())!=-1){
_Byte[len++]=(byte)t_temp;
}
String _Msg = new String(_Byte,0,_Byte.length);
// 调用回调函数,返回到界面处理
m_OnPortListener.OnReceiverData(_Msg);
} catch (Exception e) {
Log.i(s_Tag, e.getMessage());
if (!m_IsNormalClose) {
Close(false);
CreatePortListen();
}
}
}
public void SendData(String p_Data) {
try {
// 调用输出流向对方发送数据
m_OutputStream.write(p_Data.getBytes());
} catch (Exception e) {
Log.i(s_Tag, e.getMessage());
}
}
public void Close(boolean p_IsNormalClose) {
m_IsNormalClose = p_IsNormalClose;
m_State = m_StateDisConnect;
if (m_PortListenThread != null) {
m_PortListenThread.Close();
m_PortListenThread = null;
}
}
}
3、MainActivity.java,入口代码
package cn.com.leon.bluetooth;
import cn.com.leon.bluetooth.BusiessBlueToothChat.OnPortListener;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener, OnPortListener {
private BusiessBlueToothChat m_BusiessBlueToothChat;
EditText _edtMessage;
Button _btnSend;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
InitView();
InitListener();
m_BusiessBlueToothChat = new BusiessBlueToothChat(this);
m_BusiessBlueToothChat.CreatePortListen();
}
private void InitView(){
_edtMessage = (EditText) this.findViewById(R.id.edtMessage);
_btnSend = (Button) this.findViewById(R.id.btnSend);
}
private void InitListener(){
_btnSend.setOnClickListener(this);
}
@Override
public void onClick(View v){
switch (v.getId()) {
case R.id.btnSend:
m_BusiessBlueToothChat.SendData(_edtMessage.getText().toString());
break;
default:
break;
}
}
@Override
public void OnReceiverData(String p_Message) {
Log.i("BusinessBluetooth", "接收到的数据:"+p_Message);
}
}
4、注册mianfest.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.com.leon.bluetooth"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<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>
</application>
<uses-permission android:name="android.permission.BLUETOOTH"/>
</manifest>
完成。