Android 实现蓝牙客户端与服务器端通信

Posted lovoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 实现蓝牙客户端与服务器端通信相关的知识,希望对你有一定的参考价值。

一、首先说明:蓝牙通信必须用手机测试,因为avd里没有相关的硬件,会报错!
好了,看看最后的效果图:

二、概述:
1.判断是否支持Bluetooth

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(bluetoothAdapter == null) 
    //the device doesn't support bluetooth
 else 
    //the device support bluetooth

2.如果支持,打开Bluetooth

if(!bluetoothAdapter.isEnable()) 
    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

3.监视Bluetooth打开状态

BroadcastReceiver bluetoothState = new BroadcastReceiver() 
    public void onReceive(Context context, Intent intent) 
    String stateExtra = BluetoothAdapter.EXTRA_STATE;
       int state = intent.getIntExtra(stateExtra, -1);
       switch(state) 
    case BluetoothAdapter.STATE_TURNING_ON:
        break;
    case BluetoothAdapter.STATE_ON:
        break;
    case BluetoothAdapter.STATE_TURNING_OFF:
        break;
    case BluetoothAdapter.STATE_OFF:
        break;
    
    


registerReceiver(bluetoothState,new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

4.设置本地设备可以被其它设备搜索

Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(discoveryIntent,REQUEST_DISCOVERY);

BroadcastReceiver discovery = new BroadcastReceiver() 
    @Override
    public void onRecevie(Content context, Intent intent) 
        String scanMode = BluetoothAdapter.EXTRA_SCAN_MODE;
        String preScanMode = BluetoothAdapter.EXTRA_PREVIOUS_SCAN_MODE;
        int mode = intent.getIntExtra(scanMode);
    


registerReceiver(discovery,new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);

5.搜索设备
开始搜索 bluetoothAdapter.startDiscovery();
停止搜索 bluetoothAdapter.cancelDiscovery();

当发现一个设备时,系统会发出ACTION_FOUND广播消息,我们可以实现接收这个消息的BroadcastReceiver

BroadcastReceiver deviceFound = new BroadcastReceiver() 
    @Override
    public void onReceiver(Content content, Intent intent) 
        String remoteDeviceName = intent.getStringExtra(BluetoothAdapter.EXTRA_NAME);
        BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothAdapter.EXTRA_DEVICE);
    

registerReceiver(deviceFound, new IntentFilter(BluetoothAdapter.ACTION_FOUND);

6.连接设备

连接两个蓝牙设备要分别实现服务器端(BluetoothServerSocket)和客户端(BluetoothSocket),这点与J2SE中的

ServerSocket和Socket很类似。

BluetoothServerSocket在服务器端调用方法accept()监听,当有客户端请求到来时,accept()方法返回BluetoothSocket,客户端得到后,两端便可以通信。通过InputStream和OutputStream来实现数据的传输。

accept方法是阻塞的,所以不能放在UI线程中,当用到BluetoothServerSocket和BluetoothSocket时,通常把它们放在各自的新线程中。

三、如何实现
以下是开发中的几个关键步骤:
1)首先开启蓝牙
2)搜索可用设备
3)创建蓝牙socket,获取输入输出流
4)读取和写入数据
5)断开连接关闭蓝牙

1、因为有页面切换,这里我使用了TabHost,但原来的效果不好,没有动画,那只好自己复写了

/**
 * 带有动画效果的TabHost
 * 
 * @Project App_Bluetooth
 * @Package com.android.bluetooth
 * @author chenlin
 * @version 1.0
 * @Date 2013年6月2日
 * @Note TODO
 */
