android经典蓝牙开发

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实现功能

最后附上我的测试代码
项目地址

猜你喜欢

转载自blog.csdn.net/u010471406/article/details/73504154
今日推荐