基于蓝牙的安卓客户端开发

努力尽今夕,少年犹可夸。这篇文章主要讲述基于蓝牙的安卓客户端开发相关的知识,希望能为你提供帮助。
一.安卓蓝牙开发基本流程

  • 获取本地蓝牙适配器,打开蓝牙,获得已配对蓝牙设备列表
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
mBtAdapter.enable();  
Set< BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
  • 扫描未配对设备,通过广播(BluetoothDevice.ACTION_FOUND)接收列表出未配对的设备
mBtAdapter.startDiscovery();
  • 从列表设备选择某个蓝牙进行连接,获得BluetoothDevice 对象
device.getName()
device.getAddress()
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address)
  • 开始连接线程,获得BluetoothSocket
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothSocket bluetoothSocket=  device.createRfcommSocketToServiceRecord(MY_UUID)
  • 开始已连接线程,由BluetoothSocket获得输入输出流从而收发数据
二.权限申明
1 < !--蓝牙权限--> 2< uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 3< uses-permission android:name="android.permission.BLUETOOTH" />

三.布局文件
1 < ?xml version="1.0" encoding="utf-8"?> 2 < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3xmlns:tools="http://schemas.android.com/tools" 4android:id="@+id/activity_main" 5android:layout_width="match_parent" 6android:layout_height="match_parent" 7android:orientation="vertical" 8> 9< !--标题栏--> 10< LinearLayout 11android:layout_width="match_parent" 12android:layout_height="wrap_content" 13android:background="#CDC9C9"> 14< TextView 15android:id="@+id/DeviceTextView" 16android:layout_width="wrap_content" 17android:layout_weight="1" 18android:layout_height="wrap_content" 19android:text="设备:" 20android:textColor="#FFFFFF" 21android:textSize="20dp" 22/> 23< TextView 24android:id="@+id/StateTextView" 25android:layout_width="wrap_content" 26android:layout_weight="1" 27android:layout_height="wrap_content" 28android:text="状态:" 29android:textColor="#FFFFFF" 30android:textSize="20dp" 31/> 32< /LinearLayout> 33< !--聊天界面--> 34< LinearLayout 35android:id="@+id/chatPage" 36android:layout_width="match_parent" 37android:layout_height="wrap_content" 38android:orientation="vertical" 39android:visibility="gone" 40android:layout_marginLeft="10dp" 41android:layout_marginRight="10dp" 42> 43< LinearLayout 44android:layout_width="match_parent" 45android:layout_height="wrap_content" 46 47> 48< EditText 49android:id="@+id/MessageEditText" 50android:layout_marginTop="5dp" 51android:layout_width="wrap_content" 52android:layout_weight="1" 53android:layout_height="40dp" 54/> 55< Button 56android:id="@+id/SendButton" 57android:layout_width="wrap_content" 58android:layout_height="wrap_content" 59android:layout_marginTop="4dp" 60android:textAllCaps="false" 61android:text="Send" 62/> 63< /LinearLayout> 64< LinearLayout 65android:layout_width="match_parent" 66android:layout_height="wrap_content"> 67< TextView 68android:id="@+id/DisplayTextView" 69android:layout_width="match_parent" 70android:layout_height="wrap_content" 71android:hint="DisplayTextView"/> 72< /LinearLayout> 73 74< /LinearLayout> 75< !--控制界面--> 76< LinearLayout 77android:id="@+id/controlPage" 78android:layout_width="match_parent" 79android:layout_height="match_parent" 80android:orientation="vertical" 81android:visibility="visible"> 82< /LinearLayout> 83< !--数据中心--> 84< LinearLayout 85android:id="@+id/displayPage" 86android:layout_width="match_parent" 87android:layout_height="match_parent" 88android:orientation="vertical" 89android:visibility="gone"> 90< /LinearLayout> 91 < /LinearLayout>

【基于蓝牙的安卓客户端开发】 
四.具体代码实现
  • MainActivity