public class AnimationTabHost extends TabHost 

    private int mCurrentTabID = 0;//当前的tabId
    private final long mDuration = 400;//动画时间

    public AnimationTabHost(Context context) 
        this(context, null);
    

    public AnimationTabHost(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    /**
     * 切换动画
     */
    @Override
    public void setCurrentTab(int index) 
        //向右平移 
        if (index > mCurrentTabID) 
            TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,
                    -1.0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
            translateAnimation.setDuration(mDuration);
            getCurrentView().startAnimation(translateAnimation);
            //向左平移
         else if (index < mCurrentTabID) 
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0f,
                    Animation.RELATIVE_TO_SELF, 0f);
            translateAnimation.setDuration(mDuration);
            getCurrentView().startAnimation(translateAnimation);
         

        super.setCurrentTab(index);

        //-----方向平移------------------------------
        if (index > mCurrentTabID) 
            TranslateAnimation translateAnimation = new TranslateAnimation( //
                    Animation.RELATIVE_TO_PARENT, 1.0f,// RELATIVE_TO_SELF
                    Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f);
            translateAnimation.setDuration(mDuration);
            getCurrentView().startAnimation(translateAnimation);
         else if (index < mCurrentTabID) 
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_PARENT, -1.0f, Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f,
                    Animation.RELATIVE_TO_PARENT, 0f);
            translateAnimation.setDuration(mDuration);
            getCurrentView().startAnimation(translateAnimation);
        
        mCurrentTabID = index;
    

2、先搭建好主页,使用复写的TabHost滑动,如何滑动,根据状态,有三种状态

/**
 * 主页
 * 
 * @Project App_Bluetooth
 * @Package com.android.bluetooth
 * @author chenlin
 * @version 1.0
 * @Date 2013年6月2日
 */
@SuppressWarnings("deprecation")
public class BluetoothActivity extends TabActivity 
    static AnimationTabHost mTabHost;//动画tabhost
    static String BlueToothAddress;//蓝牙地址
    static Type mType = Type.NONE;//类型
    static boolean isOpen = false;

    //类型:
    enum Type 
        NONE, SERVICE, CILENT
    ;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initTab();
    

    private void initTab() 
        //初始化
        mTabHost = (AnimationTabHost) getTabHost();
        //添加tab
        mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator("设备列表", getResources().getDrawable(android.R.drawable.ic_menu_add))
                .setContent(new Intent(this, DeviceActivity.class)));
        mTabHost.addTab(mTabHost.newTabSpec("Tab2").setIndicator("会话列表", getResources().getDrawable(android.R.drawable.ic_menu_add))
                .setContent(new Intent(this, ChatActivity.class)));
        //添加监听
        mTabHost.setOnTabChangedListener(new OnTabChangeListener() 
            public void onTabChanged(String tabId) 
                if (tabId.equals("Tab1")) 
                    //TODO
                
            
        );
        //默认在第一个tabhost上面
        mTabHost.setCurrentTab(0);
    

    public void onActivityResult(int requestCode, int resultCode, Intent data) 
        Toast.makeText(this, "address:", Toast.LENGTH_SHORT).show();
    

3、有了主页,就开始分别实现两个列表页面,一个是寻找设备页面DeviceActivity.java,另一个是会话页面ChatActivity.java
1)设备页面DeviceActivity.java

/**
 * 发现的设备列表
 * @Project    App_Bluetooth
 * @Package    com.android.bluetooth
 * @author     chenlin
 * @version    1.0
 * @Date       2013年6月2日
 * @Note       TODO
 */
