淺談Android 中BlueTooth

淺談本人對Android中BlueTooth的學習理解:
首先貼出效果圖:
    然後是在使用藍牙過程中需要的權限詳情:
在清單文件中配置權限,權限一共有兩個需要注意的地方:藍牙權限和定位權限:
藍牙權限:<uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
定位權限:<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
         <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
這個地方爲什麼會用到定位權限呢?因爲在藍牙搜索附近設備的時候是需要定位的,
如果沒有在沒有定位權限的場景下在本程序中直接配對連接藍牙設備是會出現配對不成功的問題的,有時甚至搜索附近的藍牙設備
都搜索不到。
以下是在利用藍牙通訊過程中用到的代碼,這是初始化藍牙以及實現通訊功能的主頁面的activity
public class ChatActivity extends AppCompatActivity {
    private Button mBtnSend;//發送消息的按鈕
    private EditText mEditTextContent;//輸入框
    private TextView tx;//是否連接的TextView
    private ChatMsgViewAdapter mAdapter;//聊天Listview的適配器
    private ListView mListView;
    private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();//存儲數據的集合

    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;//點擊按鈕1   建立新的藍牙連接
    private static final int REQUEST_ENABLE_BT = 3;//打開系統的藍牙

    /**
     * 連接上的藍牙設備的名字
     */
    private String mConnectedDeviceName = null;

    /**
     * 聊天線程的適配器
     */
    private ArrayAdapter<String> mConversationArrayAdapter;

    /**
     *傳出消息
     */
    private StringBuffer mOutStringBuffer;
    /**
     * 本地的藍牙適配器
     */
    private BluetoothAdapter mBluetoothAdapter = null;

    /**
     *  聊天服務
     */
    private BluetoothChatService mChatService = null;

