編輯:關於Android編程
本demo是《Android智能穿戴設備開發指南》書中的一塊內容,實現了兩台手機基於藍牙進行即時通訊的功能。
demo演示如下:
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.startServerBtn:
//打開服務器
Intent serverIntent = new Intent(MainActivity.this, ServerActivity.class);
serverIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(serverIntent);
break;
case R.id.startClientBtn:
//打開客戶端
Intent clientIntent = new Intent(MainActivity.this, ClientActivity.class);
clientIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(clientIntent);
break;
}
}
注冊廣播,開啟服務(BluetoothClientService)
//廣播接收器
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_NOT_FOUND_SERVER.equals(action)) {
//未發現設備
serversText.append("not found device\r\n");
} else if (BluetoothTools.ACTION_FOUND_DEVICE.equals(action)) {
//獲取到設備對象
BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE);
deviceList.add(device);
serversText.append(device.getName() + "\r\n");
} else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) {
//連接成功
serversText.append("連接成功");
sendBtn.setEnabled(true);
} else if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) {
//接收數據
TransmitBean data = (TransmitBean)intent.getExtras().getSerializable(BluetoothTools.DATA);
String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n";
chatEditText.append(msg);
}
}
};
#
//注冊BoradcasrReceiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothTools.ACTION_NOT_FOUND_SERVER);
intentFilter.addAction(BluetoothTools.ACTION_FOUND_DEVICE);
intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME);
intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS);
registerReceiver(broadcastReceiver, intentFilter);
#
//開啟後台service
Intent startService = new Intent(ClientActivity.this, BluetoothClientService.class);
startService(startService);
#
開始搜索藍牙和連接第一個設備
startSearchBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//開始搜索
Intent startSearchIntent = new Intent(BluetoothTools.ACTION_START_DISCOVERY);
sendBroadcast(startSearchIntent);
}
});
selectDeviceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//選擇第一個設備
Intent selectDeviceIntent = new Intent(BluetoothTools.ACTION_SELECTED_DEVICE);
selectDeviceIntent.putExtra(BluetoothTools.DEVICE, deviceList.get(0));
sendBroadcast(selectDeviceIntent);
}
});
向服務器發送消息
sendBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//發送消息
if ("".equals(sendEditText.getText().toString().trim())) {
Toast.makeText(ClientActivity.this, "輸入不能為空", Toast.LENGTH_SHORT).show();
} else {
//發送消息
TransmitBean data = new TransmitBean();
data.setMsg(sendEditText.getText().toString());
Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE);
sendDataIntent.putExtra(BluetoothTools.DATA, data);
sendBroadcast(sendDataIntent);
}
}
});
注冊廣播接收器
//廣播接收器
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) {
//接收數據
TransmitBean data = (TransmitBean) intent.getExtras().getSerializable(BluetoothTools.DATA);
String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n";
msgEditText.append(msg);
} else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) {
//連接成功
serverStateTextView.setText("連接成功");
sendBtn.setEnabled(true);
}
}
};
//注冊BoradcasrReceiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME);
intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS);
registerReceiver(broadcastReceiver, intentFilter);
開啟後台服務
//開啟後台service
Intent startService = new Intent(ServerActivity.this, BluetoothServerService.class);
startService(startService);
向客戶端發送消息
sendBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if ("".equals(sendMsgEditText.getText().toString().trim())) {
Toast.makeText(ServerActivity.this, "輸入不能為空", Toast.LENGTH_SHORT).show();
} else {
//發送消息
TransmitBean data = new TransmitBean();
data.setMsg(sendMsgEditText.getText().toString());
Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE);
sendDataIntent.putExtra(BluetoothTools.DATA, data);
sendBroadcast(sendDataIntent);
}
}
});
/**
* 藍牙模塊客戶端主控制Service
*/
public class BluetoothClientService extends Service {
//搜索到的遠程設備集合
private List discoveredDevices = new ArrayList();
//藍牙適配器
private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//藍牙通訊線程
private BluetoothCommunThread communThread;
//控制信息廣播的接收器
private BroadcastReceiver controlReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_START_DISCOVERY.equals(action)) {
//開始搜索
discoveredDevices.clear(); //清空存放設備的集合
bluetoothAdapter.enable(); //打開藍牙
bluetoothAdapter.startDiscovery(); //開始搜索
} else if (BluetoothTools.ACTION_SELECTED_DEVICE.equals(action)) {
//選擇了連接的服務器設備
BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE);
//開啟設備連接線程
new BluetoothClientConnThread(handler, device).start();
} else if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
//停止後台服務
if (communThread != null) {
communThread.isRun = false;
}
stopSelf();
} else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
//獲取數據
Object data = intent.getSerializableExtra(BluetoothTools.DATA);
if (communThread != null) {
communThread.writeObject(data);
}
}
}
};
//藍牙搜索廣播的接收器
private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//獲取廣播的Action
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//開始搜索
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//發現遠程藍牙設備
//獲取設備
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
discoveredDevices.add(bluetoothDevice);
//發送發現設備廣播
Intent deviceListIntent = new Intent(BluetoothTools.ACTION_FOUND_DEVICE);
deviceListIntent.putExtra(BluetoothTools.DEVICE, bluetoothDevice);
sendBroadcast(deviceListIntent);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//搜索結束
if (discoveredDevices.isEmpty()) {
//若未找到設備,則發動未發現設備廣播
Intent foundIntent = new Intent(BluetoothTools.ACTION_NOT_FOUND_SERVER);
sendBroadcast(foundIntent);
}
}
}
};
//接收其他線程消息的Handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//處理消息
switch (msg.what) {
case BluetoothTools.MESSAGE_CONNECT_ERROR:
//連接錯誤
//發送連接錯誤廣播
Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
sendBroadcast(errorIntent);
break;
case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
//連接成功
//開啟通訊線程
communThread = new BluetoothCommunThread(handler, (BluetoothSocket)msg.obj);
communThread.start();
//發送連接成功廣播
Intent succIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
sendBroadcast(succIntent);
break;
case BluetoothTools.MESSAGE_READ_OBJECT:
//讀取到對象
//發送數據廣播(包含數據對象)
Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
sendBroadcast(dataIntent);
break;
}
super.handleMessage(msg);
}
};
/**
* 獲取通訊線程
* @return
*/
public BluetoothCommunThread getBluetoothCommunThread() {
return communThread;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* Service創建時的回調函數
*/
@Override
public void onCreate() {
//discoveryReceiver的IntentFilter
IntentFilter discoveryFilter = new IntentFilter();
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
//controlReceiver的IntentFilter
IntentFilter controlFilter = new IntentFilter();
controlFilter.addAction(BluetoothTools.ACTION_START_DISCOVERY);
controlFilter.addAction(BluetoothTools.ACTION_SELECTED_DEVICE);
controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);
//注冊BroadcastReceiver
registerReceiver(discoveryReceiver, discoveryFilter);
registerReceiver(controlReceiver, controlFilter);
super.onCreate();
}
/**
* Service銷毀時的回調函數
*/
@Override
public void onDestroy() {
if (communThread != null) {
communThread.isRun = false;
}
//解除綁定
unregisterReceiver(discoveryReceiver);
super.onDestroy();
}
}
/**
* 藍牙模塊服務器端主控制Service
*/
public class BluetoothServerService extends Service {
//藍牙適配器
private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//藍牙通訊線程
private BluetoothCommunThread communThread;
//控制信息廣播接收器
private BroadcastReceiver controlReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
//停止後台服務
if (communThread != null) {
communThread.isRun = false;
}
stopSelf();
} else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
//發送數據
Object data = intent.getSerializableExtra(BluetoothTools.DATA);
if (communThread != null) {
communThread.writeObject(data);
}
}
}
};
//接收其他線程消息的Handler
private Handler serviceHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
//連接成功
//開啟通訊線程
communThread = new BluetoothCommunThread(serviceHandler, (BluetoothSocket)msg.obj);
communThread.start();
//發送連接成功消息
Intent connSuccIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
sendBroadcast(connSuccIntent);
break;
case BluetoothTools.MESSAGE_CONNECT_ERROR:
//連接錯誤
//發送連接錯誤廣播
Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
sendBroadcast(errorIntent);
break;
case BluetoothTools.MESSAGE_READ_OBJECT:
//讀取到數據
//發送數據廣播(包含數據對象)
Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
sendBroadcast(dataIntent);
break;
}
super.handleMessage(msg);
}
};
/**
* 獲取通訊線程
* @return
*/
public BluetoothCommunThread getBluetoothCommunThread() {
return communThread;
}
@Override
public void onCreate() {
//ControlReceiver的IntentFilter
IntentFilter controlFilter = new IntentFilter();
controlFilter.addAction(BluetoothTools.ACTION_START_SERVER);
controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);
//注冊BroadcastReceiver
registerReceiver(controlReceiver, controlFilter);
//開啟服務器
bluetoothAdapter.enable(); //打開藍牙
//開啟藍牙發現功能(300秒)
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
discoveryIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(discoveryIntent);
//開啟後台連接線程
new BluetoothServerConnThread(serviceHandler).start();
super.onCreate();
}
@Override
public void onDestroy() {
if (communThread != null) {
communThread.isRun = false;
}
unregisterReceiver(controlReceiver);
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
/**
* 藍牙客戶端連接線程
*/
public class BluetoothClientConnThread extends Thread{
private Handler serviceHandler; //用於向客戶端Service回傳消息的handler
private BluetoothDevice serverDevice; //服務器設備
private BluetoothSocket socket; //通信Socket
/**
* 構造函數
* @param handler
* @param serverDevice
*/
public BluetoothClientConnThread(Handler handler, BluetoothDevice serverDevice) {
this.serviceHandler = handler;
this.serverDevice = serverDevice;
}
@Override
public void run() {
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
try {
socket = serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
socket.connect();
} catch (Exception ex) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
//發送連接失敗消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
return;
}
//發送連接成功消息,消息的obj參數為連接的socket
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
msg.obj = socket;
msg.sendToTarget();
}
}
/**
* 服務器連接線程
*/
public class BluetoothServerConnThread extends Thread {
private Handler serviceHandler; //用於同Service通信的Handler
private BluetoothAdapter adapter;
private BluetoothSocket socket; //用於通信的Socket
private BluetoothServerSocket serverSocket;
/**
* 構造函數
* @param handler
*/
public BluetoothServerConnThread(Handler handler) {
this.serviceHandler = handler;
adapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
public void run() {
try {
serverSocket = adapter.listenUsingRfcommWithServiceRecord("Server", BluetoothTools.PRIVATE_UUID);
socket = serverSocket.accept();
} catch (Exception e) {
//發送連接失敗消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
e.printStackTrace();
return;
} finally {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (socket != null) {
//發送連接成功消息,消息的obj字段為連接的socket
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
msg.obj = socket;
msg.sendToTarget();
} else {
//發送連接失敗消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
return;
}
}
}
/**
* 藍牙通訊線程
*/
public class BluetoothCommunThread extends Thread {
private Handler serviceHandler; //與Service通信的Handler
private BluetoothSocket socket;
private ObjectInputStream inStream; //對象輸入流
private ObjectOutputStream outStream; //對象輸出流
public volatile boolean isRun = true; //運行標志位
/**
* 構造函數
*
* @param handler 用於接收消息
* @param socket
*/
public BluetoothCommunThread(Handler handler, BluetoothSocket socket) {
this.serviceHandler = handler;
this.socket = socket;
try {
this.outStream = new ObjectOutputStream(socket.getOutputStream());
this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
} catch (Exception e) {
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
//發送連接失敗消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
if (!isRun) {
break;
}
try {
Object obj = inStream.readObject();
//發送成功讀取到對象的消息,消息的obj參數為讀取到的對象
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_READ_OBJECT;
msg.obj = obj;
msg.sendToTarget();
} catch (Exception ex) {
//發送連接失敗消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
ex.printStackTrace();
return;
}
}
//關閉流
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 寫入一個可序列化的對象
*
* @param obj
*/
public void writeObject(Object obj) {
try {
outStream.flush();
outStream.writeObject(obj);
outStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最後還有一個藍牙工具類(BluetoothTools)和用於傳輸的數據類(TransmitBean)代碼就不粘了,直接把源碼地址發出來
當ListView實例addheaderView()或者addFooterView後,再通過setAdapter來添加適配器,此時在ListView實例變量裡保存的適配器
對話框就是一個AlertDialog,但是一個簡單的AlertDialog,我們卻可以將它玩出許多花樣來,下面我們就來一起總結一下AlertDialog的用法。看看各位童
安卓手機自誕生之日起無論多大運存,似乎清內存都是安卓用戶一個必不可少的動作,發展至今安卓系統版本幾經迭代、手機運存不斷飙升,軟硬件都有了翻天覆地的變化,那
一.摘要彈窗通常用於提示用戶進行某種操作,比如:點擊分享按鈕,彈窗分享對話框;雙擊返回按鈕,彈窗退出對話框;下載文件,提示下載對話框等等,分享對話框/退出對話框/下載對話