Bluetooth

Bluetooth模块中Socket通信


要实现多个蓝牙设备之间的通信连接,必须实现服务器端与客户端的机制。

1.BluetoothAdapter
本地的蓝牙适配器,是所有蓝牙通信的入口点。使用BluetoothAdapter,搜索其他蓝牙设备,获得一个bonded的设备列 表,使用一个知名的(know)MAC地址实例化一个BluetoothDevice,并创建一个BluetoothServerSocket来监听其他设备的通信

 

2.BluetoothDevice
远程蓝牙设备,使用BluetoothSocket对另一个蓝牙远程设备发出连接请求,或者查询该远程设备的名字、地址、类和连接状态。 
 
3.BluetoothSocket
蓝牙socket的接口(类似于TCP/IP socket接口)。应用程序通过InputStream或者OutputStream与其他蓝牙设备交换数据的连接点。
 
4.BluetoothServerSocket
开放的服务器socket,监听进入的连接请求(类似于TCP/IP的ServerSocket)。为了连接两个Android设备,其中一个 必须打开一个server socket。当一个远程蓝牙设备发出一个连接请求并被接受时,BluetoothServerSocket将返回一个已连接的 BluetoothSocket。




设置蓝牙需要的权限:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.INTERNET"/>

打开蓝牙:

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//方法1
startActivityForResult(intent, REQUEST_SEARCH_BLUETOOTH);
//mAdapter.enable(); //方法2

设置可见:

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
                startActivityForResult(intent, REQUEST_DISCOVER_BLUETOOTH);

onAcitivityResult

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_SEARCH_BLUETOOTH:
                    SingleToast.show(this, "enable ok, scan mode:" + mAdapter.getScanMode());
                    break;
            }
            mStartBtn.setEnabled(true);
        } else if (requestCode == REQUEST_DISCOVER_BLUETOOTH) {
            SingleToast.show(this, "discover ok, scan mode:" + mAdapter.getScanMode());
            mStartBtn.setEnabled(true);
        }
    }
蓝牙配对

/*
     * 連接設備,藍牙配對
     */
    protected void bondDevice() {
        Log.i(ConstantUtil.TAG, "客戶端準備連接->Trying to connect...");
        if (mDevice.getBondState() == BluetoothDevice.BOND_NONE) {
            mDevice.createBond();
        }
    }

蓝牙连接

1.客户端连接

public class ConnectThread extends Thread implements MessageSender{
    private BluetoothSocket mClient;
    private BluetoothDevice mDevice;
    private BluetoothAdapter mAdapter;
    private InputStream mInStream;
    private Handler mHandler;
    private String message;

