Android蓝牙通信开发实例演示

< 上一页Android蓝牙开发 WIFI是什么下一页 >
在上一节《Android蓝牙(Bluetooth)连接与通讯》教程中我们已经了解如何探测并开启手机的蓝牙功能、蓝牙服务搜索和建立蓝牙连接。下面我们编写实例 BluetoothDemo。

实例 BluetoothDemo 演示了使用蓝牙功能对其他蓝牙设备进行搜寻、连接并进行数据传输的过程。该应用程序的运行效果如图 1 所示。

实例BluetoothDemo的运行效果
图 1  实例 BluetoothDemo 的运行效果

该视图整体使用 LinearLayout 布局,使用 ListView 显示聊天内容,下方的横向 LinearLayout 布局中放置了一个用于输入文本的 EditText 和一个按钮。对应的布局文件 main.xml 的内容如下:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:myapp="http://schemas.android.com/apk/res/android.BluetoothChat"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:background="@drawable/bg01">
  8.  
  9. <ListView
  10. android:id="@+id/in"
  11. android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:stackFromBottom="true"
  14. android:transcriptMode="alwaysScroll"
  15. android:layout_weight="1"/>
  16.  
  17. <LinearLayout
  18. android:layout_width="match_parent"
  19. android:layout_height="wrap_parent"
  20. android:orientation="horizontal" >
  21.  
  22. <EditText
  23. android:id="@+id/edit_text_out"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_weight="1"
  27. android:layout_gravity="bottom"/>
  28. <ListView
  29. android:id="@+id/button_send"
  30. android:layout_width="wrap_content"
  31. android:layout_height="wrap_content"
  32. android:text="@string/send" />
  33. </LinearLayout>
  34. </LinearLayout>
实例 BluetoothDemo 的 AndroidManifest.xml 文件的内容如下:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  4. package="introduction.android.BluetoothChat"
  5. android:versionCode="1"
  6. android:versionName="1.0">
  7.  
  8. <uses-sdk android:minSdkVersion="14" />
  9.  
  10. <uses-permission android:name="android.permission.BLUE TOOTH_ADMIN">
  11. <uses-permission android:name="android.permission.BLUETOOTH" />
  12.  
  13. <application
  14. android:icon="@drawable/app_icon"
  15. android:label="@string/app_name">
  16.  
  17. <activity
  18. android:name=".BluetoothChat"
  19. android:configChanges="orientation\keyboardHidden"
  20. android:label="@string/app_name">
  21. <intent-filter>
  22. <action android:name="android.in tent.action.MAIN" />
  23. <category android:name="android.intent.category.LAUNCHER" />
  24. </intent-filter>
  25. </activity>
  26.  
  27. <activity
  28. android:name=".DeviceList"
  29. android:configChanges="orientation\keyboardHidden"
  30. android:label="@string/select_device"
  31. android:theme="@android:style/Theme.Dialog" />
  32. </application>
  33. </manifest>