    /**
     * 獲取信息從bluetoothchatservice處理程序
     */
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BluetoothChatService.STATE_CONNECTED:
                            //連接完成
                            tx.setText(mConnectedDeviceName + " 連接到 " + mBluetoothAdapter.getName());
                            break;
                        case BluetoothChatService.STATE_CONNECTING:
                            tx.setText("連接中。。。");
                            break;
                        case BluetoothChatService.STATE_LISTEN:
                        case BluetoothChatService.STATE_NONE:
                            //連接失敗
                            tx.setText("無連接");
                            break;
                    }
                    break;

                //接收  發送的消息
                case Constants.MESSAGE_WRITE:
                    byte[] writeBuf = (byte[]) msg.obj;
                    // 從緩衝區中構造一個字符串
                    String writeMessage = new String(writeBuf);
                    //mConversationArrayAdapter.add("Me:  " + writeMessage);
                    send(writeMessage);
                    break;
                //接收 收到的消息
                case Constants.MESSAGE_READ:
                    byte[] readBuf = (byte[]) msg.obj;
                    // 在緩衝區中的有效字節中構造一個字符串
                    String readMessage = new String(readBuf, 0, msg.arg1);
                    receive(readMessage);
                    break;
                case Constants.MESSAGE_DEVICE_NAME:
                    // 保存連接設備的名稱
                    mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
                    if (null != this) {
                        Toast.makeText(ChatActivity.this, "Connected to "
                                + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
                    }
                    break;
                case Constants.MESSAGE_TOAST:
                    if (null != this) {
                        Toast.makeText(ChatActivity.this, msg.getData().getString(Constants.TOAST),
                                Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        initView();
        initData();

        //獲得BluetoothAdapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //判斷有沒有藍牙設備
        if (mBluetoothAdapter == null) {
            Log.e("錯誤", "設備沒有藍牙模塊");
            finish();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        /** 打開藍牙設備*/
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        } else if (mChatService == null) {
            setupChat();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mChatService != null) {
            mChatService.stop();
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        // 在onresume()執行此檢查覆蓋的情況下,BT是在onstart()沒有啓用,
        // 所以我們停了下來,使它…onresume()時將調用返回action_request_enable活動。
        if (mChatService != null) {
            // 只有國家state_none,我們知道我們還沒有開始
            if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
                // 啓動藍牙聊天服務
                mChatService.start();
            }
        }
    }

    /**
     * 發送按鈕監聽  發送消息
     */
    private void setupChat() {
        mBtnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /** 通過按鈕點擊監聽發送消息的相關處理*/
                sendMessage();
            }
        });
        // 初始化bluetoothchatservice進行藍牙連接
        mChatService = new BluetoothChatService(this, mHandler);

        // 初始化傳出消息的緩衝區
        mOutStringBuffer = new StringBuffer("");
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CONNECT_DEVICE_SECURE:
                // 當devicelistactivity返回與設備連接
                if (resultCode == Activity.RESULT_OK) {
                    connectDevice(data, true);
                }
                break;
            case REQUEST_ENABLE_BT:
                // 當請求啓用藍牙返回時
                if (resultCode == Activity.RESULT_OK) {
                    // 藍牙現在啓用,所以設置一個聊天會話
                    setupChat();
                } else {
                    // 用戶沒有啓用藍牙或發生錯誤
                    Toast.makeText(this, "藍牙開啓失敗!",
                            Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }

    /**
     * 連接設備
     */
    private void connectDevice(Intent data, boolean secure) {
        // Get the device MAC address
        String address = data.getExtras()
                .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
        // Get the BluetoothDevice object
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device, secure);
    }

    /**
     * 讓本設備可見
     */
    private void ensureDiscoverable() {
        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 initView() {
        mListView = (ListView) findViewById(R.id.chat_list_view);
        mBtnSend = (Button) findViewById(R.id.btn_send);
        mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);
        tx = (TextView) findViewById(R.id.tx);
    }

    private final static int COUNT = 8;

    //初始化要顯示的數據
    private void initData() {
        mAdapter = new ChatMsgViewAdapter(this, mDataArrays);
        mListView.setAdapter(mAdapter);
    }

    /**
     * 點擊發送按鈕時傳送數據的方法
     */
    private void sendMessage() {
        if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
            Toast.makeText(this, "未連接藍牙設備!", Toast.LENGTH_SHORT).show();
            mEditTextContent.setText("");
            return;
        }
        String contString = mEditTextContent.getText().toString();
        if (contString.length() > 0) {
            //得到消息的字節寫入bluetoothchatservice
            byte[] send = contString.getBytes();
            mChatService.write(send);
            // 將字符串緩衝區重置爲零,並清除編輯文本字段
            mOutStringBuffer.setLength(0);
            mEditTextContent.setText(mOutStringBuffer);
        } else if (contString.length() == 0) {
            Toast.makeText(this, "發送的消息不能爲空", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 通過handler得到發送的消息  建立實體類  添加到集合中
     *
     * @param msg
     */
    private void send(String msg) {

        ChatMsgEntity entity = new ChatMsgEntity();
        entity.setDate(getDate());
        entity.setName("我");
        entity.setMsgType(false);
        entity.setText(msg);
        mDataArrays.add(entity);
        mAdapter.notifyDataSetChanged();
        mListView.setSelection(mListView.getCount() - 1);
    }

    /**
     * 通過handler得到收到的消息  建立實體類  添加到集合中
     *
     * @param msg
     */
    private void receive(String msg) {
        ChatMsgEntity entity = new ChatMsgEntity();
        entity.setDate(getDate());
        entity.setName(mConnectedDeviceName);
        entity.setMsgType(true);
        entity.setText(msg);
        mDataArrays.add(entity);
        mAdapter.notifyDataSetChanged();
        mListView.setSelection(mListView.getCount() - 1);
    }

    /**
     * 獲取時間
     *
     * @return
     */
    private String getDate() {
        Calendar c = Calendar.getInstance();
        String year = String.valueOf(c.get(Calendar.YEAR));
        String month = String.valueOf(c.get(Calendar.MONTH));
        String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);
        String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
        String mins = String.valueOf(c.get(Calendar.MINUTE));
        StringBuffer sbBuffer = new StringBuffer();
        sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":" + mins);
        return sbBuffer.toString();
    }

    /**
     * 掃描藍牙 延時搜索
     *
     * @param view
     */
    public void abc(View view) {
        switch (view.getId()) {
            case R.id.bt1:
                Intent serverIntent = new Intent(this, DeviceListActivity.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
                break;
            case R.id.bt2:
                //請求本設備是否可被搜索到
                ensureDiscoverable();
                break;
        }
    }
}