1 package com.example.john.esdc; 2 3 import android.app.Activity; 4 import android.bluetooth.BluetoothAdapter; 5 import android.bluetooth.BluetoothDevice; 6 import android.content.Intent; 7 import android.os.Handler; 8 import android.os.Message; 9 import android.support.v7.app.AppCompatActivity; 10 import android.os.Bundle; 11 import android.view.Menu; 12 import android.view.MenuItem; 13 import android.view.View; 14 import android.widget.Button; 15 import android.widget.EditText; 16 import android.widget.TextView; 17 import android.widget.Toast; 18 19 public class MainActivity extends AppCompatActivity { 20 21// Intent request codes 22private static final int REQUEST_CONNECT_DEVICE = 1; 23// Local Bluetooth adapter 24private BluetoothAdapter mBluetoothAdapter = null; 25// Member object for the chat services 26private BluetoothChatService mChatService = null; 27// Message types sent from the BluetoothChatService Handler 28public static final int MESSAGE_STATE_CHANGE = 1; 29public static final int MESSAGE_READ = 2; 30public static final int MESSAGE_WRITE = 3; 31public static final int MESSAGE_DEVICE_NAME = 4; 32public static final int MESSAGE_TOAST = 5; 33// Key names received from the BluetoothChatService Handler 34public static final String DEVICE_NAME = "device_name"; 35public static final String TOAST = "toast"; 36// Name of the connected device 37private String mConnectedDeviceName = null; 38//控件 39TextView deviceTextView; 40TextView stateTextView; 41EditText messageEditText; 42Button sendButton; 43TextView displayTextView; 44private int numofMessage=0; //显示的消息数 45//界面 46View controlPage; 47View displayPage; 48View chatPage; 49 50 51@Override 52protected void onCreate(Bundle savedInstanceState) { 53super.onCreate(savedInstanceState); 54setContentView(R.layout.activity_main); 55getWidget(); 56// Initialize the BluetoothChatService to perform bluetooth connections 57mChatService = new BluetoothChatService(this, mHandler); 58// Get local Bluetooth adapter 59mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 60sendButton.setOnClickListener(new View.OnClickListener() { 61@Override 62public void onClick(View v) { 63String message = messageEditText.getText().toString(); 64sendMessage(message); 65} 66}); 67} 68//获取控件对象 69private void getWidget(){ 70deviceTextView = (TextView)findViewById(R.id.DeviceTextView); 71stateTextView = (TextView)findViewById(R.id.StateTextView); 72messageEditText = (EditText)findViewById(R.id.MessageEditText); 73sendButton = (Button)findViewById(R.id.SendButton); 74displayTextView = (TextView)findViewById(R.id.DisplayTextView); 75 76chatPage = (View)findViewById(R.id.chatPage); 77controlPage = (View)findViewById(R.id.controlPage); 78displayPage = (View)findViewById(R.id.displayPage); 79} 80//发送一条消息 81private void sendMessage(String message){ 82if (mChatService.getState()!=BluetoothChatService.STATE_CONNECTED){ 83Toast.makeText(this, "未连接蓝牙设备", Toast.LENGTH_SHORT).show(); 84return; 85} 86if (message.length()> 0){ 87byte[] send = message.getBytes(); 88mChatService.write(send); 89messageEditText.setText(""); 90} 91} 92//********************************************************************************* 93//建立菜单 94@Override 95public boolean onCreateOptionsMenu(Menu menu) { 96getMenuInflater().inflate(R.menu.option_menu,menu); 97return true; 98} 99//菜单响应事件,主要完成界面切换 100@Override 101public boolean onOptionsItemSelected(MenuItem item) { 102switch (item.getItemId()){ 103case R.id.scan://点击“Scan”项,执行DeviceListActivity,在onActivityResult中返回用户点击连接的蓝牙MAC地址 104Intent serverIntent = new Intent(this,DeviceListActivity.class); 105startActivityForResult(serverIntent,REQUEST_CONNECT_DEVICE); 106return true; 107case R.id.chatPage: 108chatPage.setVisibility(View.VISIBLE); 109displayPage.setVisibility(View.GONE); 110controlPage.setVisibility(View.GONE); 111return true; 112case R.id.displayPage: 113chatPage.setVisibility(View.GONE); 114displayPage.setVisibility(View.VISIBLE); 115controlPage.setVisibility(View.GONE); 116return true; 117case R.id.controlPage: 118chatPage.setVisibility(View.GONE); 119displayPage.setVisibility(View.GONE); 120controlPage.setVisibility(View.VISIBLE); 121return true; 122} 123return false; 124} 125//********************************************************************************************** 126//获得DeviceList活动反馈回的蓝牙设备地址,获取BluetoothDevice,开始连接 127@Override 128protected void onActivityResult(int requestCode, int resultCode, Intent data) { 129switch (requestCode){ 130case REQUEST_CONNECT_DEVICE: 131//获取蓝牙地址并执行连接 132if(resultCode== Activity.RESULT_OK){ 133String address = data.getExtras() 134.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); 135BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 136mChatService.connect(device); 137 138} 139} 140} 141//********************************************************************************************** 142//主要负责更新UI 143private final Handler mHandler = new Handler(){ 144@Override 145public void handleMessage(Message msg) { 146 147switch (msg.what){ 148case MESSAGE_STATE_CHANGE: 149switch (msg.arg1){ 150case BluetoothChatService.STATE_CONNECTED: 151stateTextView.setText("状态:已连接"); 152break; 153case BluetoothChatService.STATE_CONNECTING: 154stateTextView.setText("状态:正连接"); 155break; 156case BluetoothChatService.STATE_NONE: 157stateTextView.setText("状态:未连接"); 158break; 159} 160break; 161case MESSAGE_TOAST: 162Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), 163Toast.LENGTH_SHORT).show(); 164break; 165case MESSAGE_DEVICE_NAME: 166mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); 167deviceTextView.setText("设备:"+mConnectedDeviceName); 168Toast.makeText(MainActivity.this, "已连接上"+mConnectedDeviceName, Toast.LENGTH_SHORT).show(); 169break; 170case MESSAGE_READ: 171if (chatPage.getVisibility() == View.VISIBLE){ 172displayTextView.append(mConnectedDeviceName+":"+msg.obj+"\\n"); 173numofMessage++; 174if (numofMessage==10) { 175displayTextView.setText(""); 176numofMessage = 0; 177} 178} 179break; 180case MESSAGE_WRITE: 181byte[] writeBuf = (byte[]) msg.obj; 182String writeMessage = new String(writeBuf); 183if (chatPage.getVisibility() == View.VISIBLE){ 184displayTextView.append("本机:"+writeMessage+"\\n"); 185numofMessage++; 186if (numofMessage==10) { 187displayTextView.setText(""); 188numofMessage = 0; 189} 190} 191break; 192} 193} 194}; 195 }

  • DeviceListActivity
1 package com.example.john.esdc; 2 import android.annotation.SuppressLint; 3 import android.app.Activity; 4 import android.bluetooth.BluetoothAdapter; 5 import android.bluetooth.BluetoothDevice; 6 import android.content.BroadcastReceiver; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.content.IntentFilter; 10 import android.support.v7.app.AppCompatActivity; 11 import android.os.Bundle; 12 import android.view.View; 13 import android.view.Window; 14 import android.widget.AdapterView; 15 import android.widget.ArrayAdapter; 16 import android.widget.ListView; 17 import android.widget.TextView; 18 import android.widget.Toast; 19 20 import java.util.Set; 21 22 import static android.R.attr.filter; 23 @SuppressLint("NewApi") 24 public class DeviceListActivity extends AppCompatActivity { 25 26// Return Intent extra 27public static String EXTRA_DEVICE_ADDRESS = "device_address"; 28 29// Member fields 30private BluetoothAdaptermBtAdapter; 31private ArrayAdapter< String> mPairedDevicesArrayAdapter; 32private ArrayAdapter< String> mNewDevicesArrayAdapter; 33 34@Override 35protected void onCreate(Bundle savedInstanceState) { 36super.onCreate(savedInstanceState); 37setContentView(R.layout.activity_device_list); 38setResult(Activity.RESULT_CANCELED); 39// 获取本地蓝牙适配器 40mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 41mBtAdapter.enable(); //打开蓝牙 42doDiscovery(); //开始搜索蓝牙设备 43 44 45//ListView控件适配器组装 46mPairedDevicesArrayAdapter = new ArrayAdapter< String> (this,android.R.layout.simple_list_item_1); 47mNewDevicesArrayAdapter = new ArrayAdapter< String> (this,android.R.layout.simple_list_item_1); 48ListView pairedListView = (ListView)findViewById(R.id.paired_devices); 49pairedListView.setAdapter(mPairedDevicesArrayAdapter); 50pairedListView.setOnItemClickListener(mDeviceClickListener1); 51ListView newDevicesListView = (ListView)findViewById(R.id.new_devices); 52newDevicesListView.setAdapter(mNewDevicesArrayAdapter); 53newDevicesListView.setOnItemClickListener(mDeviceClickListener2); 54 55//注册广播 56IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 57this.registerReceiver(mReceive,filter); 58filter = new IntentFilter((BluetoothAdapter.ACTION_DISCOVERY_FINISHED)); 59this.registerReceiver(mReceive,filter); 60 61//获得已配对的蓝牙设备 62Set< BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); 63if (pairedDevices.size()> 0) { 64for (BluetoothDevice device : pairedDevices) { 65mPairedDevicesArrayAdapter.add(device.getName() + "\\n" + device.getAddress()); 66} 67} 68else{ 69mPairedDevicesArrayAdapter.add("无已配对设备"); 70} 71 72} 73 74//蓝牙设备列表的点击响应 75private AdapterView.OnItemClickListener mDeviceClickListener1 = new AdapterView.OnItemClickListener() { 76@Override 77public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { 78mBtAdapter.cancelDiscovery(); 79//获取蓝牙设备的MAC地址返回到主活动 80String info = mPairedDevicesArrayAdapter.getItem(position); 81String address = info.substring(info.length()-17); 82Intent intent = new Intent(); 83intent.putExtra(EXTRA_DEVICE_ADDRESS,address); 84setResult(Activity.RESULT_OK,intent); 85finish(); 86 87 88 89} 90}; 91private AdapterView.OnItemClickListener mDeviceClickListener2 = new AdapterView.OnItemClickListener() { 92@Override 93public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { 94mBtAdapter.cancelDiscovery(); 95//获取蓝牙设备的MAC地址返回到主活动 96String info = mNewDevicesArrayAdapter.getItem(position); 97String address = info.substring(info.length()-17); 98//Toast.makeText(DeviceListActivity.this, address, Toast.LENGTH_SHORT).show(); 99Intent intent = new Intent(); 100intent.putExtra(EXTRA_DEVICE_ADDRESS,address); 101setResult(Activity.RESULT_OK,intent); 102finish(); 103 104 105 106} 107}; 108 109private void doDiscovery(){ 110setTitle("扫描中,请稍等……"); 111if (mBtAdapter.isDiscovering()){ 112mBtAdapter.cancelDiscovery(); 113} 114mBtAdapter.startDiscovery(); 115} 116 117 118@Override 119protected void onDestroy() { 120super.onDestroy(); 121// Make sure we\'re not doing discovery anymore 122if (mBtAdapter != null) { 123mBtAdapter.cancelDiscovery(); 124} 125// Unregister broadcast listeners 126this.unregisterReceiver(mReceive); 127} 128//广播监听,当发现新设备时将其添加至列表 129private final BroadcastReceiver mReceive = new BroadcastReceiver() { 130@Override

    推荐阅读