实例 BluetoothDemo 的主 Activity 为 BluetoothChat,其对应的文件内容如下:
  1. package introduction.android.mydbdemo;
  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.Bundle;
  8. import android.os.Handler;
  9. import android.os.Message;
  10. import android.view.KeyEvent;
  11. import android.view.Menu;
  12. import android.view.MenuInflater;
  13. import android.view.MenuItem;
  14. import android.view.View;
  15. import android.view.View.OnClickListener;
  16. import android.view.Window;
  17. import android.view.inputmethod.EditorInfo;
  18. import android.widget.ArrayAdapter;
  19. import android.widget.Button;
  20. import android.widget.EditText;
  21. import android.widget.ListView;
  22. import android.widget.TextView;
  23. import android.widget.Toast;
  24.  
  25. public class BluetoothChat extends Activity {
  26.  
  27. public static final int MESSAGE_STATE_CHANGE = 1;
  28. public static final int MESSAGE_READ = 2;
  29. public static final int MESSAGE_WRITE = 3;
  30. public static final int MESSAGE_DEVICE_NAME = 4;
  31. public static final int MESSAGE_TOAST = 5;
  32. public static final String DEVICE_NAME = "device_name";
  33. public static final String TOAST = "toast";
  34. private static final int REQUEST_C0NNECT_DEVICE = 1;
  35. private static final int REQUEST_ENABLE_BT = 2;
  36. private TextView mTitle;
  37. private ListView mConversationView;
  38. private EditText mOutEditText;
  39. private Button mSendButton;
  40. private String mConnectedDeviceName = null;
  41. private ArrayAdapter<String> mConversationArrayAdapter;
  42. private StringBuffer mOutStringBuffer;
  43. private BluetoothAdapter mBluetoothAdapter = null;
  44. private ChatService mChatService = null;
  45.  
  46. @Override
  47. public void onCreate(Bundle savedInstanceState) {
  48. super.onCreate(savedInstanceState);
  49.  
  50. //设置窗口布局为自定义标题
  51. requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
  52. setContentView(R.layout.main);
  53.  
  54. //设置窗口标题为布局文件
  55. getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
  56. mTitle = (TextView) findViewById(R.id.title_left_text);
  57. mTitle.setText(R.string.app_name);
  58. mTitle = (TextView) findViewById(R.id.title_right_text);
  59.  
  60. // 得到本地蓝牙适配器
  61. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  62.  
  63. //若当前设备不支持蓝牙功能
  64. if (mBluetoothAdapter == null) {
  65. Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_LONG).show();
  66. finish();
  67. return;
  68. }
  69. }
  70.  
  71. @Override
  72. public void onStart() {
  73. super.onStart();
  74. if (!mBluetoothAdapter.isEnabled()) {
  75. Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  76. startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
  77. } else {
  78. if (mChatService == null)
  79. setupChat();
  80. }
  81. }
  82.  
  83. @Override
  84. public synchronized void onResume() {
  85. super.onResume();
  86. if (mChatService != null) {
  87. if (mChatService.getState() == ChatService.STATE_NONE) {
  88. mChatService.start();
  89. }
  90. }
  91. }
  92.  
  93. private void setupChat() {
  94. mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
  95. mConversationView = (ListView) findViewById(R.id.in);
  96. mConversationView.setAdapter(mConversationArrayAdapter);
  97. mOutEditText = (EditText) findViewById(R.id.edit_text_out);
  98. mOutEditText.setOnEditorActionListener(mWriteListener);
  99. mSendButton = (Button) findViewById(R.id.button_send);
  100. mSendButton.setOnClickListener(new OnClickListener() {
  101. public void onClick(View v) {
  102. TextView view = (TextView) findViewById(R.id.edit_text_out);
  103. String message = view.getText().toString();
  104. sendMessage(message);
  105. }
  106. });
  107.  
  108. mChatService = new ChatService(this, mHandler);
  109. mOutStringBuffer = new StringBuffer("");
  110. }
  111.  
  112. @Override
  113. public synchronized void onPause() {
  114. super.onPause();
  115. }
  116.  
  117. @Override
  118. public void onStop() {
  119. super.onStop();
  120. }
  121.  
  122. @Override
  123. public void onDestroy() {
  124. super.onDestroy();
  125. if (mChatService != null)
  126. mChatService.stop();
  127. }
  128.  
  129. private void ensureDiscoverable() {
  130. if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
  131. Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  132. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  133. startActivity(discoverableIntent);
  134. }
  135. }
  136.  
  137. private void sendMessage(String message) {
  138. if (mChatService.getState() != ChatService.STATE_CONNECTED) {
  139. Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
  140. return;
  141. }
  142.  
  143. if (message.length() > 0) {
  144. byte[] send = message.getBytes();
  145. mChatService.write(send);
  146. mOutStringBuffer.setLength(0);
  147. mOutEditText.setText(mOutStringBuffer);
  148. }
  149. }
  150.  
  151. private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {
  152.  
  153. public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
  154. if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
  155. String message = view.getText().toString();
  156. sendMessage(message);
  157. }
  158. return true;
  159. }
  160. };
  161.  
  162. private final Handler mHandler = new Handler() {
  163. @Override
  164. public void handleMessage(Message msg) {
  165. switch (msg.what) {
  166. case MESSAGE_STATE_CHANGE:
  167.  
  168. switch (msg.argl) {
  169. case ChatService.STATE_CONNECTED:
  170. mTitle.setText(R.string.title_connected_to);
  171. mTitle.append(mConnectedDeviceName);
  172. mConversationArrayAdapter.clear();
  173. break;
  174. case ChatService.STATE_CONNECTING:
  175. mTitle.setText(R.string.title_connecting);
  176. break;
  177. case ChatService.STATE_LISTEN:
  178. case ChatService.STATE_NONE:
  179. mTitle.setText(R.string.title_not_connected);
  180. break;
  181. }
  182. break;
  183.  
  184. case MESSAGE_WRITE:
  185. byte[] writeBuf = (byte[]) msg.obj;
  186. String writeMessage = new String(writeBuf);
  187. mConversationArrayAdapter.add("我: " + writeMessage);
  188. break;
  189.  
  190. case MESSAGE_READ:
  191. byte[] readBuf = (byte[]) msg.obj;
  192. String readMessage = new String(readBuf, 0, msg.argl);
  193. mConversationArrayAdapter.add(mConnectedDeviceName + ":" + readMessage);
  194. break;
  195.  
  196. case MESSAGE_DEVICE_NAME:
  197. mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
  198. Toast.makeText(getApplicationContext(), "链接到" + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
  199. break;
  200. case MESSAGE_TOAST:
  201. Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
  202. break;
  203. }
  204. }
  205. };
  206.  
  207. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  208.  
  209. switch (requestCode) {
  210. case REQUEST_CONNECT_DEVICE:
  211. if (resultCode == Activity.RESULT_OK) {
  212. String address = data.getExtras().getString(DeviceList.EXTRA_DEVICE_ADDRESS);
  213. BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
  214. mChatService.connect(device);
  215. }
  216. break;
  217. case REQUEST_ENABLE_BT:
  218. if (resultCode == Activity.RESULT_OK) {
  219. setupChat();
  220. } else {
  221. Toast.makeText(this, R.string.bt_not_enabled_leaving,
  222. Toast.LENGTH_SHORT).show();
  223. finish();
  224. }
  225. }
  226.  
  227. }
  228.  
  229. @Override
  230. public boolean onCreateOptionsMenu(Menu menu) {
  231. MenuInflater inflater = getMenuInflater();
  232. inflater.inflate(R.menu.option_menu, menu);
  233. return true;
  234. }
  235.  
  236. @Override
  237. public boolean onOptionsItemSelected(MenuItem item) {
  238. switch (item.getItemId()) {
  239. case R.id.scan:
  240. Intent serverIntent = new Intent(this, DeviceList.class);
  241. startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  242. return true;
  243. case R.id.discoverable:
  244. ensureDiscoverable();
  245. return true;
  246. case R.id.back:
  247. finish();
  248. System.exit(0);
  249. return true;
  250. }
  251. return false;
  252. }
  253. }