public class DeviceActivity extends Activity 
    private ListView mListView;
    //数据
    private ArrayList<DeviceBean> mDatas;
    private Button mBtnSearch, mBtnService;
    private ChatListAdapter mAdapter;
    //蓝牙适配器
    private BluetoothAdapter mBtAdapter;


    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.devices);
        initDatas();
        initViews();
        registerBroadcast();
        init();
    

    private void initDatas() 
        mDatas = new ArrayList<DeviceBean>();
        mAdapter = new ChatListAdapter(this, mDatas);
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    

    /**
     * 列出所有的蓝牙设备
     */
    private void init() 
        Log.i("tag", "mBtAdapter=="+ mBtAdapter);
        //根据适配器得到所有的设备信息
        Set<BluetoothDevice> deviceSet = mBtAdapter.getBondedDevices();
        if (deviceSet.size() > 0) 
            for (BluetoothDevice device : deviceSet) 
                mDatas.add(new DeviceBean(device.getName() + "\\n" + device.getAddress(), true));
                mAdapter.notifyDataSetChanged();
                mListView.setSelection(mDatas.size() - 1);
            
         else 
            mDatas.add(new DeviceBean("没有配对的设备", true));
            mAdapter.notifyDataSetChanged();
            mListView.setSelection(mDatas.size() - 1);
        
    

    /**
     * 注册广播
     */
    private void registerBroadcast() 
        //设备被发现广播
        IntentFilter discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mReceiver, discoveryFilter);

        // 设备发现完成
        IntentFilter foundFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, foundFilter);
    

    /**
     * 初始化视图
     */
    private void initViews() 
        mListView = (ListView) findViewById(R.id.list);
        mListView.setAdapter(mAdapter);
        mListView.setFastScrollEnabled(true);


        mListView.setOnItemClickListener(mDeviceClickListener);

        mBtnSearch = (Button) findViewById(R.id.start_seach);
        mBtnSearch.setOnClickListener(mSearchListener);


        mBtnService = (Button) findViewById(R.id.start_service);
        mBtnService.setOnClickListener(new OnClickListener() 
            @Override
            public void onClick(View arg0) 
                BluetoothActivity.mType = Type.SERVICE;
                BluetoothActivity.mTabHost.setCurrentTab(1);
            
        );

    


    /**
     * 搜索监听
     */
    private OnClickListener mSearchListener = new OnClickListener() 
        @Override
        public void onClick(View arg0) 
            if (mBtAdapter.isDiscovering()) 
                mBtAdapter.cancelDiscovery();
                mBtnSearch.setText("重新搜索");
             else 
                mDatas.clear();
                mAdapter.notifyDataSetChanged();

                init();

                /* 开始搜索 */
                mBtAdapter.startDiscovery();
                mBtnSearch.setText("ֹͣ停止搜索");
            
        
    ;

    /**
     * 点击设备监听
     */
    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() 
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

            DeviceBean bean = mDatas.get(position);
            String info = bean.message;
            String address = info.substring(info.length() - 17);
            BluetoothActivity.BlueToothAddress = address;

            AlertDialog.Builder stopDialog = new AlertDialog.Builder(DeviceActivity.this);
            stopDialog.setTitle("连接");//标题
            stopDialog.setMessage(bean.message);
            stopDialog.setPositiveButton("连接", new DialogInterface.OnClickListener() 
                public void onClick(DialogInterface dialog, int which) 
                    mBtAdapter.cancelDiscovery();
                    mBtnSearch.setText("重新搜索");

                    BluetoothActivity.mType = Type.CILENT;
                    BluetoothActivity.mTabHost.setCurrentTab(1);

                    dialog.cancel();
                
            );
            stopDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() 
                public void onClick(DialogInterface dialog, int which) 
                    BluetoothActivity.BlueToothAddress = null;
                    dialog.cancel();
                
            );
            stopDialog.show();
        
    ;

    /**
     * 发现设备广播
     */
    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) 
                    mDatas.add(new DeviceBean(device.getName() + "\\n" + device.getAddress(), false));
                    mAdapter.notifyDataSetChanged();
                    mListView.setSelection(mDatas.size() - 1);
                
                // 如果搜索完成了
             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) 
                setProgressBarIndeterminateVisibility(false);
                if (mListView.getCount() == 0) 
                    mDatas.add(new DeviceBean("û没有发现蓝牙设备", false));
                    mAdapter.notifyDataSetChanged();
                    mListView.setSelection(mDatas.size() - 1);
                
                mBtnSearch.setText("重新搜索");
            
        
    ;

    @Override
    public void onStart() 
        super.onStart();
        if (!mBtAdapter.isEnabled()) 
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, 3);
        
    

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

2)会话页面ChatActivity.java

/**
 * 会话界面
 * 
 * @Project App_Bluetooth
 * @Package com.android.bluetooth
 * @author chenlin
 * @version 1.0
 * @Date 2013年3月2日
 * @Note TODO
 */
