Android实现一对一蓝牙聊天APP

 更新时间:2018年06月02日 13:28:50   作者:yangxlAndroid  
这篇文章主要为大家详细介绍了Android实现一对一蓝牙聊天APP,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

学习了,三天的Android 蓝牙开发,开始是一头雾水,看着别人讲的Google官方的demo感觉很容易,所有自己也尝试写一个很简单的聊天demo.可是想的很简单,自己做起来也花了,将近一天的时间才搞定这个基本的流程设计.下面是几点心得后面再贴代码

1)写一个简单的demo也好,记得一定需要有总体的流程,才开始抠代码
2)既然是demo毕竟就是新的知识,代码中间的log点一定\不能少,这是你快速调试的利器
3)还是thinking in java 里面的那句话,思考什么是可变的,什么是不可变的,然后分开,这样来实现代码的封装,感觉很不错了.只是现在感觉还是很难想明白
4)开始思考以面向对象的流程处理问题,需要怎么弄,也是封装代码的一种思想

蓝牙聊天的基本功能:

1.实现一对一蓝牙连接
2.实现一对一聊天

很简单的功能,思路看着也很清晰,可是深入去写,才知道,水还是深度的,java不熟的话.
此处基本的如何打开蓝牙不在复述,请自行百度.

思路:

1)初始化,打开手机的蓝牙,开始蓝牙服务器线程,等待连接
2)配对,获取某台手机的蓝牙address地址.
3)开启连接线程连接手机蓝牙
4)连接成功后,开启,蓝牙聊天的线程,进行聊天的通讯.

上面四步是主要思路,其中存在着几个细节的地方,就是在开发中某些逻辑问题,线程间的安全问题,也是需要好好处理的. 让我感受比较深的地方是,一对一聊天,相当于,首相每台机器都可能作为服务器在进行通讯,所以一开始开启了两个服务监听,一旦有一个接入进来,这里需要弄清楚哪个是接入对象,哪个是被接入对象, 没有作为服务端的,可以把服务端线程关闭掉。

下面贴点代码