Activity BluetoothChat 的 onCreate() 方法检查当前设备是否支持蓝牙功能,并得到本地的 BluetoothAdapter 设备。

在 onStart() 中检查是否启用了蓝牙功能,若未启用,则请求启用,然后通过 setupChat() 方法对界面中的控件进行初始化、增加单击监听器等,BluetoothChat 创建了 ChatService 对象,该对象在整个应用过程中存在,并完成了蓝牙连接的建立、消息发送与接收等功能。

ChatService.java 的代码如下:
  1. package introduction.android.BluetoothChat;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. import java.util.UUID;
  7.  
  8. import android.bluetooth.BluetoothAdapter;
  9. import android.bluetooth.BluetoothDevice;
  10. import android.bluetooth.BluetoothServerSocket;
  11. import android.bluetooth.BluetoothSocket;
  12. import android.content.Context;
  13. import android.os.Bundle;
  14. import android.os.Handler;
  15. import android.os.Message;
  16.  
  17. import introduction.android.mydbdemo.BluetoothChat;
  18.  
  19. public class ChatService {
  20.  
  21. private static final String NAME = "BluetoothChat";
  22. // UUID-->通用唯一识别码,能唯一辨识资讯
  23. private static final UUID MY_UUID = UUID
  24. .fromString("fa87c0d0-afac-llde-8a39-0800200c9a66");
  25. private final BluetoothAdapter mAdapter;
  26. private final Handler mHandler;
  27. private AcceptThread mAcceptThread;
  28. private ConnectThread mConnectThread;
  29. private ConnectedThread mConnectedThread;
  30.  
  31. private int mState;
  32. public static final int STATE_NONE = 0;
  33. public static final int STATE_LISTEN = 1;
  34. public static final int STATE_CONNECTING = 2;
  35. public static final int STATE_CONNECTED = 3;
  36.  
  37. public ChatService(Context context, Handler handler) {
  38. mAdapter = BluetoothAdapter.getDefaultAdapter();
  39. mState = STATE_NONE;
  40. mHandler = handler;
  41. }
  42.  
  43. private synchronized void setState(int state) {
  44. mState = state;
  45. mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
  46. }
  47.  
  48. public synchronized int getState() {
  49. return mState;
  50. }
  51.  
  52. public synchronized void start() {
  53.  
  54. if (mConnectThread != null) {
  55. mConnectThread.cancel();
  56. mConnectThread = null;
  57. }
  58. if (mConnectedThread != null) {
  59. mConnectedThread.cancel();
  60. mConnectedThread = null;
  61. }
  62. if (mAcceptThread == null) {
  63. mAcceptThread = new AcceptThread();
  64. mAcceptThread.start();
  65. }
  66. setState(STATE_LISTEN);
  67. }
  68.  
  69. //取消CONNECTING和CONNECTED状态下的相关线程,然后运行新的mConnectThread线程
  70. public synchronized void connect(BluetoothDevice device) {
  71. if (mState == STATE_CONNECTING) {
  72. if (mConnectThread != null) {
  73. mConnectThread.cancel();
  74. mConnectThread = null;
  75. }
  76. }
  77. if (mConnectedThread != null) {
  78. mConnectedThread.cancel();
  79. mConnectedThread = null;
  80. }
  81. mConnectThread = new ConnectThread(device);
  82. mConnectThread.start();
  83. setState(STATE_CONNECTING);
  84. }
  85.  
  86. //开启一个ConnectedThread来管理对应的当前连接。之前先取消任意现存的mConnectThread、
  87. //mConnectedThread 、mAcceptThread 线程,然后开启新 mConnectedThread ,传入当前刚刚接受的
  88. //socket连接
  89. //最后通过Handler来通知UI连接
  90. public synchronized void connected(BluetoothSocket socket,
  91. BluetoothDevice device) {
  92.  
  93. if (mConnectThread != null) {
  94. mConnectThread.cancel();
  95. mConnectThread = null;
  96. }
  97.  
  98. if (mConnectedThread != null) {
  99. mConnectedThread.cancel();
  100. mConnectedThread = null;
  101. }
  102.  
  103. if (mAcceptThread != null) {
  104. mAcceptThread.cancel();
  105. mAcceptThread = null;
  106. }
  107. mConnectedThread = new ConnectedThread(socket);
  108. mConnectedThread.start();
  109. Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
  110. Bundle bundle = new Bundle();
  111. bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());
  112. msg.setData(bundle);
  113. mHandler.sendMessage(msg);
  114. setState(STATE_CONNECTED);
  115. }
  116.  
  117. //停止所有相关线程,设当前状态为NONE
  118. public synchronized void stop() {
  119. if (mConnectThread != null) {
  120. mConnectThread.cancel();
  121. mConnectThread = null;
  122. }
  123.  
  124. if (mConnectedThread != null) {
  125. mConnectedThread.cancel();
  126. mConnectedThread = null;
  127. }
  128.  
  129. if (mAcceptThread != null) {
  130. mAcceptThread.cancel();
  131. setState(STATE_NONE);
  132. }
  133. }
  134.  
  135. //在 STATE_CONNECTED 状态下,调用 mConnectedThread 里的 write 方法,写入 byte
  136. public void write(byte[] out) {
  137. ConnectedThread r;
  138.  
  139. synchronized (this) {
  140. if (mState != STATE_CONNECTED)
  141. return;
  142. r = mConnectedThread;
  143. }
  144. r.write(out);
  145. }
  146.  
  147. //连接失败的时候处理,通知ui ,并设为STATE一LISTEN状态
  148. private void connectionFailed() {
  149. setState(STATE_LISTEN);
  150. Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
  151. Bundle bundle = new Bundle();
  152. bundle.putString(BluetoothChat.TOAST, "链接不到设备");
  153. msg.setData(bundle);
  154. mHandler.sendMessage(msg);
  155. }
  156.  
  157. //当连接失去的时候,设为STATE_LISTEN状态并通知UI
  158. private void connectionLost() {
  159. setState(STATE_LISTEN);
  160. Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
  161. Bundle bundle = new Bundle();
  162. bundle.putString(BluetoothChat.TOAST, "设备链接中断");
  163. msg.setData(bundle);
  164. mHandler.sendMessage(msg);
  165. }
  166.  
  167. //创建监听线程,准备接受新连接。使用阻塞方式调用BluetoothServerSocket.accept()
  168. private class AcceptThread extends Thread {
  169. private final BluetoothServerSocket mmServerSocket;
  170.  
  171. public AcceptThread() {
  172. BluetoothServerSocket tmp = null;
  173. try {
  174. tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
  175. } catch (IOException e) {
  176.  
  177. }
  178. mmServerSocket = tmp;
  179. }
  180.  
  181. public void run() {
  182. setName("AcceptThread");
  183. BluetoothSocket socket = null;
  184. while (mState != STATE_CONNECTED) {
  185. try {
  186. socket = mmServerSocket.accept();
  187. } catch (IOException e) {
  188. break;
  189. }
  190. if (socket != null) {
  191. synchronized (ChatService.this) {
  192. switch (mState) {
  193. case STATE_LISTEN:
  194. case STATE_CONNECTING:
  195. connected(socket, socket.getRemoteDevice());
  196. break;
  197. case STATE_NONE:
  198. case STATE_CONNECTED:
  199. try {
  200. socket.close();
  201. } catch (IOException e) {
  202. }
  203. break;
  204. }
  205. }
  206. }
  207. }
  208. }
  209.  
  210. public void cancel() {
  211. try {
  212. mmServerSocket.close();
  213. } catch (IOException e) {
  214. }
  215. }
  216. }
  217.  
  218. // 连接进程,专门用来对外发出连接对方蓝牙的请求并进行处理
  219. // 构造函数里,通过BluetoothDevice.createRfcommSocketToServiceRecord(),
  220. // 从待连接的device产生BluetoothSocket.然后在run方法中connect ,
  221. // 成功后调用BluetoothChatSevice的connected() 方法。定义cancel()再关闭线程时能关闭相关Socket
  222. private class ConnectThread extends Thread {
  223. private final BluetoothSocket mmSocket;
  224. private final BluetoothDevice mmDevice;
  225.  
  226. public ConnectThread(BluetoothDevice device) {
  227. mmDevice = device;
  228. BluetoothSocket tmp = null;
  229. try {
  230. tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
  231. } catch (IOException e) {
  232.  
  233. }
  234. mmSocket = tmp;
  235. }
  236.  
  237. public void run() {
  238. setName("ConnectThread");
  239. mAdapter.cancelDiscovery();
  240. try {
  241. mmSocket.connect();
  242. } catch (IOException e) {
  243. connectionFailed();
  244. try {
  245. mmSocket.close();
  246. } catch (IOException e2) {
  247.  
  248. }
  249. ChatService.this.start();
  250. return;
  251. synchronized (ChatService.this) {
  252. mConnectThread = null;
  253. }
  254. connected(mmSocket, mmDevice);
  255. }
  256. }
  257.  
  258. public void cancel() {
  259. try {
  260. mmSocket.close();
  261. } catch (IOException e) {
  262. }
  263. }
  264. }
  265.  
  266. // 双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流
  267. // Run方法中使用阻塞模式的Inputstream.read()循环读取输入流,
  268. // 然后post到UI线程中更新聊天信息。也提供了write()将聊天信息写入输出流传输至对方,传输成功后回写入UI线程,最后cancle()关闭连接的socket
  269. private class ConnectedThread extends Thread {
  270. private final BluetoothSocket mmSocket;
  271. private final InputStream mmInStream;
  272. private final OutputStream mmOutStream;
  273.  
  274. public ConnectedThread(BluetoothSocket socket) {
  275. mmSocket = socket;
  276. InputStream tmpIn = null;
  277. OutputStream tmpOut = null;
  278. try {
  279. tmpIn = socket.getInputStream();
  280. tmpOut = socket.getOutputStream();
  281. } catch (IOException e) {
  282.  
  283. }
  284. mmInStream = tmpIn;
  285. mmOutStream = tmpOut;
  286. }
  287.  
  288. public void run() {
  289. byte[] buffer = new byte[1024];
  290. int bytes;
  291. while (true) {
  292. try {
  293. bytes = mmInStream.read(buffer);
  294. mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes,
  295. -1, buffer).sendToTarget();
  296. } catch (IOException e) {
  297. connectionLost();
  298. break;
  299. }
  300. }
  301. }
  302.  
  303. public void write(byte[] buffer) {
  304. try {
  305. mmOutStream.write(buffer);
  306. mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
  307. } catch (IOException e) {
  308. }
  309. }
  310. }
  311.  
  312. public void cancel() {
  313. try {
  314. mmSocket.close();
  315. } catch (IOException e) {
  316.  
  317. }
  318. }
  319. }

