看了两天,终于能在两个手机端发送接收消息(自用 记录)
来源:互联网 发布:ipad淘宝怎么追加评价 编辑:程序博客网 时间:2024/04/30 04:22
主要功能是能在两个手机上实现数据传输,主要资料来源android 官网的 蓝牙API文档,作为一个初学者,这也是第一个自己看谷歌文档做出来的第一个东西,虽然也挺简单的,但是因为涉及到多线程 而且自己对一些Java函数运用的不是很熟练,所以,在做这个东西的过程中还是遇到了挺多的问题。然后 就自己所遇到的问题做一个简单的记录吧。
利用谷歌官网上的文档实现蓝牙的开启关闭,查找已配对的设备,利用广播接收器实现周围设备的发现(得到其周围未配对设备的Name和address),这些谷歌文档中都有API的实例,比较关键的是设备之间的连接,要在两台设备上的应用之间创建连接,必须同时实现服务器端和客户端机制,因为其中一台设备必须开放服务器套接字,而另一台设备必须发起连接(使用服务器设备的 MAC 地址发起连接)。 当服务器和客户端在同一 RFCOMM 通道上分别拥有已连接的 BluetoothSocket 时,二者将被视为彼此连接。
下面是两台设备获得Socket的过程:
其中一台设备必须通过保持开放的 BluetoothServerSocket 来充当服务器。 服务器套接字的用途是侦听传入的连接请求,并在接受一个请求后提供已连接的 BluetoothSocket。 从 BluetoothServerSocket 获取BluetoothSocket 后,可以(并且应该)舍弃 BluetoothServerSocket,除非您需要接受更多连接。
对于另一台设备:使用 BluetoothDevice,通过调用 createRfcommSocketToServiceRecord(UUID) 获取 BluetoothSocket。这将初始化将要连接到 BluetoothDevice 的 BluetoothSocket。 此处传递的 UUID 必须与服务器设备在使用 listenUsingRfcommWithServiceRecord(String, UUID) 开放其 BluetoothServerSocket 时所用的 UUID 相匹配。 要使用相同的 UUID,只需将该 UUID 字符串以硬编码方式编入应用,然后通过服务器代码和客户端代码引用该字符串。UUID可由众多生成器生成,在这台设备的Socket的生成 必须首先获取表示该远程设备的 BluetoothDevice 对象,(
device.createRfcommSocketToServiceRecord(MY_UUID);)
这两个Socket的获得的关键方法:accept()和connect();都是阻塞调用,所以两个Socket获得写在两个Thread类中,
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
由上面介绍,可以得到几个关键的对象:两个socket对象 以及device对象,对于device ,加入我们知道另一台设备的address值,可由函数String address = "94:65:2D:25:C3:1E"; BluetoothDevice device = BLEadpter.getRemoteDevice(address);得到,因为我们在已配对设备时,返回的是set数组,可以用foreach()语句遍历这个set数组,
for(BluetoothDevice device : pairedDevides){ String name = device.getName(); String address = device.getAddress();}
得到设备address 再利用address获得 远程设备对象。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
有了两个Socket就可以进行数据传输操作了,这里的Socket传输应该和连接是客户端、服务器端应该没什么关系,谷歌文档中用了一个继承自Thread的Connected类,来实现数据的读写,run方法中用不断遍历的方法不断读取
instream中的数据,而write谷歌说通常不会阻塞,一个Socket不断的读,另一个sockte去写数据就实现了数据的传递,因为之前学java也没仔细学,Socket根本不会,在这上面但耽误我很多的时间,下面个人理解:还需要说的是:因为Connected类构造方法需要传入一个Socket类,而对于读操作来说,只需要在Accept类和Connect类中在获取到socket后,就new Connected(Socket socket).start就行,可以变会不断的循环接收数据, 而对于写操作,我是定义了一个Socket成员变量(我做的是一个设备做接收,一个设备做发送,所以直射了一个),在得到Socket时就已经赋给了成员变量,不知道有没有更好的方法 。下面代码很不完善(只是能实现这个功能而已啦)
package com.example.chang.test_finalble;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothServerSocket;import android.bluetooth.BluetoothSocket;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.UUID;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; BluetoothSocket writeSocket; BluetoothSocket acceptSocket; BluetoothAdapter BLEadpter; Handler mhandler; EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = findViewById(R.id.editText); mhandler = new Handler(){ @Override public void handleMessage(Message msg) { byte[] bytes = (byte[])msg.obj; String s = new String(bytes); Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } }; BLEadpter = BluetoothAdapter.getDefaultAdapter(); Button button = findViewById(R.id.button_lianjie); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String address = "94:65:2D:25:C3:1E"; BluetoothDevice device = BLEadpter.getRemoteDevice(address); Log.d(TAG, "device"+(device == null)); //下面对发送数据方注释掉第二行,对接收数据方注释掉第一行 new ConnectThread(device).start(); //new AcceptThread().start(); } }); new AcceptThread().start(); Button button_fasong = findViewById(R.id.button_fasong); button_fasong.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String msg = editText.getText().toString(); try { byte[] bytes = msg.getBytes(); new ConnectedThread(writeSocket).write(bytes); }catch (Exception w){ w.getStackTrace(); } } }); } class AcceptThread extends Thread{ UUID myuuid = UUID.fromString("2aa9ef56-d765-4c66-8b43-06316d968151"); private BluetoothServerSocket mServerSocket; public AcceptThread() { BluetoothServerSocket tmp = null; try { // BLEadpter.cancelDiscovery(); tmp = BLEadpter.listenUsingRfcommWithServiceRecord("Myuuid",myuuid); }catch (Exception e){ e.getStackTrace(); } mServerSocket = tmp; } @Override public void run() { BluetoothSocket socket = null; while (true){ try { Log.d(TAG, "run: "+"Server Socket is running"); socket = mServerSocket.accept(); acceptSocket = socket; }catch (Exception e){ e.getStackTrace(); } if(socket != null){ try { mServerSocket.close(); new ConnectedThread(socket).start(); // manageConnectedSocket(socket); }catch (Exception e){ e.getStackTrace(); } break; } } } } class ConnectThread extends Thread{ private final BluetoothSocket mSocket; private final BluetoothDevice mDevice; UUID myuuid = UUID.fromString("2aa9ef56-d765-4c66-8b43-06316d968151"); public ConnectThread(BluetoothDevice device) { BluetoothSocket tmp = null; mDevice = device; try {BLEadpter.cancelDiscovery(); tmp = device.createRfcommSocketToServiceRecord(myuuid); }catch (Exception e){ e.getStackTrace(); } mSocket = tmp; } @Override public void run() { BLEadpter.cancelDiscovery(); try { writeSocket = mSocket; mSocket.connect(); String msg = "huangty"; try { byte[] bytes = msg.getBytes(); new ConnectedThread(mSocket).write(bytes); }catch (Exception w){ w.getStackTrace(); } //manageConnectedSocket(mSocket); }catch (IOException e){ e.getStackTrace(); } } } class ConnectedThread extends Thread{ private final BluetoothSocket mSocket; private final InputStream mInstream; private final OutputStream moutstream; public ConnectedThread(BluetoothSocket socket) { mSocket = socket; InputStream tmpin = null; OutputStream tmpOut = null; try { tmpin = socket.getInputStream(); tmpOut = socket.getOutputStream(); }catch (Exception e){ e.getStackTrace(); } mInstream = tmpin; moutstream = tmpOut; } @Override public void run() { byte[] buffer = new byte[1024]; // buffer store for the stream int bytes; // bytes returned from read() while (true) { try { bytes = mInstream.read(buffer); mhandler.obtainMessage(1, bytes, -1, buffer) .sendToTarget(); }catch (Exception e){ e.getStackTrace(); } } } public void write(byte[] bytes){ try { moutstream.write(bytes); }catch (Exception e){ e.getStackTrace(); } } }}
- 看了两天,终于能在两个手机端发送接收消息(自用 记录)
- 微信开放,能接收消息不能发送消息
- 终于能上网了~~~
- 终于能访问了!
- 终于能上来了。
- 终于能写了
- AmqpTemplate-发送-接收-消息
- Chrome for Android 编译了两天终于在师傅指导下搞定
- 终于能在手机端上gmail啦|Gmail pop3 (手机端使用),opera mini一点使用感觉
- 最近甚是无聊, 学起了VC, 看了点书,在网上也找了些, 终于搞出两个病毒,呵呵
- 终于摆脱windows能在纯净的linux开发了
- 如何在Qt中处理(接收/发送)MFC或Windows消息(message)
- 求助在java(java web)中发送接收soap消息。
- 进程间传递消息(发送和接收系统消息)
- 终于换手机了!
- JSP服务器什么时候将cookie发送给客户端?一次请求中在一个组件中创建了Cookie,在另外一个组件中能接收到值么?
- 这几天都在看lucene,终于有点眉目了.
- 这两天看了一本好书
- 00000
- GitHub上排名前100的Android开源库
- Java并发编程:Synchronized及其实现原理
- [Leetcode] 517. Super Washing Machines 解题报告
- 【Scikit-Learn 中文文档】线性和二次判别分析
- 看了两天,终于能在两个手机端发送接收消息(自用 记录)
- 模仿米家有品网页3
- BP算法双向传_链式求导---阿里云社区
- xpath路径表达式笔记
- phantom.addCookie正确方法
- 记录tomcat 8.0.26/27/28 容器bug,导致解析jsp错误
- Kafka Java Producer代码实现
- android library引用失败,出现红叉叉解决办法
- 《深入理解java虚拟机》-第2章