public class ChatActivity extends Activity implements OnItemClickListener, OnClickListener 
    private static final int STATUS_CONNECT = 0x11;

    private ListView mListView;
    private ArrayList<DeviceBean> mDatas;
    private Button mBtnSend;// 发送按钮
    private Button mBtnDisconn;// 断开连接
    private EditText mEtMsg;
    private DeviceListAdapter mAdapter;

    /* 一些常量,代表服务器的名称 */
    public static final String PROTOCOL_SCHEME_L2CAP = "btl2cap";
    public static final String PROTOCOL_SCHEME_RFCOMM = "btspp";
    public static final String PROTOCOL_SCHEME_BT_OBEX = "btgoep";
    public static final String PROTOCOL_SCHEME_TCP_OBEX = "tcpobex";

    // 蓝牙服务端socket
    private BluetoothServerSocket mServerSocket;
    // 蓝牙客户端socket
    private BluetoothSocket mSocket;
    // 设备
    private BluetoothDevice mDevice;
    private BluetoothAdapter mBluetoothAdapter;

    // --线程类-----------------
    private ServerThread mServerThread;
    private ClientThread mClientThread;
    private ReadThread mReadThread;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat);
        initDatas();
        initViews();
        initEvents();
    

    private void initEvents() 
        mListView.setOnItemClickListener(this);

        // 发送信息
        mBtnSend.setOnClickListener(new OnClickListener() 
            @Override
            public void onClick(View arg0) 
                String text = mEtMsg.getText().toString();
                if (!TextUtils.isEmpty(text)) 
                    // 发送信息
                    sendMessageHandle(text);

                    mEtMsg.setText("");
                    mEtMsg.clearFocus();
                    // 隐藏软键盘
                    InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    manager.hideSoftInputFromWindow(mEtMsg.getWindowToken(), 0);
                 else
                    Toast.makeText(ChatActivity.this, "发送内容不能为空!", Toast.LENGTH_SHORT).show();
            
        );

        // 关闭会话
        mBtnDisconn.setOnClickListener(new OnClickListener() 
            @Override
            public void onClick(View view) 
                if (BluetoothActivity.mType == Type.CILENT) 
                    shutdownClient();
                 else if (BluetoothActivity.mType == Type.SERVICE) 
                    shutdownServer();
                
                BluetoothActivity.isOpen = false;
                BluetoothActivity.mType = Type.NONE;
                Toast.makeText(ChatActivity.this, "已断开连接!", Toast.LENGTH_SHORT).show();
            
        );
    

    private void initViews() 
        mListView = (ListView) findViewById(R.id.list);
        mListView.setAdapter(mAdapter);
        mListView.setFastScrollEnabled(true);

        mEtMsg = (EditText) findViewById(R.id.MessageText);
        mEtMsg.clearFocus();

        mBtnSend = (Button) findViewById(R.id.btn_msg_send);
        mBtnDisconn = (Button) findViewById(R.id.btn_disconnect);
    

    private void initDatas() 
        mDatas = new ArrayList<DeviceBean>();
        mAdapter = new DeviceListAdapter(this, mDatas);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    

    /**
     * 信息处理
     */
    private Handler mHandler = new Handler() 
        @Override
        public void handleMessage(Message msg) 
            String info = (String) msg.obj;
            switch (msg.what) 
            case STATUS_CONNECT:
                Toast.makeText(ChatActivity.this, info, 0).show();
                break;
            

            if (msg.what == 1) 
                mDatas.add(new DeviceBean(info, true));
                mAdapter.notifyDataSetChanged();
                mListView.setSelection(mDatas.size() - 1);
            else 
                mDatas.add(new DeviceBean(info, false));
                mAdapter.notifyDataSetChanged();
                mListView.setSelection(mDatas.size() - 1);
            
        

    ;

    @Override
    public void onResume() 
        super.onResume();
        if (BluetoothActivity.isOpen) 
            Toast.makeText(this, "连接已经打开,可以通信。如果要再建立连接,请先断开", Toast.LENGTH_SHORT).show();
            return;
        
        if (BluetoothActivity.mType == Type.CILENT) 
            String address = BluetoothActivity.BlueToothAddress;
            if (!"".equals(address)) 
                mDevice = mBluetoothAdapter.getRemoteDevice(address);
                mClientThread = new ClientThread();
                mClientThread.start();
                BluetoothActivity.isOpen = true;
             else 
                Toast.makeText(this, "address is null !", Toast.LENGTH_SHORT).show();
            
         else if (BluetoothActivity.mType == Type.SERVICE) 
            mServerThread = new ServerThread();
            mServerThread.start();
            BluetoothActivity.isOpen = true;
        
    

    // 客户端线程
    private class ClientThread extends Thread 
        public void run() 
            try 
                mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                Message msg = new Message();
                msg.obj = "请稍候,正在连接服务器:" + BluetoothActivity.BlueToothAddress;
                msg.what = STATUS_CONNECT;
                mHandler.sendMessage(msg);

                mSocket.connect();

                msg = new Message();
                msg.obj = "已经连接上服务端!可以发送信息。";
                msg.what = STATUS_CONNECT;
                mHandler.sendMessage(msg);
                // 启动接受数据
                mReadThread = new ReadThread();
                mReadThread.start();
             catch (IOException e) 
                Message msg = new Message();
                msg.obj = "连接服务端异常!断开连接重新试一试。";
                msg.what = STATUS_CONNECT;
                mHandler.sendMessage(msg);
            
        
    ;

    // 开启服务器
    private class ServerThread extends Thread 
        public void run() 
            try 
                // 创建一个蓝牙服务器 参数分别:服务器名称、UUID
                mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
                        UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

                Message msg = new Message();
                msg.obj = "请稍候,正在等待客户端的连接...";
                msg.what = STATUS_CONNECT;
                mHandler.sendMessage(msg);

                /* 接受客户端的连接请求 */
                mSocket = mServerSocket.accept();

                msg = new Message();
                msg.obj = "客户端已经连接上!可以发送信息。";
                msg.what = STATUS_CONNECT;
                mHandler.sendMessage(msg);
                // 启动接受数据
                mReadThread = new ReadThread();
                mReadThread.start();
             catch (IOException e) 
                e.printStackTrace();
            
        
    ;

    /* 停止服务器 */
    private void shutdownServer() 
        new Thread() 
            public void run() 
                if (mServerThread != null) 
                    mServerThread.interrupt();
                    mServerThread = null;
                
                if (mReadThread != null) 
                    mReadThread.interrupt();
                    mReadThread = null;
                
                try 
                    if (mSocket != null) 
                        mSocket.close();
                        mSocket = null;
                    
                    if (mServerSocket != null) 
                        mServerSocket.close();
                        mServerSocket = null;
                    
                 catch (IOException e) 
                    Log.e("server", "mserverSocket.close()", e);
                
            ;
        .start();
    

    /* ͣ停止客户端连接 */
    private void shutdownClient() 
        new Thread() 
            public void run() 
                if (mClientThread != null) 
                    mClientThread.interrupt();
                    mClientThread = null;
                
                if (mReadThread != null) 
                    mReadThread.interrupt();
                    mReadThread = null;
                
                if (mSocket != null) 
                    try 
                        mSocket.close();
                     catch (IOException e) 
                        e.printStackTrace();
                    
                    mSocket = null;
                
            ;
        .start();
    

    // 发送数据
    private void sendMessageHandle(String msg) 
        if (mSocket == null) 
            Toast.makeText(this, "没有连接", Toast.LENGTH_SHORT).show();
            return;
        
        try 
            OutputStream os = mSocket.getOutputStream();
            os.write(msg.getBytes());

            mDatas.add(new DeviceBean(msg, false));
            mAdapter.notifyDataSetChanged();
            mListView.setSelection(mDatas.size() - 1);

         catch (IOException e) 
            e.printStackTrace();
        

    

    // 读取数据
    private class ReadThread extends Thread 
        public void run() 
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream is = null;
            try 
                is = mSocket.getInputStream();
                while (true) 
                    if ((bytes = is.read(buffer)) > 0) 
                        byte[] buf_data = new byte[bytes];
                        for (int i = 0; i < bytes; i++) 
                            buf_data[i] = buffer[i];
                        
                        String s = new String(buf_data);
                        Message msg = new Message();
                        msg.obj = s;
                        msg.what = 1;
                        mHandler.sendMessage(msg);
                    
                
             catch (IOException e1) 
                e1.printStackTrace();
             finally 
                try 
                    is.close();
                 catch (IOException e1) 
                    e1.printStackTrace();
                
            

        
    

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
    

    @Override
    public void onClick(View view) 
    

    @Override
    protected void onDestroy() 
        super.onDestroy();
        if (BluetoothActivity.mType == Type.CILENT) 
            shutdownClient();
         else if (BluetoothActivity.mType == Type.SERVICE) 
            shutdownServer();
        
        BluetoothActivity.isOpen = false;
        BluetoothActivity.mType = Type.NONE;
    

