作者在这里介绍的这个实例是Google SDK中提供的一个蓝牙聊天程序,简单但信息量巨大,非常适合初学者学习蓝牙方面的知识。
在学习这个实例前请读者仔细阅读并理解Socket的工作原理和实现机制,作者的这篇博客中有详细的介绍:
http://blog.csdn.net/dlutbrucezhang/article/details/8577810
在 Android1.x 的时候,相关 API 非常不完善,还不能简单的使用 Bluetooth 开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法 bluetooth 协议栈。在 Android2 以后,框架提供了一些官方 API 来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论 Android2 后的 Bluetooth 通信的 API 使用方法。
首先看聊天室的效果图:


蓝牙设备连接的过程如下图所示:

下面这张图展示的是蓝牙聊天的时序图:

接下来将贴出源码并对源码做出详细的解释说明:
BluetoothChat.java
例程的主 Activity 。 onCreate() 得到本地 BluetoothAdapter 设备,检查是否支持。 onStart() 中检查是否启用蓝牙,并请求启用,然后执行 setupChat() 。 setupChat() 中先对界面中的控件进行初始化增加点击监听器等,然创建 BluetoothChatService 对象,该对象在整个应用过程中存在,并执行蓝牙连接建立、消息发送接受等实际的行为。
-
import android.app.Activity;
-
import android.bluetooth.BluetoothAdapter;
-
import android.bluetooth.BluetoothDevice;
-
import android.content.Intent;
-
import android.os.Bundle;
-
import android.os.Handler;
-
import android.os.Message;
-
import android.util.Log;
-
import android.view.KeyEvent;
-
import android.view.Menu;
-
import android.view.MenuInflater;
-
import android.view.MenuItem;
-
import android.view.View;
-
import android.view.Window;
-
import android.view.View.OnClickListener;
-
import android.view.inputmethod.EditorInfo;
-
import android.widget.ArrayAdapter;
-
import android.widget.Button;
-
import android.widget.EditText;
-
import android.widget.ListView;
-
import android.widget.TextView;
-
import android.widget.Toast;
-
-
-
-
-
public class BluetoothChat extends Activity {
-
-
private static final String TAG = "BluetoothChat";
-
private static final boolean D = true;
-
-
-
public static final int MESSAGE_STATE_CHANGE = 1;
-
public static final int MESSAGE_READ = 2;
-
public static final int MESSAGE_WRITE = 3;
-
public static final int MESSAGE_DEVICE_NAME = 4;
-
public static final int MESSAGE_TOAST = 5;
-
-
-
public static final String DEVICE_NAME = "device_name";
-
public static final String TOAST = "toast";
-
-
-
private static final int REQUEST_CONNECT_DEVICE = 1;
-
private static final int REQUEST_ENABLE_BT = 2;
-
-
-
private TextView mTitle;
-
private ListView mConversationView;
-
private EditText mOutEditText;
-
private Button mSendButton;
-
-
-
private String mConnectedDeviceName = null;
-
-
private ArrayAdapter<String> mConversationArrayAdapter;
-
-
private StringBuffer mOutStringBuffer;
-
-
private BluetoothAdapter mBluetoothAdapter = null;
-
-
private BluetoothChatService mChatService = null;
-
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
if(D) Log.e(TAG, "+++ ON CREATE +++");
-
-
-
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
-
setContentView(R.layout.main);
-
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
-
-
-
mTitle = (TextView) findViewById(R.id.title_left_text);
-
mTitle.setText(R.string.app_name);
-
mTitle = (TextView) findViewById(R.id.title_right_text);
-
-
-
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
-
-
if (mBluetoothAdapter == null) {
-
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
-
finish();
-
return;
-
}
-
}
-
-
@Override
-
public void onStart() {
-
super.onStart();
-
if(D) Log.e(TAG, "++ ON START ++");
-
-
-
-
if (!mBluetoothAdapter.isEnabled()) {
-
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
-
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
-
-
} else {
-
if (mChatService == null) setupChat();
-
}
-
}
-
-
@Override
-
public synchronized void onResume() {
-
super.onResume();
-
if(D) Log.e(TAG, "+ ON RESUME +");
-
-
-
-
-
if (mChatService != null) {
-
-
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
-
-
mChatService.start();
-
}
-
}
-
}
-
-
private void setupChat() {
-
Log.d(TAG, "setupChat()");
-
-
-
mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
-
mConversationView = (ListView) findViewById(R.id.in);
-
mConversationView.setAdapter(mConversationArrayAdapter);
-
-
-
mOutEditText = (EditText) findViewById(R.id.edit_text_out);
-
mOutEditText.setOnEditorActionListener(mWriteListener);
-
-
-
mSendButton = (Button) findViewById(R.id.button_send);
-
mSendButton.setOnClickListener(new OnClickListener() {
-
public void onClick(View v) {
-
-
TextView view = (TextView) findViewById(R.id.edit_text_out);
-
String message = view.getText().toString();
-
sendMessage(message);
-
}
-
});
-
-
-
mChatService = new BluetoothChatService(this, mHandler);
-
-
-
mOutStringBuffer = new StringBuffer("");
-
}
-
-
@Override
-
public synchronized void onPause() {
-
super.onPause();
-
if(D) Log.e(TAG, "- ON PAUSE -");
-
}
-
-
@Override
-
public void onStop() {
-
super.onStop();
-
if(D) Log.e(TAG, "-- ON STOP --");
-
}
-
-
@Override
-
public void onDestroy() {
-
super.onDestroy();
-
-
if (mChatService != null) mChatService.stop();
-
if(D) Log.e(TAG, "--- ON DESTROY ---");
-
}
-
-
private void ensureDiscoverable() {
-
if(D) Log.d(TAG, "ensure discoverable");
-
if (mBluetoothAdapter.getScanMode() !=
-
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
-
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
-
startActivity(discoverableIntent);
-
}
-
}
-
-
-
-
-
-
private void sendMessage(String message) {
-
-
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
-
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
-
return;
-
}
-
-
-
if (message.length() > 0) {
-
-
byte[] send = message.getBytes();
-
mChatService.write(send);
-
-
-
mOutStringBuffer.setLength(0);
-
mOutEditText.setText(mOutStringBuffer);
-
}
-
}
-
-
-
private TextView.OnEditorActionListener mWriteListener =
-
new TextView.OnEditorActionListener() {
-
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
-
-
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
-
String message = view.getText().toString();
-
sendMessage(message);
-
}
-
if(D) Log.i(TAG, "END onEditorAction");
-
return true;
-
}
-
};
-
-
-
private final Handler mHandler = new Handler() {
-
@Override
-
public void handleMessage(Message msg) {
-
switch (msg.what) {
-
case MESSAGE_STATE_CHANGE:
-
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
-
switch (msg.arg1) {
-
case BluetoothChatService.STATE_CONNECTED:
-
mTitle.setText(R.string.title_connected_to);
-
mTitle.append(mConnectedDeviceName);
-
mConversationArrayAdapter.clear();
-
break;
-
case BluetoothChatService.STATE_CONNECTING:
-
mTitle.setText(R.string.title_connecting);
-
break;
-
case BluetoothChatService.STATE_LISTEN:
-
case BluetoothChatService.STATE_NONE:
-
mTitle.setText(R.string.title_not_connected);
-
break;
-
}
-
break;
-
case MESSAGE_WRITE:
-
byte[] writeBuf = (byte[]) msg.obj;
-
-
String writeMessage = new String(writeBuf);
-
mConversationArrayAdapter.add("Me: " + writeMessage);
-
break;
-
case MESSAGE_READ:
-
byte[] readBuf = (byte[]) msg.obj;
-
-
String readMessage = new String(readBuf, 0, msg.arg1);
-
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
-
break;
-
case MESSAGE_DEVICE_NAME:
-
-
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
-
Toast.makeText(getApplicationContext(), "Connected to "
-
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
-
break;
-
case MESSAGE_TOAST:
-
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
-
Toast.LENGTH_SHORT).show();
-
break;
-
}
-
}
-
};
-
-
public void onActivityResult(int requestCode, int resultCode, Intent data) {
-
if(D) Log.d(TAG, "onActivityResult " + resultCode);
-
switch (requestCode) {
-
case REQUEST_CONNECT_DEVICE:
-
-
if (resultCode == Activity.RESULT_OK) {
-
-
String address = data.getExtras()
-
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
-
-
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
-
-
mChatService.connect(device);
-
}
-
break;
-
case REQUEST_ENABLE_BT:
-
-
if (resultCode == Activity.RESULT_OK) {
-
-
setupChat();
-
} else {
-
-
Log.d(TAG, "BT not enabled");
-
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
-
finish();
-
}
-
}
-
}
-
-
@Override
-
public boolean onCreateOptionsMenu(Menu menu) {
-
MenuInflater inflater = getMenuInflater();
-
inflater.inflate(R.menu.option_menu, menu);
-
return true;
-
}
-
-
@Override
-
public boolean onOptionsItemSelected(MenuItem item) {
-
switch (item.getItemId()) {
-
case R.id.scan:
-
-
Intent serverIntent = new Intent(this, DeviceListActivity.class);
-
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
-
return true;
-
case R.id.discoverable:
-
-
ensureDiscoverable();
-
return true;
-
}
-
return false;
-
}
-
-
}
BluetoothChatService.java
public synchronized void start() :
开启 mAcceptThread 线程,由于样例程序是仅 2 人的聊天过程,故之前先检测 mConnectThread 和 mConnectedThread 是否运行,运行则先退出这些线程。
public synchronized voidconnect(BluetoothDevice device) :
取消 CONNECTING 和 CONNECTED 状态下的相关线程,然后运行新的 mConnectThread 线程。
public synchronized voidconnected(BluetoothSocket socket, BluetoothDevice device) :
开启一个 ConnectedThread 来管理对应的当前连接。之前先取消任意现存的 mConnectThread 、 mConnectedThread 、 mAcceptThread 线程,然后开启新 mConnectedThread ,传入当前刚刚接受的socket 连接。最后通过 Handler 来通知 UI 连接 OK 。
public synchronized void stop() :
停止所有相关线程,设当前状态为 NONE 。
public void write(byte[] out) :
在 STATE_CONNECTED 状态下,调用 mConnectedThread 里的 write 方法,写入 byte 。
private void connectionFailed() :
连接失败的时候处理,通知 ui ,并设为 STATE_LISTEN 状态。
private void connectionLost() :
当连接失去的时候,设为 STATE_LISTEN 状态并通知 ui 。
内部类:
private class AcceptThread extendsThread :
创建监听线程,准备接受新连接。使用阻塞方式,调用 BluetoothServerSocket.accept() 。提供 cancel 方法关闭 socket 。
private class ConnectThread extendsThread :
这是定义的连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。构造函数里通过 BluetoothDevice.createRfcommSocketToServiceRecord() ,从待连接的 device 产生 BluetoothSocket. 然后在run 方法中 connect ,成功后调用 BluetoothChatSevice 的 connected() 方法。定义 cancel() 在关闭线程时能够关闭相关 socket 。
private class ConnectedThread extendsThread :
这个是双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。 Run 方法中使用阻塞模式的 InputStream.read() 循环读取输入流, 然后 post 到 UI 线程中更新聊天消息。也提供了 write() 将聊天消息写入输出流传输至对方,传输成功后回写入 UI 线程。最后 cancel() 关闭连接的 socket 。
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.OutputStream;
-
import java.util.UUID;
-
-
import android.annotation.SuppressLint;
-
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;
-
-
-
-
-
-
-
-
@SuppressLint("NewApi")
-
public class BluetoothChatService {
-
-
private static final String TAG = "BluetoothChatService";
-
private static final boolean D = true;
-
-
-
private static final String NAME = "BluetoothChat";
-
-
-
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
-
-
-
private final BluetoothAdapter mAdapter;
-
private final Handler mHandler;
-
private AcceptThread mAcceptThread;
-
private ConnectThread mConnectThread;
-
private ConnectedThread mConnectedThread;
-
private int mState;
-
-
-
public static final int STATE_NONE = 0;
-
public static final int STATE_LISTEN = 1;
-
public static final int STATE_CONNECTING = 2;
-
public static final int STATE_CONNECTED = 3;
-
-
-
-
-
-
-
public BluetoothChatService(Context context, Handler handler) {
-
mAdapter = BluetoothAdapter.getDefaultAdapter();
-
mState = STATE_NONE;
-
mHandler = handler;
-
}
-
-
-
-
-
-
private synchronized void setState(int state) {
-
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
-
mState = state;
-
-
-
mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
-
}
-
-
-
-
public synchronized int getState() {
-
return mState;
-
}
-
-
-
-
-
public synchronized void start() {
-
if (D) Log.d(TAG, "start");
-
-
-
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
-
-
-
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
-
-
-
if (mAcceptThread == null) {
-
mAcceptThread = new AcceptThread();
-
mAcceptThread.start();
-
}
-
setState(STATE_LISTEN);
-
}
-
-
-
-
-
-
public synchronized void connect(BluetoothDevice device) {
-
if (D) Log.d(TAG, "connect to: " + device);
-
-
-
if (mState == STATE_CONNECTING) {
-
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
-
}
-
-
-
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
-
-
-
mConnectThread = new ConnectThread(device);
-
mConnectThread.start();
-
setState(STATE_CONNECTING);
-
}
-
-
-
-
-
-
-
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
-
if (D) Log.d(TAG, "connected");
-
-
-
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
-
-
-
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
-
-
-
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
-
-
-
mConnectedThread = new ConnectedThread(socket);
-
mConnectedThread.start();
-
-
-
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
-
Bundle bundle = new Bundle();
-
bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());
-
msg.setData(bundle);
-
mHandler.sendMessage(msg);
-
-
setState(STATE_CONNECTED);
-
}
-
-
-
-
-
public synchronized void stop() {
-
if (D) Log.d(TAG, "stop");
-
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
-
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
-
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
-
setState(STATE_NONE);
-
}
-
-
-
-
-
-
-
public void write(byte[] out) {
-
-
ConnectedThread r;
-
-
synchronized (this) {
-
if (mState != STATE_CONNECTED) return;
-
r = mConnectedThread;
-
}
-
-
r.write(out);
-
}
-
-
-
-
-
private void connectionFailed() {
-
setState(STATE_LISTEN);
-
-
-
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
-
Bundle bundle = new Bundle();
-
bundle.putString(BluetoothChat.TOAST, "Unable to connect device");
-
msg.setData(bundle);
-
mHandler.sendMessage(msg);
-
}
-
-
-
-
-
private void connectionLost() {
-
setState(STATE_LISTEN);
-
-
-
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
-
Bundle bundle = new Bundle();
-
bundle.putString(BluetoothChat.TOAST, "Device connection was lost");
-
msg.setData(bundle);
-
mHandler.sendMessage(msg);
-
}
-
-
-
-
-
-
-
@SuppressLint("NewApi")
-
private class AcceptThread extends Thread {
-
-
private final BluetoothServerSocket mmServerSocket;
-
-
public AcceptThread() {
-
BluetoothServerSocket tmp = null;
-
-
-
try {
-
-
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
-
} catch (IOException e) {
-
Log.e(TAG, "listen() failed", e);
-
}
-
mmServerSocket = tmp;
-
}
-
-
public void run() {
-
if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
-
setName("AcceptThread");
-
BluetoothSocket socket = null;
-
-
-
while (mState != STATE_CONNECTED) {
-
try {
-
-
-
socket = mmServerSocket.accept();
-
} catch (IOException e) {
-
Log.e(TAG, "accept() failed", e);
-
break;
-
}
-
-
-
if (socket != null) {
-
synchronized (BluetoothChatService.this) {
-
switch (mState) {
-
case STATE_LISTEN:
-
case STATE_CONNECTING:
-
-
connected(socket, socket.getRemoteDevice());
-
break;
-
case STATE_NONE:
-
case STATE_CONNECTED:
-
-
try {
-
socket.close();
-
} catch (IOException e) {
-
Log.e(TAG, "Could not close unwanted socket", e);
-
}
-
break;
-
}
-
}
-
}
-
}
-
if (D) Log.i(TAG, "END mAcceptThread");
-
}
-
-
public void cancel() {
-
if (D) Log.d(TAG, "cancel " + this);
-
try {
-
mmServerSocket.close();
-
} catch (IOException e) {
-
Log.e(TAG, "close() of server failed", e);
-
}
-
}
-
}
-
-
-
-
-
-
-
-
private class ConnectThread extends Thread {
-
private final BluetoothSocket mmSocket;
-
private final BluetoothDevice mmDevice;
-
-
public ConnectThread(BluetoothDevice device) {
-
mmDevice = device;
-
BluetoothSocket tmp = null;
-
-
-
-
try {
-
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
-
} catch (IOException e) {
-
Log.e(TAG, "create() failed", e);
-
}
-
mmSocket = tmp;
-
}
-
-
public void run() {
-
Log.i(TAG, "BEGIN mConnectThread");
-
setName("ConnectThread");
-
-
-
mAdapter.cancelDiscovery();
-
-
-
try {
-
-
-
mmSocket.connect();
-
} catch (IOException e) {
-
connectionFailed();
-
-
try {
-
mmSocket.close();
-
} catch (IOException e2) {
-
Log.e(TAG, "unable to close() socket during connection failure", e2);
-
}
-
-
BluetoothChatService.this.start();
-
return;
-
}
-
-
-
synchronized (BluetoothChatService.this) {
-
mConnectThread = null;
-
}
-
-
-
connected(mmSocket, mmDevice);
-
}
-
-
public void cancel() {
-
try {
-
mmSocket.close();
-
} catch (IOException e) {
-
Log.e(TAG, "close() of connect socket failed", e);
-
}
-
}
-
}
-
-
-
-
-
-
private class ConnectedThread extends Thread {
-
private final BluetoothSocket mmSocket;
-
private final InputStream mmInStream;
-
private final OutputStream mmOutStream;
-
-
public ConnectedThread(BluetoothSocket socket) {
-
Log.d(TAG, "create ConnectedThread");
-
mmSocket = socket;
-
InputStream tmpIn = null;
-
OutputStream tmpOut = null;
-
-
-
try {
-
tmpIn = socket.getInputStream();
-
tmpOut = socket.getOutputStream();
-
} catch (IOException e) {
-
Log.e(TAG, "temp sockets not created", e);
-
}
-
-
mmInStream = tmpIn;
-
mmOutStream = tmpOut;
-
}
-
-
public void run() {
-
Log.i(TAG, "BEGIN mConnectedThread");
-
byte[] buffer = new byte[1024];
-
int bytes;
-
-
-
while (true) {
-
try {
-
-
bytes = mmInStream.read(buffer);
-
-
-
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
-
.sendToTarget();
-
} catch (IOException e) {
-
Log.e(TAG, "disconnected", e);
-
connectionLost();
-
break;
-
}
-
}
-
}
-
-
-
-
-
-
public void write(byte[] buffer) {
-
try {
-
mmOutStream.write(buffer);
-
-
-
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
-
.sendToTarget();
-
} catch (IOException e) {
-
Log.e(TAG, "Exception during write", e);
-
}
-
}
-
-
public void cancel() {
-
try {
-
mmSocket.close();
-
} catch (IOException e) {
-
Log.e(TAG, "close() of connect socket failed", e);
-
}
-
}
-
}
-
}
DeviceListActivity.java
该类包含 UI 和操作的 Activity 类,作用是得到系统默认蓝牙设备的已配对设备列表,以及搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。
-
import java.util.Set;
-
-
import android.annotation.SuppressLint;
-
import android.app.Activity;
-
import android.bluetooth.BluetoothAdapter;
-
import android.bluetooth.BluetoothDevice;
-
import android.content.BroadcastReceiver;
-
import android.content.Context;
-
import android.content.Intent;
-
import android.content.IntentFilter;
-
import android.os.Bundle;
-
import android.util.Log;
-
import android.view.View;
-
import android.view.Window;
-
import android.view.View.OnClickListener;
-
import android.widget.AdapterView;
-
import android.widget.ArrayAdapter;
-
import android.widget.Button;
-
import android.widget.ListView;
-
import android.widget.TextView;
-
import android.widget.AdapterView.OnItemClickListener;
-
-
-
-
-
-
-
-
@SuppressLint("NewApi")
-
public class DeviceListActivity extends Activity {
-
-
private static final String TAG = "DeviceListActivity";
-
private static final boolean D = true;
-
-
-
public static String EXTRA_DEVICE_ADDRESS = "device_address";
-
-
-
private BluetoothAdapter mBtAdapter;
-
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
-
private ArrayAdapter<String> mNewDevicesArrayAdapter;
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
-
-
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
setContentView(R.layout.device_list);
-
-
-
setResult(Activity.RESULT_CANCELED);
-
-
-
Button scanButton = (Button) findViewById(R.id.button_scan);
-
scanButton.setOnClickListener(new OnClickListener() {
-
public void onClick(View v) {
-
doDiscovery();
-
v.setVisibility(View.GONE);
-
}
-
});
-
-
-
-
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
-
mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
-
-
-
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
-
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
-
pairedListView.setOnItemClickListener(mDeviceClickListener);
-
-
-
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
-
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
-
newDevicesListView.setOnItemClickListener(mDeviceClickListener);
-
-
-
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
-
this.registerReceiver(mReceiver, filter);
-
-
-
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
-
this.registerReceiver(mReceiver, filter);
-
-
-
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
-
-
-
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
-
-
-
if (pairedDevices.size() > 0) {
-
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
-
for (BluetoothDevice device : pairedDevices) {
-
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
-
}
-
} else {
-
String noDevices = getResources().getText(R.string.none_paired).toString();
-
mPairedDevicesArrayAdapter.add(noDevices);
-
}
-
}
-
-
@Override
-
protected void onDestroy() {
-
super.onDestroy();
-
-
-
if (mBtAdapter != null) {
-
mBtAdapter.cancelDiscovery();
-
}
-
-
-
this.unregisterReceiver(mReceiver);
-
}
-
-
-
-
-
private void doDiscovery() {
-
if (D) Log.d(TAG, "doDiscovery()");
-
-
-
setProgressBarIndeterminateVisibility(true);
-
setTitle(R.string.scanning);
-
-
-
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
-
-
-
if (mBtAdapter.isDiscovering()) {
-
mBtAdapter.cancelDiscovery();
-
}
-
-
-
mBtAdapter.startDiscovery();
-
}
-
-
-
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
-
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
-
-
mBtAdapter.cancelDiscovery();
-
-
-
String info = ((TextView) v).getText().toString();
-
String address = info.substring(info.length() - 17);
-
-
-
Intent intent = new Intent();
-
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
-
-
-
setResult(Activity.RESULT_OK, intent);
-
finish();
-
}
-
};
-
-
-
-
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
@Override
-
public void onReceive(Context context, Intent intent) {
-
String action = intent.getAction();
-
-
-
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
-
-
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
-
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
-
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
-
}
-
-
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
-
setProgressBarIndeterminateVisibility(false);
-
setTitle(R.string.select_device);
-
if (mNewDevicesArrayAdapter.getCount() == 0) {
-
String noDevices = getResources().getText(R.string.none_found).toString();
-
mNewDevicesArrayAdapter.add(noDevices);
-
}
-
}
-
}
-
};
-
-
}
-