以下是展示聊天信息的實體類
public class ChatMsgEntity {
    private static final String TAG = ChatMsgEntity.class.getSimpleName();
    private String name;//誰被名稱
    private String date;//當前時間
    private String text;//內容
    private boolean msgType = true;//類型 true表示發送
    public boolean getMsgType() {
        return msgType;
    }
    public void setMsgType(boolean msgType) {
        this.msgType = msgType;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
    public ChatMsgEntity() {
    }
    public ChatMsgEntity(String name, String date, String text, boolean msgType) {
        this.name = name;
        this.date = date;
        this.text = text;
        this.msgType = msgType;
    }
}
定義一個常量類接口
常量接口
public interface Constants {
    // 從bluetoothchatservice句柄發送消息類型
    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;
    // 從bluetoothchatservice處理接收的關鍵的名字
    public static final String DEVICE_NAME = "device_name";
    public static final String TOAST = "toast";
}
查詢附近設備的activity  
public class DeviceListActivity extends Activity {
    private static final String TAG = "DeviceListActivity";
    /**
     * 返回的地址
     */
    public static String EXTRA_DEVICE_ADDRESS = "device_address";
    /**
     *適配器
     */
    private BluetoothAdapter mBtAdapter;
    /**
     * 發現的新的設備
     */
    private ArrayAdapter<String> mNewDevicesArrayAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.activity_device_list);
        setResult(Activity.RESULT_CANCELED);
        Button scanButton = (Button) findViewById(R.id.button_scan);
        scanButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                doDiscovery();
                v.setVisibility(View.GONE);
            }
        });

        ArrayAdapter<String> pairedDevicesArrayAdapter =
                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(pairedDevicesArrayAdapter);
        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) {
                pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }
        } else {
            String noDevices = "沒有設備配對過";
            pairedDevicesArrayAdapter.add(noDevices);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBtAdapter != null) {
            mBtAdapter.cancelDiscovery();
        }
        this.unregisterReceiver(mReceiver);
    }

    /**
     * 開始查詢設備
     */
    private void doDiscovery() {

        setProgressBarIndeterminateVisibility(true);
        setTitle("掃描設備中");
        findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
        if (mBtAdapter.isDiscovering()) {
            mBtAdapter.cancelDiscovery();
        }
        mBtAdapter.startDiscovery();
    }

    /**
     * 點擊監聽
     */
    private AdapterView.OnItemClickListener mDeviceClickListener
            = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
            // Cancel discovery because it's costly and we're about to connect
            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("選擇要連接的設備");
                if (mNewDevicesArrayAdapter.getCount() == 0) {
                    String noDevices = "沒有發現設備";
                    mNewDevicesArrayAdapter.add(noDevices);
                }
            }
        }
    };
}
創建的服務
public class BluetoothChatService {
    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("fa87c0d0-afac-11de-8a39-0800200c9a66");

    private static final UUID MY_UUID_INSECURE =
            UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");