三、相关代码下载
链接:http://pan.baidu.com/s/1eSNRvzG 密码:awgv

—————————————————————————————————————————————————–

java架构师项目实战,高并发集群分布式,大数据高可用视频教程,共760G

下载地址:

https://item.taobao.com/item.htm?id=56273996582

01.高级架构师四十二个阶段高
02.Java高级系统培训架构课程148课时
03.Java高级互联网架构师课程
04.Java互联网架构Netty、Nio、Mina等-视频教程
05.Java高级架构设计2016整理-视频教程
06.架构师基础、高级片
07.Java架构师必修linux运维系列课程
08.Java高级系统培训架构课程116课时
+
hadoop系列教程,java设计模式与数据结构, Spring Cloud微服务, SpringBoot入门

内容详情:

【入门篇】
J2SE的Socket网络编程应用
J2SE的反射机制高级应用
J2SE高深讲解
JAVA编程思想 中级教程
JAVA编程思想 初级教程
JAVA编程思想 高级教程
基于J2SE的QQ聊天工具开发
我来说说面向对象
【进阶篇】
CRM项目
Eclipse
Hibernate
JAVA WEB开发视频
JAVAWEB开发实战经典-高级案例篇
JAVAWEB
JAVA线程并发教程
java网上在线支付实战视频
java设计模式
jdbc
junit
mybatis
spring mvc
SpringMvc+Spring+MyBatis+Maven整合视频
SpringMVC
Spring
Struts2 开发实战讲解
Struts2+Spring3+Hibernate4+Maven+EasyUI整合入门视频
Struts
SVN
tomcat
weblogic
WebService从入门到上手企业开发
企业系统OA办公自动化
手机进销存系统
数据结构和算法视频
设计模式系列
【高级篇】
Cas单点登录
Extjs4.1+Spring3.2+hibernate4.1+mysql5商城
Git权威指南
groovy入门视频
Java 8新特性
Lucene
Mongodb
node.js
Nutch相关框架
OA办公自动化系统
Quartz Job定时任务
Solr高级应用视频
Spring Security权限控制
Spring源码解读与设计详析
Struts2源码剖析与架构指导
大型CMS内容管理系统项目
微信入门视频
深入JVM内核—原理、诊断与优化
深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)
银行接口资料
【架构篇】
ActiveMQ实战
Apache-Tomcat集群搭建
Linux集群
Linux高级架构架构方案及实现指南
Memcached分布式集群
Mysql特级优化课程
nginx+Tomcat+Memcached群集配置软件包
Nginx服务器搭建
Nginx网站架构实战(Web服务器负载均衡与反向代理)
SOA Dubbo
storm入门到精通
storm集群的搭建
storm项目实战
UML建模
互联网公司技术架构系列
京东B2C平台推荐搜索的实践和思考
京东大数据分析与创新应用
京东大规模存储持续研发
京东电商海量订单处理OFC系统的关键技术
优米网架构设计方案
基于SOA 思想下的百万数据架构
大型网站提速之MySQL优化
大型网站架构设计
大数据高并发架构实战案例
数据优化技术Redis
数据库高并发原理
深入Java程序性能调优
深入浅出MongoDB应用实战集群及系统架构
深度揭秘服务器端内幕
电商网站之Solr应用
系统架构设计师
阿里分布式数据库服务实践
—————————————————————————————————————————————————–

以上是关于Android 实现蓝牙客户端与服务器端通信的主要内容,如果未能解决你的问题,请参考以下文章

Android蓝牙开发——实现蓝牙聊天

Android-蓝牙传输

蓝牙通信第2篇:建立通信和发送文字消息,文件消息

蓝牙通信的简要设计与开发

PC端实现蓝牙开发

实现蓝牙客户端与服务器端的区别BluetoothServerSocket和BluetoothSocke