/**
 * 客户端启动连接线程
 * 通过蓝牙的mac地址获取连接
 * @author Administrator
 *
 */
 private class ConnectThread extends Thread {

 private BluetoothDevice mDevice;
 private BluetoothSocket btSocket = null;

 public ConnectThread(String address) {
  // TODO Auto-generated constructor stub
  mDevice = mBluetoothAdapter.getRemoteDevice(address);
 }

 @Override
 public void run() {
  // TODO Auto-generated method stub
  connect(mDevice);
 }

 private void connect(BluetoothDevice btDev) {

  Method creMethod;
  try {
  creMethod = BluetoothDevice.class.getMethod("createBond");
  creMethod.invoke(btDev);

  } catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
  try {
  btSocket = btDev.createRfcommSocketToServiceRecord(MYUUID);
  System.out.println("========" + "start connect");
  Log.d("BlueToothTestActivity", "开始连接...");
  btSocket.connect();
  mClientSocket = btSocket;
  isConnected=true;
  mHandler.sendEmptyMessage(SUCCESS_SERVICE_BEGIN_TALKING);

  // 作为客户端 关闭 服务端 等待的链接
  if (acceptThread != null) {
   acceptThread.close();
  }
  startTalk();
  } catch (IOException e) {
  // TODO Auto-generated catch block
  System.out.println("???????????????? close socket");
  close();
  System.out.println(e.toString());
  e.printStackTrace();
  }

 }

 private void close() {
  if (btSocket != null) {
  try {
   btSocket.close();
   mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);
  } catch (IOException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  }
 }

}
/**
 * 服务端的设计
 * 每个蓝牙的客户端先要开启服务端等待接入
 * @author Administrator
 *
*/
 private class AcceptThread extends Thread {
 private final BluetoothServerSocket mmServerSocket;

 public AcceptThread() {
  // Use a temporary object that is later assigned to mmServerSocket,
  // because mmServerSocket is final
  BluetoothServerSocket tmp = null;
  try {
  // MY_UUID is the app's UUID string, also used by the client
  // code
  tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Fisrt", MYUUID);
  } catch (IOException e) {
  mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);

  }
  mmServerSocket = tmp;
 }

 public void run() {
  BluetoothSocket socket = null;
  // Keep listening until exception occurs or a socket is returned
  while (isRun) {
  try {
   socket = mmServerSocket.accept();
   mHandler.sendEmptyMessage(SUCCESS_SERVICE_SOCRCKET);

   Log.e("TAG", "========== server start ====");

  } catch (IOException e) {
   mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);
   close();
  }



  // If a connection was accepted
  if (socket != null) {
   // 服务端连接成功,启动聊天线程,通过 同一个 socket 防止多线程赋值出现空值的问题
   isConnected=true;
   mClientSocket = socket;
   mTalkThread = new TalkThread();
   mTalkThread.start();

   // Do work to manage the connection (in a separate thread)
   // 多线程操作小心不安全性
   synchronized (BlueConnectService.this) {
   //close();
   }
  }

  }
 }

 public void close() {
  isRun = false;
  try {
  mmServerSocket.close();
  } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
 }

}
/**
 *设计连接成功后的聊天线程 1.建立流,打通连接 2.发送和接收数据 3.显示数据
 *需要注意的是聊天的时候,需要同一个socket建立连接才能获取对应的输入输出流
 */

 private class TalkThread extends Thread {

 private final BluetoothSocket talkSocket;
 private final InputStream mIs;
 private final OutputStream mOs;
 private boolean isRunning = true;

 public TalkThread() {
  // TODO Auto-generated constructor stub
  talkSocket = mClientSocket;
  if (talkSocket == null) {
  System.out.println("================= talkThread erro ");
  // return;
  }

  InputStream is = null;
  OutputStream os = null;
  try {
  is = talkSocket.getInputStream();
  os = talkSocket.getOutputStream();
  } catch (IOException e) {
  // TODO Auto-generated catch block
  try {
   System.out.println("???????????????? close socket");
   talkSocket.close();
   CloseUtil.closeStream(is, os);
  } catch (IOException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  e.printStackTrace();
  }

  mIs = is;
  mOs = os;

 }

 @Override
 public void run() {
  // TODO Auto-generated method stub
  super.run();
  byte[] buffer = new byte[1024];
  int len;
  while (isRunning) {
  try {
   len = mIs.read(buffer);
   mHandler.obtainMessage(READ_MESSAGE, len, -1, buffer).sendToTarget();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   try {
   isRunning = false;
   isConnected=false;
   System.out.println("???????????????? close socket");
   talkSocket.close();
   // 需要重启服务器
   // 启动服务器

   } catch (IOException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
   }
   CloseUtil.closeStream(mIs, mOs);

  }
  }

 }

 public void write(byte[] bytes) {
  try {
  mOs.write(bytes);
  mHandler.obtainMessage(WRITE_MESSAGE, bytes.length, -1, bytes).sendToTarget();
  } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
 }

}

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

相关文章

  • 关于AndroidStudio新建与编译项目速度慢解决办法

    关于AndroidStudio新建与编译项目速度慢解决办法

    这篇文章主要介绍了关于AndroidStudio新建与编译项目速度慢的解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Android实现多个连续带数字圆圈效果

    Android实现多个连续带数字圆圈效果

    这篇文章主要为大家详细介绍了Android实现多个连续带数字圆圈效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Android提高之模拟信号示波器的实现

    Android提高之模拟信号示波器的实现

    这篇文章主要介绍了Android模拟信号示波器的实现方法,在Android项目开发中有一定的实用价值,需要的朋友可以参考下
    2014-08-08
  • 新手必看Android Studio入门详解

    新手必看Android Studio入门详解

    上篇文章已经说过了Android Studio的安装配置,这篇文章主要介绍了Android Studio入门详解以及一些常见的报错,新手同学一起从这里开始完成我们的第一个Android项目吧!
    2021-08-08
  • Android操作Excel文件的功能实现

    Android操作Excel文件的功能实现

    本篇文章主要介绍了Android操作Excel文件的功能实现,Android中操作Excel文件导出报表时主要采用开源库jxl,有兴趣的可以了解一下。
    2017-03-03
  • android通过自定义toast实现悬浮通知效果的示例代码

    android通过自定义toast实现悬浮通知效果的示例代码

    这篇文章主要介绍了android通过自定义toast实现悬浮通知效果,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • Android实现网易新闻客户端侧滑菜单(1)

    Android实现网易新闻客户端侧滑菜单(1)

    这篇文章主要为大家详细介绍了Android实现网易新闻客户端侧滑菜单第一篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android注册广播的两种方法分析

    Android注册广播的两种方法分析

    这篇文章主要介绍了Android注册广播的两种方法,结合实例形式分析了Android注册广播的方法、步骤与相关注意事项,需要的朋友可以参考下
    2016-02-02
  • flutter实现点击事件

    flutter实现点击事件

    这篇文章主要为大家详细介绍了flutter实现点击事件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • Android简单实现引导页

    Android简单实现引导页

    这篇文章主要为大家详细介绍了Android简单实现引导页,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04

最新评论