    private final BluetoothAdapter mAdapter;
    private final Handler mHandler;
    private AcceptThread mSecureAcceptThread;
    private AcceptThread mInsecureAcceptThread;
    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) {
        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);

        // 已經完成連接,所以結束ConnectThread
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        // 結束所有正在運行的ConnectedThread
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        // 結束所有正在運行的AcceptThread因爲我們只要和一個藍牙設備通信!
        if (mSecureAcceptThread != null) {
            mSecureAcceptThread.cancel();
            mSecureAcceptThread = null;
        }
        if (mInsecureAcceptThread != null) {
            mInsecureAcceptThread.cancel();
            mInsecureAcceptThread = null;
        }

        // 開啓一個新的ConnectedThread用於管理消息的讀寫
        mConnectedThread = new ConnectedThread(socket, socketType);
        mConnectedThread.start();

        // 把已經連上的藍牙設備名發給UI Activity
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.DEVICE_NAME, device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);

        setState(STATE_CONNECTED);
    }

    /**
     * Stop 所有線程
     */
    public synchronized void stop() {
        Log.d(TAG, "stop");

        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);
    }


    public void write(byte[] out) {
  
        ConnectedThread r;

        synchronized (this) {
            if (mState != STATE_CONNECTED) return;
            r = mConnectedThread;
        }

        r.write(out);
    }

  
    private void connectionFailed() {
        // Send a failure message back to the Activity
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.TOAST, "Unable to connect device");
        msg.setData(bundle);
        mHandler.sendMessage(msg);


        BluetoothChatService.this.start();
    }

    private void connectionLost() {
    
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.TOAST, "Device connection was lost");
        msg.setData(bundle);
        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, "Socket Type: " + mSocketType + "listen() failed", e);
            }
            mmServerSocket = tmp;
        }

        public void run() {
            Log.d(TAG, "Socket Type: " + mSocketType +
                    "BEGIN mAcceptThread" + this);
            setName("AcceptThread" + mSocketType);

            BluetoothSocket socket = null;

            // Listen to the server socket if we're not connected
            while (mState != STATE_CONNECTED) {
                try {
                    // This is a blocking call and will only return on a
                    // successful connection or an exception
                    socket = mmServerSocket.accept();
                } catch (IOException e) {
                    Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
                    break;
                }

                // If a connection was accepted
                if (socket != null) {
                    synchronized (BluetoothChatService.this) {
                        switch (mState) {
                            case STATE_LISTEN:
                            case STATE_CONNECTING:
                                // Situation normal. Start the connected thread.
                                connected(socket, socket.getRemoteDevice(),
                                        mSocketType);
                                break;
                            case STATE_NONE:
                            case STATE_CONNECTED:
                                // Either not ready or already connected. Terminate new socket.
                                try {
                                    socket.close();
                                } catch (IOException e) {
                                    Log.e(TAG, "Could not close unwanted socket", e);
                                }
                                break;
                        }
                    }
                }
            }
            Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);

        }

        public void cancel() {
            Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
            try {
                mmServerSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
            }
        }
    }
    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
        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, "Socket Type: " + mSocketType + "create() failed", e);
            }
            mmSocket = tmp;
        }

        public void run() {
            Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
            setName("ConnectThread" + mSocketType);

            // 在執行連接時務必關閉藍牙發現以提高效率
            mAdapter.cancelDiscovery();

            // 創建一個 BluetoothSocket 連接
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                mmSocket.connect();
            } catch (IOException e) {
                // Close the socket
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() " + mSocketType +
                            " socket during connection failure", e2);
                }
                connectionFailed();
                return;
            }

            // 已經完成藍牙連接,重置ConnectThread
            synchronized (BluetoothChatService.this) {
                mConnectThread = null;
            }

            // 連接完成,開啓監聽
            connected(mmSocket, mmDevice, mSocketType);
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
            }
        }
    }
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket, String socketType) {
            Log.d(TAG, "create ConnectedThread: " + socketType);
            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 {
                    // 讀InputStream
                    bytes = mmInStream.read(buffer);

                    // 發送讀取的消息到UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    BluetoothChatService.this.start();
                    break;
                }
            }
        }
        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);

                // Share the sent message back to the UI Activity
                mHandler.obtainMessage(Constants.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);
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章