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

}

三、相关代码下载

demo下载:http://xiazai.jb51.net/201701/yuanma/App_BlueTooth_jb51.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android适配安卓6.0蓝牙通讯实现过程

    事先说明: 安卓蓝牙需要定位权限申请,在安卓6.0需要用户手动确认权限后才能使用,各位可以自行查询资料实现,如果嫌麻烦,可以用第三方Bmob集成好的工具类进行实现,详细可以看http://blog.csdn.net/qq_30379689/article/details/52223244 蓝牙连接过程: 1.查询用户是否开启蓝牙. 2.搜索附近的可用的蓝牙. 3.进行蓝牙配对. 4.进行蓝牙连接. 5.获取输入流和输出流. 6.发送消息. 晒上我自己画的美图: 实验效果图: 实现需要的权限:由于

  • Android6.0蓝牙出现无法扫描设备或闪退问题解决办法

    Android6.0蓝牙出现无法扫描设备或闪退问题解决办法 前言: 目前待的这家公司是做智能家居的,最近客户那边有反馈说为什么我的手机蓝牙也打开了,设备的蓝牙也打开了,为啥总是扫描不到呢,但是我们公司的测试人员几经排查,并未发现客户的所描述的扫描不到设备,但客户所说的问题确实又存在,几经周折,找到了原因,原来是现在市场上出来的android6.0手机需要添加两个权限,Android官网也已经说明了, 直接上图 具体权限官网说的很清楚了 解决办法 Android6.0设备通过蓝牙和Wi-Fi扫描访

  • 分享Android 蓝牙4.0(ble)开发的解决方案

    最近,随着智能穿戴式设备.智能医疗以及智能家居的普及,蓝牙开发在移动开中显得非常的重要.由于公司需要,研究了一下,蓝牙4.0在Android中的应用. 以下是我的一些总结. 1.先介绍一下关于蓝牙4.0中的一些名词吧:    (1).GATT(Gneric Attibute  Profile) 通过ble连接,读写属性类小数据Profile通用的规范.现在所有的ble应用Profile  都是基于GATT (2).ATT(Attribute Protocal) GATT是基于ATT Potoca

  • Android系统中的蓝牙连接程序编写实例教程

    Bluetooth结构 1.JAVA层 frameworks/base/core/java/android/bluetooth/ 包含了bluetooth的JAVA类. 2.JNI层 frameworks/base/core/jni/android_bluetooth_开头的文件 定义了bluez通过JNI到上层的接口. frameworks/base/core/jni/android_server_bluetoothservice.cpp 调用硬件适配层的接口system/bluetooth/

  • Android手机通过蓝牙连接佳博打印机的实例代码

    所使用的打印机为佳博打印机,支持蓝牙.wifi.usb我所使用的是通过蓝牙来连接. 在网上找到一个佳博官方针对安卓开发的App源码,但是各种的跳转,没有看太懂,所以又去问度娘,找到了一个不错的文章 Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发. 1. 首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限 // 管理蓝牙设备的权限 <uses-permissionandroid:name="

  • Android单片机与蓝牙模块通信实例代码

    啦啦毕业了,毕业前要写毕业设计,需要写一个简单的蓝牙APP进行交互,通过参考网上资料,问题顺利搞定,下面小编把具体实现思路分享给大家,供大家参考. 1.Android蓝牙编程 蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码(Universally Unique Identifier),这是一个软件构建的标准,也是被开源基金会组织应用在分布式计算环境领域的一部分.在蓝牙3.0及下一版本中,UUID被用于唯一标识一个服务,比如文件传输服务,串口服务.打印机服务等,如下: #蓝牙串

  • Android Bluetooth蓝牙技术使用流程详解

    在上篇文章给大家介绍了Android Bluetooth蓝牙技术初体验相关内容,感兴趣的朋友可以点击了解详情. 一:蓝牙设备之间的通信主要包括了四个步骤 设置蓝牙设备 寻找局域网内可能或者匹配的设备 连接设备 设备之间的数据传输 二:具体编程实现 1. 启动蓝牙功能 首先通过调用静态方法getDefaultAdapter()获取蓝牙适配器BluetoothAdapter,如果返回为空,则无法继续执行了.例如: BluetoothAdapter mBluetoothAdapter = Blueto

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

    一.首先说明:蓝牙通信必须用手机测试,因为avd里没有相关的硬件,会报错! 好了,看看最后的效果图:   二.概述: 1.判断是否支持Bluetooth BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if(bluetoothAdapter == null) { //the device doesn't support bluetooth } else { //the device support

  • Python实现的FTP通信客户端与服务器端功能示例

    本文实例讲述了Python实现的FTP通信客户端与服务器端功能.分享给大家供大家参考,具体如下: 一 代码 1.服务端代码 import socket import threading import os import struct #用户账号.密码.主目录 #也可以把这些信息存放到数据库中 users = {'zhangsan':{'pwd':'zhangsan1234', 'home':r'c:\python 3.5'}, 'lisi':{'pwd':'lisi567', 'home':'c

  • Android中Service和Activity相互通信示例代码

    前言 在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,本文就给大家详细介绍了关于Android中Service和Activity相互通信的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Activity向Service通信 第一种方式:通过MyBinder方式调用Service方法 MainActivity public class Ma

  • Android 获取蓝牙Mac地址的正确方法

    android 从6.0开始,通过BluetoothAdapter.getDefaultAdapter().getAddress()获取的地址是一个固定值02:00:00:00:00:00.6.0已经对蓝牙Wi-Fi的MAC地址做了隐藏. 以下方法能正确的获取android自带蓝牙的Mac地址: 1.添加net.vidageek:mirror:1.6.1 2.实现过程 本人也尝试过其他方法获取,比如从cat /sys/class/net/wlan0/address 或者/sys/class/ne

  • android利用websocket协议与服务器通信

    最近做一个项目,需求中需要服务器主动推送消息到客户端.这样的话一般的http连接就不能使用了.博主问了个朋友,向我推荐websocket协议,特此测试了一下,发现效果很好. android本身没有websocket的库,需要自己下载 ,下载地址. 客户端代码: 界面布局自己写,很简单的两个button package com.example.test; import com.example.test.R; import android.app.Activity; import android.o

  • Android编程之客户端通过socket与服务器通信的方法

    本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

  • android客户端从服务器端获取json数据并解析的实现代码

    首先客户端从服务器端获取json数据 1.利用HttpUrlConnection 复制代码 代码如下: /**      * 从指定的URL中获取数组      * @param urlPath      * @return      * @throws Exception      */     public static String readParse(String urlPath) throws Exception {                  ByteArrayOutputSt

  • java UDP通信客户端与服务器端实例分析

    本文实例讲述了java UDP通信客户端与服务器端.分享给大家供大家参考,具体如下: 最初Udp是以字节为单位进行传输的,所以有很大的限制 服务器端: import java.net.*; public class TestUdpServer { public static void main(String[] args) throws Exception { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(

  • java Tcp通信客户端与服务器端实例

    本文实例讲述了java Tcp通信客户端与服务器端.分享给大家供大家参考,具体如下: 由服务器端发送数据 服务器端: import java.io.*; import java.net.*; public class TestSocket { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(8888); while(true) { Socket s = ss.accept(); O

随机推荐