公司项目涉及蓝牙通信,所以就简单的学了学,下面是自己参考了一些资料后的总结,希望对大家有帮助。
以下是开发中的几个关键步骤:
1,首先开启蓝牙
2,搜索可用设备
3,创建蓝牙socket,获取输入输出流
4,读取和写入数据
5,断开连接关闭蓝牙
下面是一个demo
效果图:
SearchDeviceActivity.java
package com.hello.project; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import android.app.Activity; 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.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; public class SearchDeviceActivity extends Activity implements OnItemClickListener{ private BluetoothAdapter blueadapter=null; private DeviceReceiver mydevice=new DeviceReceiver(); private List<String> deviceList=new ArrayList<String>(); private ListView deviceListview; private Button btserch; private ArrayAdapter<String> adapter; private boolean hasregister=false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.finddevice); setView(); setBluetooth(); } private void setView(){ deviceListview=(ListView)findViewById(R.id.devicelist); adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, deviceList); deviceListview.setAdapter(adapter); deviceListview.setOnItemClickListener(this); btserch=(Button)findViewById(R.id.start_seach); btserch.setOnClickListener(new ClinckMonitor()); } @Override protected void onStart() { //注册蓝牙接收广播 if(!hasregister){ hasregister=true; IntentFilter filterStart=new IntentFilter(BluetoothDevice.ACTION_FOUND); IntentFilter filterEnd=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(mydevice, filterStart); registerReceiver(mydevice, filterEnd); } super.onStart(); } @Override protected void onDestroy() { if(blueadapter!=null&&blueadapter.isDiscovering()){ blueadapter.cancelDiscovery(); } if(hasregister){ hasregister=false; unregisterReceiver(mydevice); } super.onDestroy(); } /** * Setting Up Bluetooth */ private void setBluetooth(){ blueadapter=BluetoothAdapter.getDefaultAdapter(); if(blueadapter!=null){ //Device support Bluetooth //确认开启蓝牙 if(!blueadapter.isEnabled()){ //请求用户开启 Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, RESULT_FIRST_USER); //使蓝牙设备可见,方便配对 Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200); startActivity(in); //直接开启,不经过提示 blueadapter.enable(); } } else{ //Device does not support Bluetooth AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("No bluetooth devices"); dialog.setMessage("Your equipment does not support bluetooth, please change device"); dialog.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show(); } } /** * Finding Devices */ private void findAvalibleDevice(){ //获取可配对蓝牙设备 Set<BluetoothDevice> device=blueadapter.getBondedDevices(); if(blueadapter!=null&&blueadapter.isDiscovering()){ deviceList.clear(); adapter.notifyDataSetChanged(); } if(device.size()>0){ //存在已经配对过的蓝牙设备 for(Iterator<BluetoothDevice> it=device.iterator();it.hasNext();){ BluetoothDevice btd=it.next(); deviceList.add(btd.getName()+'\n'+btd.getAddress()); adapter.notifyDataSetChanged(); } }else{ //不存在已经配对过的蓝牙设备 deviceList.add("No can be matched to use bluetooth"); adapter.notifyDataSetChanged(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(resultCode){ case RESULT_OK: findAvalibleDevice(); break; case RESULT_CANCELED: break; } super.onActivityResult(requestCode, resultCode, data); } private class ClinckMonitor implements OnClickListener{ @Override public void onClick(View v) { if(blueadapter.isDiscovering()){ blueadapter.cancelDiscovery(); btserch.setText("repeat search"); }else{ findAvalibleDevice(); blueadapter.startDiscovery(); btserch.setText("stop search"); } } } /** * 蓝牙搜索状态广播监听 * @author Andy * */ private class DeviceReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String action =intent.getAction(); if(BluetoothDevice.ACTION_FOUND.equals(action)){ //搜索到新设备 BluetoothDevice btd=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //搜索没有配过对的蓝牙设备 if (btd.getBondState() != BluetoothDevice.BOND_BONDED) { deviceList.add(btd.getName()+'\n'+btd.getAddress()); adapter.notifyDataSetChanged(); } } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ //搜索结束 if (deviceListview.getCount() == 0) { deviceList.add("No can be matched to use bluetooth"); adapter.notifyDataSetChanged(); } btserch.setText("repeat search"); } } } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) { Log.e("msgParent", "Parent= "+arg0); Log.e("msgView", "View= "+arg1); Log.e("msgChildView", "ChildView= "+arg0.getChildAt(pos-arg0.getFirstVisiblePosition())); final String msg = deviceList.get(pos); if(blueadapter!=null&&blueadapter.isDiscovering()){ blueadapter.cancelDiscovery(); btserch.setText("repeat search"); } AlertDialog.Builder dialog = new AlertDialog.Builder(this);// 定义一个弹出框对象 dialog.setTitle("Confirmed connecting device"); dialog.setMessage(msg); dialog.setPositiveButton("connect", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { BluetoothMsg.BlueToothAddress=msg.substring(msg.length()-17); if(BluetoothMsg.lastblueToothAddress!=BluetoothMsg.BlueToothAddress){ BluetoothMsg.lastblueToothAddress=BluetoothMsg.BlueToothAddress; } Intent in=new Intent(SearchDeviceActivity.this,BluetoothActivity.class); startActivity(in); } }); dialog.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { BluetoothMsg.BlueToothAddress = null; } }); dialog.show(); } }
BluetoothMsg.java
package com.hello.project; public class BluetoothMsg { /** * 蓝牙连接类型 * @author Andy * */ public enum ServerOrCilent{ NONE, SERVICE, CILENT }; //蓝牙连接方式 public static ServerOrCilent serviceOrCilent = ServerOrCilent.NONE; //连接蓝牙地址 public static String BlueToothAddress = null,lastblueToothAddress=null; //通信线程是否开启 public static boolean isOpen = false; }
finddevice.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id = "@+id/devices" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom = "true" android:id= "@+id/bt_bottombar"> <Button android:id="@+id/start_seach" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/start_service" android:text="Began to search"/> </RelativeLayout> <ListView android:id="@+id/devicelist" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollingCache="false" android:divider="#ffc6c6c6" android:layout_weight="1.0" android:layout_above = "@id/bt_bottombar" android:layout_below="@id/devices" /> </RelativeLayout>
BluetoothActivity.java
package com.hello.project; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; 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.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class BluetoothActivity extends Activity{ /* 一些常量,代表服务器的名称 */ public static final String PROTOCOL_SCHEME_RFCOMM = "btspp"; private ListView mListView; private Button sendButton; private Button disconnectButton; private EditText editMsgView; private ArrayAdapter<String> mAdapter; private List<String> msgList=new ArrayList<String>(); Context mContext; private BluetoothServerSocket mserverSocket = null; private ServerThread startServerThread = null; private clientThread clientConnectThread = null; private BluetoothSocket socket = null; private BluetoothDevice device = null; private readThread mreadThread = null;; private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.chat); mContext = this; init(); } private void init() { mAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, msgList); mListView = (ListView) findViewById(R.id.list); mListView.setAdapter(mAdapter); mListView.setFastScrollEnabled(true); editMsgView= (EditText)findViewById(R.id.MessageText); editMsgView.clearFocus(); sendButton= (Button)findViewById(R.id.btn_msg_send); sendButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { String msgText =editMsgView.getText().toString(); if (msgText.length()>0) { sendMessageHandle(msgText); editMsgView.setText(""); editMsgView.clearFocus(); //close InputMethodManager InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editMsgView.getWindowToken(), 0); }else Toast.makeText(mContext, "发送内容不能为空!", Toast.LENGTH_SHORT).show(); } }); disconnectButton= (Button)findViewById(R.id.btn_disconnect); disconnectButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub if (BluetoothMsg.serviceOrCilent == BluetoothMsg.ServerOrCilent.CILENT) { shutdownClient(); } else if (BluetoothMsg.serviceOrCilent == BluetoothMsg.ServerOrCilent.SERVICE) { shutdownServer(); } BluetoothMsg.isOpen = false; BluetoothMsg.serviceOrCilent=BluetoothMsg.ServerOrCilent.NONE; Toast.makeText(mContext, "已断开连接!", Toast.LENGTH_SHORT).show(); } }); } private Handler LinkDetectedHandler = new Handler() { @Override public void handleMessage(Message msg) { //Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show(); if(msg.what==1) { msgList.add((String)msg.obj); } else { msgList.add((String)msg.obj); } mAdapter.notifyDataSetChanged(); mListView.setSelection(msgList.size() - 1); } }; @Override protected void onResume() { BluetoothMsg.serviceOrCilent=BluetoothMsg.ServerOrCilent.CILENT; if(BluetoothMsg.isOpen) { Toast.makeText(mContext, "连接已经打开,可以通信。如果要再建立连接,请先断开!", Toast.LENGTH_SHORT).show(); return; } if(BluetoothMsg.serviceOrCilent==BluetoothMsg.ServerOrCilent.CILENT) { String address = BluetoothMsg.BlueToothAddress; if(!address.equals("null")) { device = mBluetoothAdapter.getRemoteDevice(address); clientConnectThread = new clientThread(); clientConnectThread.start(); BluetoothMsg.isOpen = true; } else { Toast.makeText(mContext, "address is null !", Toast.LENGTH_SHORT).show(); } } else if(BluetoothMsg.serviceOrCilent==BluetoothMsg.ServerOrCilent.SERVICE) { startServerThread = new ServerThread(); startServerThread.start(); BluetoothMsg.isOpen = true; } super.onResume(); } //开启客户端 private class clientThread extends Thread { @Override public void run() { try { //创建一个Socket连接:只需要服务器在注册时的UUID号 // socket = device.createRfcommSocketToServiceRecord(BluetoothProtocols.OBEX_OBJECT_PUSH_PROTOCOL_UUID); socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); //连接 Message msg2 = new Message(); msg2.obj = "请稍候,正在连接服务器:"+BluetoothMsg.BlueToothAddress; msg2.what = 0; LinkDetectedHandler.sendMessage(msg2); socket.connect(); Message msg = new Message(); msg.obj = "已经连接上服务端!可以发送信息。"; msg.what = 0; LinkDetectedHandler.sendMessage(msg); //启动接受数据 mreadThread = new readThread(); mreadThread.start(); } catch (IOException e) { Log.e("connect", "", e); Message msg = new Message(); msg.obj = "连接服务端异常!断开连接重新试一试。"; msg.what = 0; LinkDetectedHandler.sendMessage(msg); } } }; //开启服务器 private class ServerThread extends Thread { @Override public void run() { try { /* 创建一个蓝牙服务器 * 参数分别:服务器名称、UUID */ mserverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM, UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); Log.d("server", "wait cilent connect..."); Message msg = new Message(); msg.obj = "请稍候,正在等待客户端的连接..."; msg.what = 0; LinkDetectedHandler.sendMessage(msg); /* 接受客户端的连接请求 */ socket = mserverSocket.accept(); Log.d("server", "accept success !"); Message msg2 = new Message(); String info = "客户端已经连接上!可以发送信息。"; msg2.obj = info; msg.what = 0; LinkDetectedHandler.sendMessage(msg2); //启动接受数据 mreadThread = new readThread(); mreadThread.start(); } catch (IOException e) { e.printStackTrace(); } } }; /* 停止服务器 */ private void shutdownServer() { new Thread() { @Override public void run() { if(startServerThread != null) { startServerThread.interrupt(); startServerThread = null; } if(mreadThread != null) { mreadThread.interrupt(); mreadThread = null; } try { if(socket != null) { socket.close(); socket = null; } if (mserverSocket != null) { mserverSocket.close();/* 关闭服务器 */ mserverSocket = null; } } catch (IOException e) { Log.e("server", "mserverSocket.close()", e); } }; }.start(); } /* 停止客户端连接 */ private void shutdownClient() { new Thread() { @Override public void run() { if(clientConnectThread!=null) { clientConnectThread.interrupt(); clientConnectThread= null; } if(mreadThread != null) { mreadThread.interrupt(); mreadThread = null; } if (socket != null) { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } socket = null; } }; }.start(); } //发送数据 private void sendMessageHandle(String msg) { if (socket == null) { Toast.makeText(mContext, "没有连接", Toast.LENGTH_SHORT).show(); return; } try { OutputStream os = socket.getOutputStream(); os.write(msg.getBytes()); } catch (IOException e) { e.printStackTrace(); } msgList.add(msg); mAdapter.notifyDataSetChanged(); mListView.setSelection(msgList.size() - 1); } //读取数据 private class readThread extends Thread { @Override public void run() { byte[] buffer = new byte[1024]; int bytes; InputStream mmInStream = null; try { mmInStream = socket.getInputStream(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while (true) { try { // Read from the InputStream if( (bytes = mmInStream.read(buffer)) > 0 ) { byte[] buf_data = new byte[bytes]; for(int i=0; i<bytes; i++) { buf_data[i] = buffer[i]; } String s = new String(buf_data); Message msg = new Message(); msg.obj = s; msg.what = 1; LinkDetectedHandler.sendMessage(msg); } } catch (IOException e) { try { mmInStream.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } break; } } } } @Override protected void onDestroy() { super.onDestroy(); if (BluetoothMsg.serviceOrCilent == BluetoothMsg.ServerOrCilent.CILENT) { shutdownClient(); } else if (BluetoothMsg.serviceOrCilent == BluetoothMsg.ServerOrCilent.SERVICE) { shutdownServer(); } BluetoothMsg.isOpen = false; BluetoothMsg.serviceOrCilent = BluetoothMsg.ServerOrCilent.NONE; } }
chat.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id = "@+id/container" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id= "@+id/edit_bottombar" android:layout_alignParentBottom = "true"> <Button android:id="@+id/btn_disconnect" android:layout_width="65dp" android:layout_height="wrap_content" android:layout_alignParentLeft ="true" android:text="断开"/> <Button android:id="@+id/btn_msg_send" android:layout_width="65dp" android:layout_height="wrap_content" android:layout_alignParentRight ="true" android:text="发送"/> <EditText android:layout_width="fill_parent" android:layout_height = "wrap_content" android:layout_toLeftOf="@id/btn_msg_send" android:layout_toRightOf="@+id/btn_disconnect" android:hint = "说点什么呢?" android:textSize="15dip" android:id = "@+id/MessageText"/> </RelativeLayout> <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollingCache="false" android:divider="#ffc6c6c6" android:layout_weight="1.0" android:layout_above = "@id/edit_bottombar" android:layout_below="@id/container" /> </RelativeLayout>
最后别忘了加入权限
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.READ_CONTACTS"/>