DeviceList 用于显示蓝牙设备列表,并返回蓝牙设备信息。DeviceList.java 的代码如下:
  1. package introduction.android.BluetoothChat;
  2.  
  3. import java.util.Set;
  4.  
  5. import android.app.Activity;
  6. import android.bluetooth.BluetoothAdapter;
  7. import android.bluetooth.BluetoothDevice;
  8. import android.content.BroadcastReceiver;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.IntentFilter;
  12. import android.os.Bundle;
  13. import android.view.View;
  14. import android.view.Window;
  15. import android.view.View.OnClickListener;
  16. import android.widget.AdapterView;
  17. import android.widget.ArrayAdapter;
  18. import android.widget.Button;
  19. import android.widget.ListView;
  20. import android.widget.TextView;
  21. import android.widget.AdapterView.OnItemClickListener;
  22.  
  23. import introduction.android.mydbdemo.R;
  24.  
  25. public class DeviceList extends Activity {
  26. public static String EXTRA_DEVICE_ADDRESS = "device_address";
  27. private BluetoothAdapter mBtAdapter;
  28. private ArrayAdapter<String> mPairedDevicesArrayAdapter;
  29. private ArrayAdapter<String> mNewDevicesArrayAdapter;
  30.  
  31. @Override
  32. protected void onCreate(Bundle savedInstanceState) {
  33. super.onCreate(savedInstanceState);
  34. requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
  35. setContentView(R.layout.device_list);
  36. setResult(Activity.RESULT_CANCELED);
  37.  
  38. Button scanButton = (Button) findViewById(R.id.button_scan);
  39. scanButton.setOnClickListener(new OnClickListener() {
  40. public void onClick(View v) {
  41. doDiscovery();
  42. v.setVisibility(View.GONE);
  43. }
  44. });
  45. mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
  46. mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
  47.  
  48. ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
  49. pairedListView.setAdapter(mPairedDevicesArrayAdapter);
  50. pairedListView.setOnItemClickListener(mDeviceClickListener);
  51.  
  52. ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
  53. newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
  54. newDevicesListView.setOnItemClickListener(mDeviceClickListener);
  55.  
  56. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  57. this.registerReceiver(mReceiver, filter);
  58.  
  59. filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  60. this.registerReceiver(mReceiver, filter);
  61.  
  62. mBtAdapter = BluetoothAdapter.getDefaultAdapter();
  63. Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
  64. if (pairedDevices.size() > 0) {
  65. findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
  66. for (BluetoothDevice device : pairedDevices) {
  67. mPairedDevicesArrayAdapter.add(device.getName() + "\n"
  68. + device.getAddress());
  69. }
  70. } else {
  71. String noDevices = getResources().getText(R.string.none_paired)
  72. .toString();
  73. mPairedDevicesArrayAdapter.add(noDevices);
  74. }
  75. }
  76.  
  77. @Override
  78. protected void onDestroy() {
  79. super.onDestroy();
  80. if (mBtAdapter != null) {
  81. mBtAdapter.cancelDiscovery();
  82. }
  83. this.unregisterReceiver(mReceiver);
  84. }
  85.  
  86. private void doDiscovery() {
  87. setProgressBarIndeterminateVisibility(true);
  88. setTitle(R.string.scanning);
  89. findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
  90. if (mBtAdapter.isDiscovering()) {
  91. mBtAdapter.cancelDiscovery();
  92. }
  93. mBtAdapter.startDiscovery();
  94. }
  95.  
  96. private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
  97. public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
  98. mBtAdapter.cancelDiscovery();
  99.  
  100. String info = ((TextView) v).getText().toString();
  101. String address = info.substring(info.length() - 17);
  102. Intent intent = new Intent();
  103. intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
  104. setResult(Activity.RESULT_OK, intent);
  105. finish();
  106. }
  107. };
  108.  
  109. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  110. @Override
  111. public void onReceive(Context context, Intent intent) {
  112. String action = intent.getAction();
  113. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  114. BluetoothDevice device = intent
  115. .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  116. if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
  117. mNewDevicesArrayAdapter.add(device.getName() + "\n"
  118. + device.getAddress());
  119. }
  120. } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
  121. setProgressBarIndeterminateVisibility(false);
  122. setTitle(R.string.select_device);
  123. if (mNewDevicesArrayAdapter.getCount() == 0) {
  124. String noDevices = getResources().getText(
  125. R.string.none_found).toString();
  126. mNewDevicesArrayAdapter.add(noDevices);
  127. }
  128. }
  129. }
  130. };
  131. }
< 上一页Android蓝牙开发 WIFI是什么下一页 >