http://download.csdn.net/download/u010471406/9970321我是Android开发小白,入坑快一年了,这是我第一次写博客。希望各位大神不要鄙视,有错的或者有待改进的地方请多多指教。。。。
这篇文章是关于经典蓝牙的,最近再做一个项目,涉及到蓝牙方面的技术,踩了不少的坑。现在总结下,以便来日翻阅和复习。
在涉及到手机与手机,手机连蓝牙串口用到不同的UUID,可以看考这篇文章,讲得非常详细
UUID相关知识
这边文档涉及到以下知识点:
1启动蓝牙.
2.扫描蓝牙
3.启动App自动连接蓝牙
4.连接蓝牙
5.蓝牙通信
6.蓝牙连接状态管理
代码比较简单,所以也不详解了。直接上代码了
2017/6/22 更新下。
之前上传的代码出现了重大bug。在测试过程中,发现蓝牙连接成功,跳转到另外界面,然后再返回,断开连接,发现显示蓝牙状态的TextView setText无效。通过打log发现新创建的TextView与调用setText方法的TextView不是同一个对象,调用setText方法的TextView是之前创建的 ,通过分析可能是之前的TextVIew没有销毁,可以退出跳转界面的时候没有销毁activity。最后发现,是我在activity中创建了一个handler对象,传给了service,这个handler对象一直存在service中,导致了activity不能销毁。
根本问题找到了,写一下解决思路,activity与service之间不用handler通信,直接通过广播的方法,最后解决了问题。这也提醒了自己,使用handler要注意一些特殊情况。多方面考虑
一般蓝牙连接异常的问题,连接不上设备,就我目前遇到的,基本上都是UUID的问题。参考[UUID](http://www.cnblogs.com/cb168/p/4844143.html)
。
自动连接:当蓝牙与设备连接成功的时候,我将设备信息通过SharedPreferences将设备信息保存起来,下次启动app的时候,
直接取出设备信息,自动连接
下面是完整的代码
MainActivity 里面的代码
package com.activity;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import org.litepal.tablemanager.Connector;
import com.application.MyApplication;
import com.bluetooth.R;
import com.constants.Constants;
import com.dialog.DialogListener;
import com.service.BlueToothService;
import com.service.BlueToothService.LocalBinder;
import com.service.BluetoothChatService;
import com.utils.AlertDialogUtil;
import com.utils.SharedPreferencesUtils;
import com.utils.ToastUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.IBinder;
import android.test.TouchUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener, OnItemClickListener {
private final String TGA="MainActivity";
private Button btnSouSuo, btnStop, btnStartService, btnStopService,btnUUID,btnNext;
private ListView lvDeviceList;
private TextView tvBlueState,tvUUID;
private ArrayList<String> mDeviceList;
private ArrayAdapter<String> adapter;
private BluetoothAdapter mBlueadapter;
private BlueToothService.LocalBinder mBind;
private BlueToothService mBlueToothService;
public static String EXTRA_DEVICE_ADDRESS = "device_address";
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBind =(LocalBinder)service;
mBlueToothService = mBind.getService();
String param = (String) SharedPreferencesUtils.getParam(mBlueToothService, "address", "0");
if(!"0".equals(param)){
if(mBlueadapter.isEnabled()){
if(MyApplication.getInstance().getConnectState()==false){
mBlueToothService.connect(param,true);
}else {
tvBlueState.setText("已连接");
}
}else {
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDeviceList = new ArrayList<String>();
init();
initSerVice();
initBlueTooth();
initFilter();
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, mDeviceList);
lvDeviceList.setAdapter(adapter);
}
/**
* 初始化控件
*/
private void init() {
btnSouSuo = (Button) findViewById(R.id.btn_sousuo);
btnStop = (Button) findViewById(R.id.btn_quxiao);
btnStartService = (Button) findViewById(R.id.btn_startSetvice);
btnStopService = (Button) findViewById(R.id.btn_stopSetvice);
btnNext = (Button) findViewById(R.id.btn_next);
tvUUID = (TextView) findViewById(R.id.tv_UUID);
btnUUID=(Button) findViewById(R.id.btn_UUID);
lvDeviceList = (ListView) findViewById(R.id.lv_device_list);
tvBlueState = (TextView) findViewById(R.id.tv_blue_state);
btnSouSuo.setOnClickListener(this);
btnStop.setOnClickListener(this);
btnStopService.setOnClickListener(this);
btnStartService.setOnClickListener(this);
tvBlueState.setOnClickListener(this);
btnUUID.setOnClickListener(this);
btnNext.setOnClickListener(this);
lvDeviceList.setOnItemClickListener(this);
}
/**
* 启动服务和绑定服务
*/
private boolean mIsStartService=false;//只StartService一次,设置flag
private void initSerVice() {
Intent bindIntent = new Intent(MainActivity.this, BlueToothService.class);
if(mIsStartService==false){
startService(bindIntent);
mIsStartService=true;
}
bindService(bindIntent, conn, BIND_AUTO_CREATE);
ToastUtils.showToast(MainActivity.this, "服务已启动", Toast.LENGTH_LONG);
}
/**
* 设置广播过滤器
*/
private void initFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(Constants.ACTION_BOUND_DEVICES);
filter.addAction(Constants.ACTION_NO_BOUND_DEVICES);
filter.addAction(Constants.ACTION_FOUND_BLUE);
filter.addAction(Constants.ACTION_DISCOVERY_FINISHED);
filter.addAction(Constants.ACTION_CONNECTED);
filter.addAction(Constants.ACTION_CONNECTED_LOST);
filter.addAction(Constants.ACTION_CONNECTED_NONE);
filter.addAction(Constants.ACTION_CONNECTED_FAILE);
filter.addAction(Constants.ACTION_CONNECTING);
filter.addAction(Constants.ACTION_DATE);
registerReceiver(receiver, filter);
}
/**
* 开启本机蓝牙
*/
private void initBlueTooth() {
mBlueadapter = BluetoothAdapter.getDefaultAdapter();
if (mBlueadapter != null) { // Device support Bluetooth
// 确认开启蓝牙
if (!mBlueadapter.isEnabled()) {
// 请求用户开启
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, RESULT_FIRST_USER);
}
} 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();
}
}
@Override
protected void onStart() {
// findAvalibleDevice();
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sousuo:
try {
if (mBind != null) {
if(MyApplication.getInstance().getConnectState()==false){
tvBlueState.setText("正在搜索蓝牙设备。。。。。");
mBlueToothService.startScan();
if (mDeviceList != null) {
mDeviceList.clear();
adapter.notifyDataSetChanged();
}
}else {
ToastUtils.showToast(MainActivity.this, "已连接", Toast.LENGTH_LONG);
}
}else {
ToastUtils.showToast(MainActivity.this, "未启动服务", Toast.LENGTH_LONG);
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.btn_quxiao:
if(mBind!=null){
mBlueToothService.stopScan();
}
break;
case R.id.btn_startSetvice:
Log.e(TGA, "startService");
Intent bindIntent = new Intent(MainActivity.this, BlueToothService.class);
startService(bindIntent);
bindService(bindIntent, conn, BIND_AUTO_CREATE);
ToastUtils.showToast(MainActivity.this, "服务已启动", Toast.LENGTH_LONG);
break;
case R.id.btn_stopSetvice:
Log.e(TGA, "stopService");
MyApplication.getInstance().setConnectState(false);
mIsStartService=false;
if(mBind!=null){
bindIntent = new Intent(MainActivity.this, BlueToothService.class);
unbindService(conn);
stopService(bindIntent);
tvBlueState.setText("断开连接");
tvBlueState.setTextColor(Color.RED);
ToastUtils.showToast(MainActivity.this, "服务已关闭", Toast.LENGTH_LONG);
}
break;
case R.id.tv_blue_state:
if(tvBlueState.getText().toString().equals("已连接")){
AlertDialogUtil.createConfirmDialog(MainActivity.this, "断开连接", "是否断开连接", new DialogListener() {
@Override
public void onOkClicked(DialogInterface dialog, Bundle rtnData) {
mBlueToothService.stopConnect();
mBlueToothService.setStateListen(false);
}
}).show();
}
break;
case R.id.btn_UUID:
String myUUID = "1234565";
tvUUID.setText(myUUID);
byte[] out;
try {
out = myUUID.getBytes("UTF-8");
mBlueToothService.write(out);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.btn_next:
Intent intent=new Intent(MainActivity.this,BaiduMapActivity.class);
startActivity(intent);
finish();
break;
}
}
/**
* 广播接受者
*/
public BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Constants.ACTION_DISCOVERY_STARTED)) {
tvBlueState.setText("正在搜索蓝牙设备。。。。。");
tvBlueState.setTextColor(Color.GREEN);
} else if (action.equals(Constants.ACTION_FOUND_BLUE)) {
String deviceInfo = intent.getStringExtra("deviceInfo");
mDeviceList.add(deviceInfo);
adapter.notifyDataSetChanged();
tvBlueState.setText("搜索到以下设备");
tvBlueState.setTextColor(Color.RED);
} else if (action.equals(Constants.ACTION_BOUND_DEVICES)) {
String deviceInfo = intent.getStringExtra("deviceInfo");
mDeviceList.add(deviceInfo);
adapter.notifyDataSetChanged();
} else if (action.equals(Constants.ACTION_NO_BOUND_DEVICES)) {
mDeviceList.add("没有可连接的设备");
adapter.notifyDataSetChanged();
} else if (action.equals(Constants.ACTION_DISCOVERY_FINISHED)) {
tvBlueState.setText("完成搜索蓝牙设备");
tvBlueState.setTextColor(Color.GREEN);
}else if (action.equals(Constants.ACTION_BLUE_CONNECTED)) {
tvBlueState.setText("已连接");
tvBlueState.setTextColor(Color.GREEN);
} else if (action.equals(Constants.ACTION_CONNECTED)) {
tvBlueState.setText("已连接");
tvBlueState.setTextColor(Color.GREEN);
} else if (action.equals(Constants.ACTION_CONNECTED_LOST)) {
tvBlueState.setText("断开连接");
tvBlueState.setTextColor(Color.RED);
} else if (action.equals(Constants.ACTION_CONNECTED_NONE)) {
tvBlueState.setText("未连接");
tvBlueState.setTextColor(Color.RED);
} else if (action.equals(Constants.ACTION_CONNECTED_FAILE)) {
tvBlueState.setText("连接失败");
tvBlueState.setTextColor(Color.RED);
} else if (action.equals(Constants.ACTION_CONNECTING)) {
tvBlueState.setText("正在连接.......");
tvBlueState.setTextColor(Color.YELLOW);
}
}
};
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String deviceInfo = mDeviceList.get(position);
AlertDialog.Builder dialog = new Builder(MainActivity.this);
dialog.setTitle("连接蓝牙").setMessage(deviceInfo)
.setPositiveButton("连接", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String address = deviceInfo.substring(deviceInfo.length() - 17);
if(MyApplication.getInstance().getConnectState()==false){
Log.e(TGA, "connect");
mBlueToothService.connect(address, true);
}else {
ToastUtils.showToast(MainActivity.this, "已连接", Toast.LENGTH_LONG);
}
}
}).setNegativeButton("取消", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.show();
}
@Override
protected void onDestroy() {
unregisterReceiver(receiver);
Intent intent=new Intent(MainActivity.this,BlueToothService.class);
if(mBind!=null){
unbindService(conn);
}
stopService(intent);
super.onDestroy();
}
BlueToothService 后台工作服务类,蓝牙连接,接收,发送数据都在后台完成,通过广播的形式将数据发送给activity显示出来
package com.service;
import java.util.ArrayList;
import com.application.MyApplication;
import com.constants.Constants;
import com.utils.SharedPreferencesUtils;
import android.app.Service;
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.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
/**
* 蓝牙连接后台服务
* @author limeng
*/
public class BlueToothService extends Service {
private final IBinder mBinder = new LocalBinder();
private BluetoothAdapter mAdapter;
private BluetoothChatService mChatService;
private BluetoothDevice device;
private boolean isRun=true;
private String address;
private Intent intent=new Intent();
private Handler mHandler=new Handler(){
private String mConnectedDeviceName;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
try {
intent.setAction(Constants.ACTION_CONNECTED);
sendBroadcast(intent);
} catch (Exception e1) {
e1.printStackTrace();
}
break;
case BluetoothChatService.STATE_CONNECTING:
intent.setAction(Constants.ACTION_CONNECTING);
sendBroadcast(intent);
break;
case Constants.CONNECT_LOST:
intent.setAction(Constants.ACTION_CONNECTED_LOST);
sendBroadcast(intent);
break;
case BluetoothChatService.STATE_NONE:
intent.setAction(Constants.ACTION_CONNECTED_NONE);
sendBroadcast(intent);
break;
}
break;
case Constants.MESSAGE_WRITE:
// 发送的数据
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
Log.e("limeng", "MESSAGE_WRITE=" + writeMessage.toString());
break;
case Constants.MESSAGE_READ:
// 接收的数据
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
break;
case Constants.MESSAGE_DEVICE_NAME:
// 连接的设备名字
mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
break;
case Constants.MESSAGE_TOAST:
try {
// Bundle bundle = msg.getData();
// String mseeage = bundle.getString(Constants.TOAST);
// ToastUtils.showToast(ParameterConfigurationActivity.this, mseeage, Toast.LENGTH_SHORT);
// mBuleConnect.setText("连接设备");
} catch (Exception e) {
e.printStackTrace();
}
break;
case Constants.STATE_CONNECTED:
Bundle bundle = msg.getData();
String address = bundle.getString(Constants.DEVICE_ADDRESS);
Log.e("limeng", "SharedPreferencesUtils----address=" + address);
SharedPreferencesUtils.clear();
// 将连接成功的目标设备的蓝牙地址保存 ,以便下次自动连接
SharedPreferencesUtils.setParam(BlueToothService.this, "address", address);
break;
case Constants.MESSAGE_DATE:
bundle = msg.getData();
String date = bundle.getString("date");
intent.putExtra("date", date);
intent.setAction(Constants.ACTION_DATE);
sendBroadcast(intent);
break;
}
}
};
@Override
public void onCreate() {Log.e("limeng","onCreate");
mAdapter = BluetoothAdapter.getDefaultAdapter();
registerReceiver(receiver, IntentFilter());// 注册广播
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.e("limeng", "onBind");
return mBinder;
}
/**
* @author limeng
*
*/
public class LocalBinder extends Binder {
public BlueToothService getService(){
mChatService=BluetoothChatService.getInstance(mHandler);
isListen=true;
// StateListenThread thread = null;
// if(thread==null){
// thread=new StateListenThread();
// }
// thread.start();
return BlueToothService.this;
}
}
/**
* 扫描蓝牙
*/
public void startScan() {
if (mAdapter != null) {
if(mAdapter.isDiscovering()){
Log.e("limeng", "isDiscovering---startScan");
mAdapter.cancelDiscovery();
mAdapter.startDiscovery();
}else {
Log.e("limeng", "No...isDiscovering---startScan");
mAdapter.startDiscovery();
}
}
}
/**
* 停止扫描蓝牙
*/
public void stopScan() {
if (mAdapter != null) {
if(mAdapter.isDiscovering()){
mAdapter.cancelDiscovery();
}
}
}
/**
* 连接蓝牙
*/
public void connect(String address,boolean flag){
Log.e("limeng", "connect1");
this.address=address;
if (mAdapter != null) {
if(!"0".equals(address)){
device = mAdapter.getRemoteDevice(address);
}
}
if (mChatService != null) {
if(mChatService.getState()!=BluetoothChatService.STATE_CONNECTED){
Log.e("limeng", "connect2");
mChatService.connect(device, true);
}else if(mChatService.getState()==BluetoothChatService.STATE_CONNECTED){
Log.e("limeng", "connect3");
intent=new Intent();
intent.setAction(Constants.ACTION_BLUE_CONNECTED);
BlueToothService.this.sendBroadcast(intent);
}
}
}
public void setStateListen(boolean isRun){
this.isRun=isRun;
}
/**
* 断开蓝牙连接
*/
public void stopConnect(){
Log.e("limeng", "stopConnect----2");
mChatService.stop();
}
public void write(byte [] out){
mChatService.write(out);
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("limeng", "onUnbind");
unregisterReceiver(receiver);
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("limeng", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.e("limeng", "onDestroy");
isListen=false;
MyApplication.getInstance().setConnectState(false);
mChatService.stop();
super.onDestroy();
}
/**
* 广播接收器
*/
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
ArrayList<String> arrayList=new ArrayList<String>();
if (BluetoothDevice.ACTION_FOUND.equals(action)) { // 搜索到新设备
BluetoothDevice btd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 搜索没有配过对的蓝牙设备
// if (btd.getBondState() != BluetoothDevice.BOND_BONDED) {
// if (btd.getName().equals("HC-06")) {
String deviceInfo=btd.getName() + '\n' + btd.getAddress();
Log.e("limeng", "BlueToothService...deviceInfo");
arrayList.add(deviceInfo);
intent.putExtra("deviceInfo", deviceInfo);
intent.setAction(Constants.ACTION_FOUND_BLUE);
BlueToothService.this.sendBroadcast(intent);
// }
// }
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { // 搜索结束
if(arrayList.size()<=0){
// intent.setAction(Constants.ACTION_NO_DEVICE);
// BlueToothService.this.sendBroadcast(intent);
}
intent.setAction(Constants.ACTION_DISCOVERY_FINISHED);
BlueToothService.this.sendBroadcast(intent);
}else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { // 搜索结束
intent.setAction(Constants.ACTION_DISCOVERY_STARTED);
BlueToothService.this.sendBroadcast(intent);
}
}
};
private boolean isListen;
/**
* 状态监听,便于调试
* @author Administrator
*/
class StateListenThread extends Thread{
@Override
public void run() {
while (isListen) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int state = mChatService.getState();
Log.e("limeng","StateListenThread-------state="+state);
}
}
}
/**
* 广播过滤器
*
* @return 过滤器
*/
private static IntentFilter IntentFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);// 搜索发现设备
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);// 开始扫描
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);// 搜索发现设备
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);// 状态改变
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);// 行动扫描模式改变了
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);// 动作状态发生了变化
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);// 连接状态改变
return filter;
}
}
BluetoothChatService
*这个类完成了设置和管理蓝牙的所有工作 与其他设备的连接。
* 它有一个监听传入的线程 连接、用于连接设备的线程和线程
* 连接时执行数据传输。
*
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import com.application.MyApplication;
import com.constants.Constants;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class BluetoothChatService {
// Debugging
private static final String TAG = “BluetoothChatService”;
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
private static final UUID MY_UUID_SECURE = UUID.fromString("00001132-0000-1000-8000-00805F9B34FB");//娑撳秴鎮撻惃鍕箾閹恒儲鏌熷锟�
private static final UUID MY_UUID_INSECURE = UUID.fromString("00001132-0000-1000-8000-00805F9B34FB");
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
private static BluetoothChatService mChatService;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public static final int CONNECT_LOST = 6;
private BluetoothChatService(Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
public static BluetoothChatService getInstance(Handler handler) {
synchronized (BluetoothChatService.class) {
if (mChatService == null) {
mChatService = new BluetoothChatService(handler);
}
}
return mChatService;
}
private synchronized void setState(int state) {
mState = state;
mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized int getState() {
return mState;
}
public synchronized void start() {
Log.d(TAG, "start");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_LISTEN);
if (mSecureAcceptThread == null) {
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
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, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device, final String socketType) {
Log.d(TAG, "connected, Socket Type:" + socketType);
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
Message msg = mHandler.obtainMessage();
msg.what = Constants.STATE_CONNECTED;
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_ADDRESS, device.getAddress());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
MyApplication.getInstance().setConnectState(true);
}
public synchronized void stop() {
Log.d(TAG, "22");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
setState(STATE_NONE);
MyApplication.getInstance().setConnectState(false);
}
public void write(byte[] out) {
ConnectedThread r;
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
r.write(out);
}
private void connectionFailed() {
Log.e(TAG, "21");
MyApplication.getInstance().setConnectState(false);
Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "杩炴帴澶辫触");
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_NONE);
BluetoothChatService.this.start();
}
private void connectionLost() {
Log.e(TAG, "20");
MyApplication.getInstance().setConnectState(false);
Message msg = Message.obtain();
msg.what=Constants.CONNECT_LOST;
mHandler.sendMessage(msg);
BluetoothChatService.this.start();
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "9");
}
mmServerSocket = tmp;
}
public void run() {
Log.e(TAG, "18");
setName("AcceptThread" + mSocketType);
BluetoothSocket socket = null;
while (mState != STATE_CONNECTED) {
try {
Log.e(TAG, "17");
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "16");
break;
}
if (socket != null) {
synchronized (BluetoothChatService.this) {
switch (mState) {
case STATE_LISTEN:
Log.e(TAG, "15");
case STATE_CONNECTING:
Log.e(TAG, "14");
connected(socket, socket.getRemoteDevice(),
mSocketType);
break;
case STATE_NONE:
Log.e(TAG, "3");
case STATE_CONNECTED:
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "11");
}
break;
}
}
}
}
}
public void cancel() {
Log.e(TAG, "12");
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "10");
}
}
}
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice;
private class ConnectThread extends Thread {
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "9");
}
mmSocket = tmp;
}
public void run() {
setName("ConnectThread" + mSocketType);
mAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException e) {
Log.e(TAG, "7");
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "8");
}
connectionFailed();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "6");
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.e(TAG, "5");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "4");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.e(TAG, "26");
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (mState == STATE_CONNECTED) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "3");
connectionLost();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
break;
}
}
}
/**
* Write to the connected OutStream.
*
* @param buffer The bytes to write
*/
public void write(byte[] buffer) {
Log.e(TAG, "24");
try {
Log.e(TAG, "25");
mmOutStream.write(buffer);
mmOutStream.flush();
// Share the sent message back to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "2");
}
}
public void cancel() {
Log.e(TAG, "23");
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "1");
}
}
}
}
“`
最后就写这么多了
总结一下:我觉得作为一个软件开发人员,重要的是思维,逻辑,学习能力,学习找资料,学习百度谷歌,学习怎么看别人优秀的代码,利用别的的成果刷经验提升自己。一个功能,看似简单,但是想要更好的的实现出来,就不是那么容易了。任务一下来,不要直接开干,事前先分析,理清项目的业务逻辑,需要什么东西,制定大概框架,将项目分解,最好通过思维导图画出设计步骤。这样日后开发也会有条理,更能跟踪项目进度。
软件开发不是简单的调用api实现功能
最后附上我的测试代码
项目地址