    public ConnectThread(BluetoothDevice device, Handler handler) {
        mDevice = device;
        mHandler = handler;
        try {
            //初始化一個連接到BluetoothDevice對象的BluetoothSocket對象。
            mClient = device.createRfcommSocketToServiceRecord(UUID.fromString(ConstantUtil.UUID));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public ConnectThread(BluetoothActivity activity, BluetoothDevice device, String msg) {
        this(device, activity.getHandler());
        message = msg;
    }

    public BluetoothSocket getBluetoothSocket() {
        return mClient;
    }

    public Handler getHandler() {
        return mHandler;
    }

    public BluetoothDevice getDevice() {
        return mDevice;
    }

    @Override
    public void run() {
        super.run();
        if (mAdapter == null) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        mAdapter.cancelDiscovery();

        connectDevice();
        while (isEstablish()) {
            try {
                handlerSocketReceived(mClient);
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    public boolean isEstablish() {
        return (mClient != null) && mClient.isConnected();
    }

    private void printLog(String message) {
        ConstantUtil.printLog(mHandler, message);
    }

    public void cancel() {
        try {
            mClient.close();
            mInStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean connectDevice() {
        try {
            if (!mClient.isConnected()) {
                mClient.connect();
            }
        } catch (IOException e) {
            printLog("客戶端失敗FAILED...");
            Log.i(ConstantUtil.TAG, "客戶端失敗FAILED..." + e.toString());
            try {
                mClient = createRfcommSocket();
                mClient.connect();
                return true;
            } catch (Exception ex) {
                printLog("客戶端仍然失敗FAILED...");
                Log.i(ConstantUtil.TAG, "客戶端仍然失敗FAILED..." + e.toString());
                try {
                    if (!mClient.isConnected()) {
                        mClient.close();
                    }
                    return false;
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }
        }

        return send(message, false);
    }

    private BluetoothSocket createRfcommSocket() throws Exception {
        BluetoothSocket socket;
        socket = (BluetoothSocket) mDevice.getClass().getMethod("createRfcommSocket",
                new Class[]{int.class}).invoke(mDevice, ConstantUtil.PORT);
        return socket;
    }

    /**
     * 初始化傳輸數據的縣城。
     * @param msg send message
     * @return true if success,else false;
     * @throws IOException
     */
    private boolean handlerSocketSend(String msg, boolean isReport) throws IOException {
        if (!mClient.isConnected()) {
            printLog("客戶端未連接,返回");
            return false;
        }
        if (msg.isEmpty()) {
            msg = "This is client, the message is test from " + mAdapter.getName() + ".";
        }
        new ConnectedThread(this, msg, isReport).start();
        if (!isReport) {
            mHandler.obtainMessage(ConstantUtil.REPLY_CONNECT_SERVER).sendToTarget();
        }
        return true;
    }

    @Override
    public boolean send(String msg, boolean isReport) {
        try {
            return handlerSocketSend(msg, isReport);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    private void handlerSocketReceived(BluetoothSocket socket) throws IOException {
        Log.i(ConstantUtil.TAG, "客戶端连接成功");
        mInStream = socket.getInputStream();
        byte[] buffer = new byte[1024];
        if (mInStream == null) {
            printLog("服务器连接成功 stream null");
            return;
        }
        int num = mInStream.read(buffer);//this will block until client data;
        String message = new String(buffer, "UTF-8");
        printLog("服务器[名称]:" + socket.getRemoteDevice().getName() + ",[地址]" +
                socket.getRemoteDevice().getAddress());
        printLog("服务器[" + num + "]:" + new String(buffer, "UTF-8") + "\n");
        Log.i(ConstantUtil.TAG, "服务器连接接成功 :" + num + message);
        if (!message.contains(ConstantUtil.RECEIVED)) {
            handlerSocketSend(ConstantUtil.RECEIVED, true);
        }
    }
}



2.服务端连接

public class AcceptThread extends Thread implements MessageSender {
    private BluetoothActivity mActivity;
    private BluetoothServerSocket mServerSocket;
    private BluetoothAdapter mAdapter;
    private InputStream mInStream;
    private OutputStream mOutputSream;
    private BluetoothSocket mSocket = null;
    private Handler mHandler;

    public AcceptThread(BluetoothActivity activity) {
        this();
        mActivity = activity;
        mHandler = activity.getHandler();
    }

    public AcceptThread() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothServerSocket temp;
        try {
//            createRfcommSocket
            temp = mAdapter.listenUsingRfcommWithServiceRecord("zxz",
                    UUID.fromString(ConstantUtil.UUID));
            mServerSocket = temp;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public BluetoothSocket getBluetoothSocket() {
        return mSocket;
    }

    public Handler getHandler() {
        return mHandler;
    }

    public boolean isEstablish() {
        return (mSocket != null) && mSocket.isConnected();
    }

    @Override
    public void run() {
        super.run();
        printLog("服务器启动...");
        Log.i(ConstantUtil.TAG, "服务器启动...");
        while (true) {
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                if (mSocket == null) {
                    if (mServerSocket == null) continue;
                    mSocket = mServerSocket.accept();
                    //Once the BluetoothSocket is acquired, to call mServerSocket.close()
                    mServerSocket.close();
                    mActivity.startServer();
                }
            } catch (IOException e) {
                printLog("服务器启动: " + mSocket + ":" + e.getMessage());
                Log.i(ConstantUtil.TAG, "服务器启动: " + mSocket + ":" + e.getMessage());
                try {
                    mServerSocket = listenUsingRfcomm();
                } catch (Exception ex) {
                    e.printStackTrace();
                    break;
                }
            }
            if (isEstablish()) {
                try {
                    handlerSocketConnect(mSocket);
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    }

    private void printLog(String message) {
        ConstantUtil.printLog(mHandler, message);
    }

    public void cancel() {
        try {
            if (mSocket != null) {
                mSocket.close();
                mSocket = null;
            }
            if (mInStream != null) {
                mInStream.close();
                mInStream = null;
            }
            if (mOutputSream != null) {
                mOutputSream.close();
                mOutputSream  = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean send(String msg, boolean isReport) {
        if (!isEstablish()) {
            printLog("客戶端未連接,返回");
            return false;
        }
        if (msg.isEmpty()) {
            msg = "This is server, the message is test from " + mAdapter.getName() + ".";
        }
        new ConnectedThread(this, msg, isReport).start();
        return true;
    }

    /**
     * 初始化傳輸數據的線程。
     *
     */
    private void handlerSocketConnect(BluetoothSocket socket) throws IOException {
        Log.i(ConstantUtil.TAG, "服务器连接成功");
        mInStream = socket.getInputStream();
        mOutputSream = socket.getOutputStream();
        byte[] buffer = new byte[1024];
        if (mInStream == null) {
            printLog("服务器连接成功 stream null");
            return;
        }
        mHandler.obtainMessage(ConstantUtil.REPLY_CONNECT_SERVER).sendToTarget();
        int num = mInStream.read(buffer);//this will block until client data;
        String message = new String(buffer, "UTF-8");
        printLog("客戶端[名称]:" + socket.getRemoteDevice().getName() + ",[地址]" +
                socket.getRemoteDevice().getAddress());
        printLog("客戶端[" + num + "]:" + message + "\n");
        Log.i(ConstantUtil.TAG, "服务器连接接成功 :" + num + message);
        if (!message.contains(ConstantUtil.RECEIVED)) {
            send(ConstantUtil.RECEIVED, true);
        }
    }

    private BluetoothServerSocket listenUsingRfcomm() throws Exception {
        Method method = mAdapter.getClass().getMethod("listenUsingRfcommOn", int.class);
        BluetoothServerSocket serverSocket = (BluetoothServerSocket) method.invoke(mAdapter,
                ConstantUtil.PORT);
        if (serverSocket == null) {
            throw new IllegalStateException("BluetoothServerSocket return null");
        }
        return serverSocket;
    }
}


3. 发送数据线程

public class ConnectedThread extends Thread {
    private final BluetoothSocket mSocket;
    private BluetoothAdapter mAdapter;
    private OutputStream mOutputStream;
    private Handler mHandler;
    private String message;
    private boolean isClient;
    private boolean mIsReport;

    public ConnectedThread(ConnectThread conn, String msg, boolean isReport) {
        mSocket = conn.getBluetoothSocket();
        mHandler = conn.getHandler();
        message = msg;
        isClient = true;
        mIsReport = isReport;

        if (mAdapter == null) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        try {
            mOutputStream = mSocket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public ConnectedThread(AcceptThread conn, String msg, boolean isReport) {
        mSocket = conn.getBluetoothSocket();
        mHandler = conn.getHandler();
        message = msg;
        isClient = false;
        mIsReport = isReport;

        if (mAdapter == null) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        try {
            mOutputStream = mSocket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

        try {
            handlerSocketConnect(message);
        } catch (IOException e) {
            e.printStackTrace();
            cancel();
        }
    }

    private void sendReport() throws IOException {
        write("Received.");
    }

    private boolean handlerSocketConnect(String msg) throws IOException {
        if (!mSocket.isConnected()) {
            printLog("未連接成功...");
            return false;
        }
        if (mIsReport) {
            sendReport();
            return true;
        }
        printLog((isClient ? "客戶端":"服务端") + "连接成功,发送:" + msg);
        if (msg.isEmpty()) {
            msg = "This is test message, the message is test from " + mAdapter.getName() + ".";
        }
        mOutputStream = mSocket.getOutputStream();
        write(msg);
        return true;
    }

    public void write(String msg) throws IOException {
        mOutputStream.write(msg.getBytes());
        mOutputStream.flush();
    }

    public void cancel() {
        try {
            mSocket.close();
            mOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void printLog(String message) {
        ConstantUtil.printLog(mHandler, message);
    }
}



4. Acitivity

package com.example.zxz.asdemo.ui;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.example.zxz.asdemo.R;
import com.example.zxz.asdemo.data.AcceptThread;
import com.example.zxz.asdemo.data.BluetoothDevicesAdapter;
import com.example.zxz.asdemo.data.ConnectThread;
import com.example.zxz.asdemo.util.ConstantUtil;
import com.example.zxz.asdemo.util.SingleToast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zxz on 15-11-15.
 * Once the device is set up as server, it will act as server among devices.
 */
public class BluetoothActivity extends ActionBarActivity implements View.OnClickListener,
        AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
    private EditText mLogcat, mSendText;
    private Button mSendBtn;
    private BluetoothDevicesAdapter mDevicesAdapter;
    private final int REQUEST_SEARCH_BLUETOOTH = 1001;
    private final int REQUEST_DISCOVER_BLUETOOTH = 1002;
    private BluetoothAdapter mAdapter;
    private ProgressDialog mDialog;
    private List<AcceptThread> server = new ArrayList<>();
    private List<ConnectThread> client = new ArrayList<>();
    private boolean isAsServer;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device;
            if (ConstantUtil.DEBUG) {
                SingleToast.show(BluetoothActivity.this, "onReceive " + action);
            }
            if (BluetoothDevice.ACTION_FOUND.equals(action) ||
                    BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                device = intent.getParcelableExtra(
                        BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                    mDevicesAdapter.addDevice(device);
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                if (mDialog.isShowing() && !mDevicesAdapter.isEmpty()) {
                    SingleToast.show(BluetoothActivity.this, "Devices " + mDevicesAdapter.
                            getCount() + " finished");
                    mDialog.dismiss();
                }
                mDevicesAdapter.notifyDataSetChanged();
            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                switch (device.getBondState()) {
                    case BluetoothDevice.BOND_NONE:
                        SingleToast.show(BluetoothActivity.this, "取消配對");
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        SingleToast.show(BluetoothActivity.this, "完成配對");
                        mDevicesAdapter.notifyDataSetChanged();
                        mDialog.dismiss();
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        mDialog.setTitle("藍牙配對");
                        mDialog.setMessage("正在配對");
                        mDialog.show();
                        break;
                }
            } else if (ConstantUtil.DEBUG) {
                SingleToast.setText(BluetoothActivity.this, "onReceive:" + action);
            }
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (mAdapter.isEnabled()) {
            menu.findItem(R.id.action_start).setTitle(
                    getResources().getString(R.string.stop_bluetooth));
        }
        menu.findItem(R.id.action_asserver).setEnabled(mAdapter.isEnabled());
        menu.findItem(R.id.action_search).setEnabled(mAdapter.isEnabled());
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_start:
                if (!mAdapter.isEnabled()) {
                    mAdapter.enable();
                    item.setTitle(getResources().getString(R.string.stop_bluetooth));
                } else {
                    mAdapter.disable();
                    mDevicesAdapter.removeAllDevice();
                    item.setTitle(getResources().getString(R.string.start_bluetooth));
                }
                break;
            case R.id.action_discover:
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
                startActivityForResult(intent, REQUEST_DISCOVER_BLUETOOTH);
                break;
            case R.id.action_search:
                mAdapter.cancelDiscovery();
                mAdapter.startDiscovery();
                mDialog.setTitle("藍牙設備");
                mDialog.setMessage("搜索中...");
                mDialog.show();
                break;
            case R.id.action_asserver:
                if (!isAsServer) {
                    if (getActionBar() != null) {
                        getActionBar().setTitle(getResources().getString(R.string.server_BT) + ":" +
                                mAdapter.getName());
                    }
                    startServer();
                    item.setTitle(getResources().getString(R.string.close_server_bluetooth));
                } else {
                    closeServer();
                    item.setTitle(getResources().getString(R.string.server_bluetooth));
                }
                break;
            case R.id.action_clear:
                mLogcat.setText("");
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    public Handler getHandler() {
        return mHandler;
    }

    private Handler mHandler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case ConstantUtil.MSG_UPDATE_MESSAGE:
                    mLogcat.append(msg.getData().getCharSequence("data") + "\n");
                    break;
                case ConstantUtil.REPLY_CONNECT_SERVER:
                    mSendBtn.setText(getResources().getString(R.string.send));
                    break;
            }
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);
        IntentFilter filter = new IntentFilter(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.setPriority(Integer.MAX_VALUE);
        registerReceiver(mReceiver, filter);

        ListView mListView = (ListView) findViewById(R.id.device_list);
        mLogcat = (EditText) findViewById(R.id.logcat);
        mSendText = (EditText) findViewById(R.id.send_message);
        mSendBtn = (Button) findViewById(R.id.send_bluetooth);
        mSendBtn.setOnClickListener(this);
        mDevicesAdapter = new BluetoothDevicesAdapter(this);
        mListView.setAdapter(mDevicesAdapter);
        mListView.setOnItemClickListener(this);
        mListView.setOnItemLongClickListener(this);
        mDialog = new ProgressDialog(this);
        initDevice();
    }

    private void initDevice() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        if (getActionBar() != null) {
            getActionBar().setTitle(mAdapter.getName());
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAdapter.cancelDiscovery();
        unregisterReceiver(mReceiver);
        cancel();
    }

    private void cancel() {
        if (server != null) {
            for (AcceptThread accept: server) {
                accept.cancel();
            }
        }
        if (client != null) {
            for (ConnectThread connect: client) {
                connect.cancel();
            }
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.send_bluetooth:
                if (mAdapter.isEnabled()) {
                    if (isAsServer) {//TODO
                        Log.i(ConstantUtil.TAG, "send as server reply.");
                        for (AcceptThread accept : server) {
                            accept.send(mSendText.getText().toString(), false);
                        }
                        mSendText.setText("");
                    } else {
                        if (mDevicesAdapter.getBondDevices() == null ||
                                mDevicesAdapter.getBondDevices().size() == 0) {
                            SingleToast.show(BluetoothActivity.this, "compare device first!");
                            return;
                        }
                        for (BluetoothDevice device: mDevicesAdapter.getBondDevices()) {
                            if (checkClientExist(device)) {
                                Log.i(ConstantUtil.TAG, "send as exist client.");
                                for (ConnectThread conn : client) {
                                    conn.send(mSendText.getText().toString(), false);
                                }
                            } else {
                                SingleToast.show(BluetoothActivity.this, "给" +
                                        mDevicesAdapter.getBondDevices().size() + "台设备发送");
                                sendMessageFromClient(mDevicesAdapter.getBondDevices(),
                                        mSendText.getText().toString());
                            }
                        }
                        mSendText.setText("");
                    }
                } else {
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(intent, REQUEST_SEARCH_BLUETOOTH);
                }
                break;
            default:
                break;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
        mAdapter.cancelDiscovery();
        SingleToast.show(this, "Device: " + ((BluetoothDevice) mDevicesAdapter.getItem(
                pos)).getName() + "連接");
        if (((BluetoothDevice) mDevicesAdapter.getItem(pos)).getBondState() !=
                BluetoothDevice.BOND_BONDED) {
            bondDevice((BluetoothDevice) mDevicesAdapter.getItem(pos));
        }
    }

    /**
     * Server
     */
    public void startServer() {
        isAsServer = true;
        AcceptThread thread = new AcceptThread(this);
        server.add(thread);
        new Thread(thread).start();
    }

    private void closeServer() {
        isAsServer = false;
        if (getActionBar() != null) {
            getActionBar().setTitle(mAdapter.getName());
        }
        mLogcat.append(getResources().getString(R.string.close_server_bluetooth) + "\n");
        for (AcceptThread accept:server) {
            if (accept != null) accept.cancel();
        }
        server.clear();
    }

    /**
     *
     * @param device device
     * @param message msg
     */
    private void startClient(BluetoothDevice device, String message) {
        if (device != null) {
            ConnectThread conn = new ConnectThread(this, device, message);
            client.add(conn);
            new Thread(conn).start();
        }
    }

    private boolean checkClientExist(BluetoothDevice device) {
        for (ConnectThread conn: client) {
            if (conn.getDevice() == device) {
                return true;
            }
        }
        return false;
    }

    public void sendMessageFromClient(List<BluetoothDevice> mDeviceList, String message) {
        if (mDeviceList != null) {
            for (BluetoothDevice device : mDeviceList) {
                startClient(device, message);
            }
        }
    }

    /*
     * 連接設備,藍牙配對
     */
    protected void bondDevice(BluetoothDevice device) {
        if (device.getBondState() == BluetoothDevice.BOND_NONE) {
            device.createBond();
        }
    }

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int pos, long id) {
        mAdapter.cancelDiscovery();
        SingleToast.show(this, "Device: " + ((BluetoothDevice) mDevicesAdapter.getItem(pos)).
                getName() + ":" + getBondState((BluetoothDevice) mDevicesAdapter.getItem(pos)));
        if (((BluetoothDevice) mDevicesAdapter.getItem(pos)).getBondState() ==
                BluetoothDevice.BOND_BONDED) {
            for (ParcelUuid uuid:((BluetoothDevice) mDevicesAdapter.getItem(pos)).
                    getUuids()){
                SingleToast.show(this,uuid.toString());
            }
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_SEARCH_BLUETOOTH:
                    SingleToast.show(this, "enable ok, scan mode:" + mAdapter.getScanMode());
                    break;
            }
        } else if (requestCode == REQUEST_DISCOVER_BLUETOOTH) {
            SingleToast.show(this, "discover ok, scan mode:" + mAdapter.getScanMode());
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        mDialog.dismiss();
        SingleToast.cancelShow();
        mAdapter.cancelDiscovery();
    }

    private String getBondState(BluetoothDevice device) {
        String state = "";
        switch (device.getBondState()) {
            case BluetoothDevice.BOND_BONDED:
                state = getResources().getString(R.string.state_on);
                break;
            case BluetoothDevice.BOND_NONE:
                state = getResources().getString(R.string.state_off);
                break;
            default:
                break;
        }
        return state;
    }
}


package com.example.zxz.asdemo.data;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.zxz.asdemo.R;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zxz on 15-11-16.
 * Adapter in the list
 */
public class BluetoothDevicesAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private List<BluetoothDevice> mDevices, mBondDevices;
    private Context mContext;

    public List<BluetoothDevice> getBondDevices() {
        return mBondDevices;
    }

    public BluetoothDevicesAdapter(Context context) {
        this(context, new ArrayList<BluetoothDevice>());
    }

    public BluetoothDevicesAdapter(Context context, List<BluetoothDevice> devices) {
        mInflater = LayoutInflater.from(context);
        mDevices = devices;
        mContext = context;
    }

    /**
     * 不重複添加
     * @param device bonded device
     */
    public void addDevice(BluetoothDevice device) {
        if (mDevices == null)
            mDevices = new ArrayList<>();
        if (mBondDevices == null)
            mBondDevices = new ArrayList<>();
        if (!mDevices.contains(device)) {
            mDevices.add(device);
            if (device.getBondState() == BluetoothDevice.BOND_BONDED &&
                    !mBondDevices.contains(device)) {
                mBondDevices.add(device);
            }
        }
//        else {
//            mDevices.remove(device);
//            mDevices.add(device);
//        }
        notifyDataSetChanged();
    }

    public void removeAllDevice() {
        if (mDevices == null) return;
        Iterator<BluetoothDevice> iterator = mDevices.iterator();
        mBondDevices = null;
        while (iterator.hasNext()) {
            iterator.next();
            iterator.remove();
        }
        notifyDataSetChanged();
    }

    @Override
    public Object getItem(int position) {
        return mDevices.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
            holder.image = (ImageView) convertView.findViewById(R.id.image);
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.description = (TextView) convertView.findViewById(R.id.description);
            holder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked && (!mBondDevices.contains(mDevices.get(position)))){
                    mBondDevices.add(mDevices.get(position));
                } else if (!isChecked && (mBondDevices.contains(mDevices.get(position)))) {
                    mBondDevices.remove(mDevices.get(position));
                }
            }
        });
        if (mBondDevices.contains(mDevices.get(position))) {
            holder.checkbox.setChecked(true);
        } else {
            holder.checkbox.setChecked(false);
        }
        if (mDevices.get(position).getBondState() == BluetoothDevice.BOND_BONDED) {
            holder.image.setBackground(mContext.getDrawable(
                    R.drawable.ic_settings_bluetooth_alpha));
        } else {
            holder.image.setBackground(mContext.getDrawable(
                    android.R.drawable.stat_sys_data_bluetooth));
        }
        holder.title.setText(mDevices.get(position).getName());
        holder.description.setText(mDevices.get(position).getAddress());
        return convertView;
    }

    @Override
    public int getCount() {
        return mDevices.size();
    }

    private class ViewHolder {
        private TextView title, description;
        private ImageView image;
        private CheckBox checkbox;
    }

 }



写得烂,不过可以实现一个客户端和多个server通信。未完待续



@654131580@qq.com







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值