看了两天,终于能在两个手机端发送接收消息(自用 记录)

来源:互联网 发布: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();            }        }    }}


阅读全文
1 0