Android蓝牙socket实现视频实时传输,以及图片和文本传输

您所在的位置:网站首页 蓝牙传输怎么传视频 Android蓝牙socket实现视频实时传输,以及图片和文本传输

Android蓝牙socket实现视频实时传输,以及图片和文本传输

2024-07-07 13:35| 来源: 网络整理| 查看: 265

目标 两台手机设备之间能够正常进行蓝牙配对(蓝牙模块儿和硬件挂钩,所以需要两台真机) socket实现蓝牙文本传输 实现图片传输

实现实时视频传输

代码下载:https://download.csdn.net/download/m0_37781149/10434336

蓝牙传输注意事项 Bluetooth的MTU(最大传输单元)是20字节,即一次最多能发送20个字节,若超过20个字节,建议采用分包传输的方式。在传输图片和视频的时候处理方式是将图片转换成字节byte,并在图片前面添加一个头,加入相应的标志位,例如图片大小。然后在接受端进行整合,获取图片大小(字节长度),进行相应判断,整合成图片再显示。下面分模块儿讲解: 蓝牙扫描  通过注册广播来获取蓝牙列表,蓝牙连接状态发生改变时候系统都会发送相应广播,获取相应的蓝牙列表并添加到list中,显示出来     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {         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) {                     String strNoFound = getIntent().getStringExtra("no_devices_found");                     if (strNoFound == null)                         strNoFound = "No devices found";                     if (mPairedDevicesArrayAdapter.getItem(0).equals(strNoFound)) {                         mPairedDevicesArrayAdapter.remove(strNoFound);                     }                     mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());                 }             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {                 setProgressBarIndeterminateVisibility(false);                 String strSelectDevice = getIntent().getStringExtra("select_device");                 if (strSelectDevice == null)                     strSelectDevice = "Select a device to connect";                 setTitle(strSelectDevice);             }         }     };         //扫描蓝牙设备     private void doDiscovery() {         mPairedDevicesArrayAdapter.clear();         if (pairedDevices.size() > 0) {             for (BluetoothDevice device : pairedDevices) {                 mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());             }         } else {             String strNoFound = getIntent().getStringExtra("no_devices_found");             if (strNoFound == null)                 strNoFound = "No devices found";             mPairedDevicesArrayAdapter.add(strNoFound);         }         String strScanning = getIntent().getStringExtra("scanning");         if (strScanning == null)             strScanning = "Scanning for devices...";         setProgressBarIndeterminateVisibility(true);         setTitle(strScanning);         if (mBtAdapter.isDiscovering()) {             mBtAdapter.cancelDiscovery();         }         mBtAdapter.startDiscovery();     } 点击对应的条目可以回退到MainActivity,并将对应的mac地址携带回来,用于蓝牙配对连接     //携带蓝牙地址返回主界面     private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {         public void onItemClick(AdapterView av, View v, int arg2, long arg3) {             if (mBtAdapter.isDiscovering())                 mBtAdapter.cancelDiscovery();             String strNoFound = getIntent().getStringExtra("no_devices_found");             if (strNoFound == null)                 strNoFound = "No devices found";             if (!((TextView) v).getText().toString().equals(strNoFound)) {                 String info = ((TextView) v).getText().toString();                 String address = info.substring(info.length() - 17);                 Intent intent = new Intent();                 intent.putExtra(BluetoothState.EXTRA_DEVICE_ADDRESS, address);                 setResult(Activity.RESULT_OK, intent);                 finish();             }         }     }; 蓝牙连接核心工具类BluetoothUtil,蓝牙状态BluetoothState和BluetoothService 蓝牙配对基本过程:在APP启动的时候,开启一个线程一直监听蓝牙的连接状态,这个子线程是启动时是死循环状态,在蓝牙连接成功时会停止,在蓝牙意外断开时候会重新处于监听状态           public void onStart() {         super.onStart();         if (!mBt.isBluetoothEnabled()) {             //打开蓝牙             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);             startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);         } else {             if (!mBt.isServiceAvailable()) {                 //开启监听                 mBt.setupService();                 mBt.startService(BluetoothState.DEVICE_ANDROID);             }         }     }      public void setupService() {         mChatService = new BluetoothService(mContext, mHandler);     }      public BluetoothService(Context context, Handler handler) {         mAdapter = BluetoothAdapter.getDefaultAdapter();         mState = BluetoothState.STATE_NONE;         mHandler = handler;     }     //开启蓝牙一直监听是否连接的状态     public void startService(boolean isAndroid) {         if (mChatService != null) {             if (mChatService.getState() == BluetoothState.STATE_NONE) {                 isServiceRunning = true;                 mChatService.start(isAndroid);                 BluetoothUtil.this.isAndroid = isAndroid;             }         }     }      //开启子线程     public synchronized void start(boolean isAndroid) {         // Cancel any thread attempting to make a connection         if (mConnectThread != null) {             mConnectThread.cancel();             mConnectThread = null;         }         if (mConnectedThread != null) {             mConnectedThread.cancel();             mConnectedThread = null;         }         setState(BluetoothState.STATE_LISTEN);                  //开启子线程         if (mSecureAcceptThread == null) {             mSecureAcceptThread = new AcceptThread(isAndroid);             mSecureAcceptThread.start();             BluetoothService.this.isAndroid = isAndroid;         }     }     //监听蓝牙连接的线程     private class AcceptThread extends Thread {         private BluetoothServerSocket mmServerSocket;         private String mSocketType;         boolean isRunning = true;         public AcceptThread(boolean isAndroid) {             BluetoothServerSocket tmp = null;             try {                 if (isAndroid)                     //获取蓝牙socket                     tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_ANDROID_DEVICE);                 else                     tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_OTHER_DEVICE);             } catch (IOException e) {             }             mmServerSocket = tmp;         }         public void run() {             setName("AcceptThread" + mSocketType);             BluetoothSocket socket = null;             //死循环监听蓝牙连接状态,首次进入一定满足条件,蓝牙连上后,循环停止             while (mState != BluetoothState.STATE_CONNECTED && isRunning) {                 try {                     socket = mmServerSocket.accept();                 } catch (IOException e) {                     break;                 }                 if (socket != null) {                     synchronized (BluetoothService.this) {                         switch (mState) {                             case BluetoothState.STATE_LISTEN:                             case BluetoothState.STATE_CONNECTING:                                 connected(socket, socket.getRemoteDevice(),                                         mSocketType);                                 break;                             case BluetoothState.STATE_NONE:                             case BluetoothState.STATE_CONNECTED:                                 try {                                     socket.close();                                 } catch (IOException e) {                                 }                                 break;                         }                     }                 }             }         }         public void cancel() {             try {                 mmServerSocket.close();                 mmServerSocket = null;             } catch (IOException e) {             }         }         public void kill() {             isRunning = false;         }     } 核心部分:蓝牙发送和接受数据,蓝牙发送数据处理过程,比如发送一张图片,肯定是大于20字节的,蓝牙是采用分包发送机制,在处理的时候,我们把图片转换成字节,并在图片前面添加一个头,这个头是固定字节的长度,不能太小,因为拍摄图片的时候,图片有大有小,避免和图面装换成字节后产生冲突。这个头里面主要携带两个信息,当然也可以是多个,自由定义。两个信息分别是,图片的大小,即字节长度length,还有一个是动作,例如传照片,传文本,实时视频传输,代码如下:     //添加头发送数据     public void send(byte[] data, String str) {         int length = data.length;         byte[] length_b = null;         try {             length_b = intToByteArray(length);         } catch (Exception e) {             e.printStackTrace();         }         if (length_b == null) return;         //获得一个字节长度为14的byte数组 headInfoLength为14         byte[] headerInfo = new byte[headInfoLength];         //前六位添加012345的标志位         for (int i = 0; i < headInfoLength - 8; i++) {             headerInfo[i] = (byte) i;         }                  //7到10位添加图片大小的字节长度         for (int i = 0; i < 4; i++) {             headerInfo[6 + i] = length_b[i];         }                  //11到14位添加动作信息         if (str.equals("text")) {             for (int i = 0; i < 4; i++) {                 headerInfo[10 + i] = (byte) 0;             }         } else if (str.equals("photo")) {             for (int i = 0; i < 4; i++) {                 headerInfo[10 + i] = (byte) 1;             }         } else if (str.equals("video")) {             for (int i = 0; i < 4; i++) {                 headerInfo[10 + i] = (byte) 2;             }         }          //将对应信息添加到图片前面         byte[] sendMsg = new byte[length + headInfoLength];         for (int i = 0; i < sendMsg.length; i++) {             if (i < headInfoLength) {                 sendMsg[i] = headerInfo[i];             } else {                 sendMsg[i] = data[i - headInfoLength];             }         }         mChatService.write(sendMsg);     }          //蓝牙socket发送数据      public void write(byte[] out) {         ConnectedThread r;         synchronized (this) {             if (mState != BluetoothState.STATE_CONNECTED) return;             r = mConnectedThread;         }         r.write(out);     }       public void write(byte[] buffer) {             try {                 mmOutStream.write(buffer);             } catch (IOException e) {             }         } 蓝牙接收数据:接收到的数据都是字节数据,我们需要把数据进行整合成对应的图片或视频信息,因为发送时分包机制,所以整合的时候要确保整张图片发送完毕才开始整合,具体流程是先获取前六位标志位,然后获取第7到10位的图片大小,再获取第11位到14位的动作信息,具体代码如下:               public void run() {             byte[] buffer;             ArrayList arr_byte = new ArrayList();             while (true) {                 try {                     boolean valid = true;                     //判断前六位是不是012345                     for (int i = 0; i < 6; i++) {                         int t = mmInStream.read();                         if (t != i) {                             valid = false;                             //前六位判断完了跳出循环                             break;                         }                     }                     if (valid) {                         //获取图片大小                         byte[] bufLength = new byte[4];                         for (int i = 0; i < 4; i++) {                             bufLength[i] = ((Integer) mmInStream.read()).byteValue();                         }                                          int TextCount = 0;                         int PhotoCount = 0;                         int VideoCount = 0;                         //获取动作信息                         for (int i = 0; i < 4; i++) {                             int read = mmInStream.read();                             if (read == 0) {                                 TextCount++;                             } else if (read == 1) {                                 PhotoCount++;                             } else if (read == 2) {                                 VideoCount++;                             }                         }                         //获取图片的字节                         int length = ByteArrayToInt(bufLength);                         buffer = new byte[length];                         for (int i = 0; i < length; i++) {                             buffer[i] = ((Integer) mmInStream.read()).byteValue();                         }                                      //通过handler发出去                         Message msg = Message.obtain();                         msg.what = BluetoothState.MESSAGE_READ;                         msg.obj = buffer;                         if (TextCount == 4) {                             msg.arg1 = 0;                             mHandler.sendMessage(msg);                         } else if (PhotoCount == 4) {                             msg.arg1 = 1;                             mHandler.sendMessage(msg);                         } else if (VideoCount == 4) {                             msg.arg1 = 2;                             mHandler.sendMessage(msg);                         }                     }                 } catch (IOException e) {                     connectionLost();                     BluetoothService.this.start(BluetoothService.this.isAndroid);                     break;                 } catch (Exception e) {                     e.printStackTrace();                 }             }

        }

下面分别是发送端和接受端的完整代码: 发送端SendClient代码部分: layout文件:                                                                   发射端的主界面:     public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {     private static final String TAG = MainActivity.class.getName();     private static final int REQUEST_BLUETOOTH_ENABLE = 100;     private BluetoothUtil mBt;     private Camera mCamera;     private SurfaceHolder mSurfaceHolder;     private int mWidth;     private int mHeight;     private EditText mInput;     private boolean isBluetoothConnnect;     public Camera.Size size;     private boolean mark = true;     private int count;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         mBt = new BluetoothUtil(this);         mInput = (EditText) findViewById(R.id.input);         SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);         mSurfaceHolder = surfaceView.getHolder();         mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);         mSurfaceHolder.addCallback(this);         initBlue();     }     private void initBlue() {         /**          * reveice data          */         mBt.setOnDataReceivedListener(new BluetoothUtil.OnDataReceivedListener() {             public void onDataReceived(byte[] data, String message) {             }         });         mBt.setBluetoothConnectionListener(new BluetoothUtil.BluetoothConnectionListener() {             public void onDeviceConnected(String name, String address) {                 isBluetoothConnnect = true;                 Toast.makeText(getApplicationContext(), "连接到 " + name + "\n" + address, Toast.LENGTH_SHORT).show();             }             public void onDeviceDisconnected() {                 isBluetoothConnnect = false;                 //断开蓝牙连接                 Toast.makeText(getApplicationContext(), "蓝牙断开", Toast.LENGTH_SHORT).show();             }             public void onDeviceConnectionFailed() {                 Toast.makeText(getApplicationContext(), "无法连接", Toast.LENGTH_SHORT).show();             }         });     }     @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         super.onActivityResult(requestCode, resultCode, data);         if (requestCode == BluetoothState.REQUEST_CONNECT_DEVICE) {             if (resultCode == Activity.RESULT_OK)                 mBt.connect(data);         } else if (requestCode == BluetoothState.REQUEST_ENABLE_BT) {             if (resultCode == Activity.RESULT_OK) {                 mBt.setupService();                 mBt.startService(BluetoothState.DEVICE_ANDROID);             } else {                 finish();             }         }     }     public void onStart() {         super.onStart();         if (!mBt.isBluetoothEnabled()) {             //打开蓝牙             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);             startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);         } else {             if (!mBt.isServiceAvailable()) {                 //开启监听                 mBt.setupService();                 mBt.startService(BluetoothState.DEVICE_ANDROID);             }         }     }     @Override     protected void onDestroy() {         super.onDestroy();         mBt.stopService();         releaseCamera();     }     private void releaseCamera() {         if (mCamera != null) {             mCamera.setPreviewCallback(null);             mCamera.setPreviewCallbackWithBuffer(null);             mCamera.stopPreview();// 停掉原来摄像头的预览             mCamera.release();             mCamera = null;         }     }     @Override     public void surfaceCreated(SurfaceHolder holder) {         try {             mCamera = Camera.open();             Camera.Parameters mPara = mCamera.getParameters();             List pictureSizes = mCamera.getParameters().getSupportedPictureSizes();             List previewSizes = mCamera.getParameters().getSupportedPreviewSizes();             int previewSizeIndex = -1;             Camera.Size psize;             int height_sm = 999999;             int width_sm = 999999;             //获取设备最小分辨率图片,图片越清晰,传输越卡             for (int i = 0; i < previewSizes.size(); i++) {                 psize = previewSizes.get(i);                 if (psize.height                          发射端主界面     public class MainActivity extends AppCompatActivity {     private BluetoothUtil mBt;     private ImageView mPhoto;     private ImageView mVideo;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         mBt = new BluetoothUtil(this);         initBlue();         initView();     }     private void initView() {         mPhoto = (ImageView) findViewById(R.id.photo);         mVideo = (ImageView) findViewById(R.id.video);     }     private void initBlue() {         if (!mBt.isBluetoothAvailable()) {             Toast.makeText(getApplicationContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();             finish();         }         mBt.setOnDataReceivedListener(new BluetoothUtil.OnDataReceivedListener() {             public void onDataReceived(byte[] data, String message) {                 if (message.equals("text") && data.length != 0) {                     String text = new String(data);                     Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();                 } else if (message.equals("photo") && data.length != 0) {                     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                     mPhoto.setImageBitmap(bitmap);                 } else if (message.equals("video") && data.length != 0) {                     mVideo.setImageBitmap(BitmapFactory.decodeByteArray(data, 0, data.length));                 }             }         });         mBt.setBluetoothConnectionListener(new BluetoothUtil.BluetoothConnectionListener() {             public void onDeviceConnected(String name, String address) {                 Toast.makeText(MainActivity.this,"蓝牙已连接",Toast.LENGTH_SHORT).show();             }             public void onDeviceDisconnected() {                 Toast.makeText(MainActivity.this,"蓝牙已断开",Toast.LENGTH_SHORT).show();             }             public void onDeviceConnectionFailed() {             }         });     }     public void Click(View view) {         if (mBt.getServiceState() == BluetoothState.STATE_CONNECTED) {             mBt.disconnect();         } else {             Intent intent = new Intent(getApplicationContext(), BluetoothActivity.class);             startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE);         }     }     @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         super.onActivityResult(requestCode, resultCode, data);         if (requestCode == BluetoothState.REQUEST_CONNECT_DEVICE) {             if (resultCode == Activity.RESULT_OK)                 mBt.connect(data);         } else if (requestCode == BluetoothState.REQUEST_ENABLE_BT) {             if (resultCode == Activity.RESULT_OK) {                 mBt.setupService();                 mBt.startService(BluetoothState.DEVICE_ANDROID);             } else {                 finish();             }         }     }     public void onStart() {         super.onStart();         if (!mBt.isBluetoothEnabled()) {             //打开蓝牙             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);             startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);         } else {             if (!mBt.isServiceAvailable()) {                 //开启监听                 mBt.setupService();                 mBt.startService(BluetoothState.DEVICE_ANDROID);             }         }     }     } #蓝牙列表界面好状态码的类和发射端的一样,就不帖了,下面是接收端的BluetoothUtil     public class BluetoothUtil {     private BluetoothStateListener mBluetoothStateListener = null;     private OnDataReceivedListener mDataReceivedListener = null;     private BluetoothConnectionListener mBluetoothConnectionListener = null;     private AutoConnectionListener mAutoConnectionListener = null;     private Context mContext;     private BluetoothAdapter mBluetoothAdapter = null;     private BluetoothService mChatService = null;     private String mDeviceName = null;     private String mDeviceAddress = null;     private boolean isAutoConnecting = false;     private boolean isAutoConnectionEnabled = false;     private boolean isConnected = false;     private boolean isConnecting = false;     private boolean isServiceRunning = false;     private String keyword = "";     private boolean isAndroid = BluetoothState.DEVICE_ANDROID;     private BluetoothConnectionListener bcl;     private int c = 0;     private static int headInfoLength = 10;     //获取蓝牙adapter     public BluetoothUtil(Context context) {         mContext = context;         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();     }     //判断蓝牙是否可用     public boolean isBluetoothEnable() {         return mBluetoothAdapter.isEnabled();     }     public interface BluetoothStateListener {         public void onServiceStateChanged(int state);     }     public interface OnDataReceivedListener {         public void onDataReceived(byte[] data, String message);     }     public interface BluetoothConnectionListener {         public void onDeviceConnected(String name, String address);         public void onDeviceDisconnected();         public void onDeviceConnectionFailed();     }     public interface AutoConnectionListener {         public void onAutoConnectionStarted();         public void onNewConnection(String name, String address);     }     public boolean isBluetoothAvailable() {         try {             if (mBluetoothAdapter == null || mBluetoothAdapter.getAddress().equals(null))                 return false;         } catch (NullPointerException e) {             return false;         }         return true;     }     public boolean isBluetoothEnabled() {         return mBluetoothAdapter.isEnabled();     }     public boolean isServiceAvailable() {         return mChatService != null;     }     public boolean isAutoConnecting() {         return isAutoConnecting;     }     public boolean startDiscovery() {         return mBluetoothAdapter.startDiscovery();     }     public boolean isDiscovery() {         return mBluetoothAdapter.isDiscovering();     }     public boolean cancelDiscovery() {         return mBluetoothAdapter.cancelDiscovery();     }     public void setupService() {         mChatService = new BluetoothService(mContext, mHandler);     }     public BluetoothAdapter getBluetoothAdapter() {         return mBluetoothAdapter;     }     public int getServiceState() {         if(mChatService != null)             return mChatService.getState();         else             return -1;     }     //开启蓝牙一直监听是否连接的状态     public void startService(boolean isAndroid) {         if (mChatService != null) {             if (mChatService.getState() == BluetoothState.STATE_NONE) {                 isServiceRunning = true;                 mChatService.start(isAndroid);                 BluetoothUtil.this.isAndroid = isAndroid;             }         }     }     public void stopService() {         if (mChatService != null) {             isServiceRunning = false;             mChatService.stop();         }         new Handler().postDelayed(new Runnable() {             public void run() {                 if (mChatService != null) {                     isServiceRunning = false;                     mChatService.stop();                 }             }         }, 500);     }     public void setDeviceTarget(boolean isAndroid) {         stopService();         startService(isAndroid);         BluetoothUtil.this.isAndroid = isAndroid;     }     @SuppressLint("HandlerLeak")     private final Handler mHandler = new Handler() {         public void handleMessage(Message msg) {             switch (msg.what) {                 case BluetoothState.MESSAGE_WRITE:                     break;                 case BluetoothState.MESSAGE_READ:                     String str = null;                     int arg1 = msg.arg1;                     if(arg1==0){                         str="text";                     }else if(arg1==1){                         str="photo";                     }else if(arg1==2){                         str="video";                     }                     byte[] readBuf = (byte[]) msg.obj; //                String readMessage = new String(readBuf);                     if(readBuf != null && readBuf.length > 0) {                         if(mDataReceivedListener != null)                             mDataReceivedListener.onDataReceived(readBuf, str);                     }                     break;                 case BluetoothState.MESSAGE_DEVICE_NAME:                     mDeviceName = msg.getData().getString(BluetoothState.DEVICE_NAME);                     mDeviceAddress = msg.getData().getString(BluetoothState.DEVICE_ADDRESS);                     if(mBluetoothConnectionListener != null)                         mBluetoothConnectionListener.onDeviceConnected(mDeviceName, mDeviceAddress);                     isConnected = true;                     break;                 case BluetoothState.MESSAGE_TOAST:                     Toast.makeText(mContext, msg.getData().getString(BluetoothState.TOAST)                             , Toast.LENGTH_SHORT).show();                     break;                 case BluetoothState.MESSAGE_STATE_CHANGE:                     if(mBluetoothStateListener != null)                         mBluetoothStateListener.onServiceStateChanged(msg.arg1);                     if(isConnected && msg.arg1 != BluetoothState.STATE_CONNECTED) {                         if(mBluetoothConnectionListener != null)                             mBluetoothConnectionListener.onDeviceDisconnected();                         if(isAutoConnectionEnabled) {                             isAutoConnectionEnabled = false;                             autoConnect(keyword);                         }                         isConnected = false;                         mDeviceName = null;                         mDeviceAddress = null;                     }                     if(!isConnecting && msg.arg1 == BluetoothState.STATE_CONNECTING) {                         isConnecting = true;                     } else if(isConnecting) {                         if(msg.arg1 != BluetoothState.STATE_CONNECTED) {                             if(mBluetoothConnectionListener != null)                                 mBluetoothConnectionListener.onDeviceConnectionFailed();                         }                         isConnecting = false;                     }                     break;             }         }     };     public static int ByteArrayToInt(byte b[]) throws Exception {         ByteArrayInputStream buf = new ByteArrayInputStream(b);         DataInputStream dis= new DataInputStream(buf);         return dis.readInt();     }     public static byte[] intToByteArray(int i) throws Exception {         ByteArrayOutputStream buf = new ByteArrayOutputStream();         DataOutputStream dos= new DataOutputStream(buf);         dos.writeInt(i);         byte[] b = buf.toByteArray();         dos.close();         buf.close();         return b;     }     public void stopAutoConnect() {         isAutoConnectionEnabled = false;     }     public BluetoothDevice connect(Intent data) {         String address = data.getExtras().getString(BluetoothState.EXTRA_DEVICE_ADDRESS);         BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);         mChatService.connect(device);         return device;     }     public void connect(String address) {         BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);         mChatService.connect(device);     }     public void disconnect() {         if(mChatService != null) {             isServiceRunning = false;             mChatService.stop();             if(mChatService.getState() == BluetoothState.STATE_NONE) {                 isServiceRunning = true;                 mChatService.start(BluetoothUtil.this.isAndroid);             }         }     }     public void setBluetoothStateListener (BluetoothStateListener listener) {         mBluetoothStateListener = listener;     }     public void setOnDataReceivedListener (OnDataReceivedListener listener) {         mDataReceivedListener = listener;     }     public void setBluetoothConnectionListener (BluetoothConnectionListener listener) {         mBluetoothConnectionListener = listener;     }     public void setAutoConnectionListener(AutoConnectionListener listener) {         mAutoConnectionListener = listener;     }     public void enable() {         mBluetoothAdapter.enable();     }     public void send(byte[] data, boolean CRLF) {         if(mChatService.getState() == BluetoothState.STATE_CONNECTED) {             if(CRLF) {                 byte[] data2 = new byte[data.length + 2];                 for(int i = 0 ; i < data.length ; i++)                     data2[i] = data[i];                 data2[data2.length - 2] = 0x0A;                 data2[data2.length - 1] = 0x0D;                 mChatService.write(data2);             } else {                 mChatService.write(data);             }         }     }     public void send(String data, boolean CRLF) {         if(mChatService.getState() == BluetoothState.STATE_CONNECTED) {             if(CRLF)                 data += "\r\n";             mChatService.write(data.getBytes());         }     }     public void send(byte[] data){         int length = data.length;         byte[] length_b = null;         try {             length_b= intToByteArray(length);         } catch (Exception e) {             e.printStackTrace();         }         if(length_b == null)return;         byte[] headerInfo = new byte[headInfoLength];         for (int i = 0; i < headInfoLength - 4; i++) {             headerInfo[i] = (byte) i;         }         for (int i = 0; i < 4; i++) {             headerInfo[6+i] = length_b[i];         }         byte[] sendMsg = new byte[length + headInfoLength];         for (int i = 0; i < sendMsg.length; i++) {             if(i < headInfoLength){                 sendMsg[i] = headerInfo[i];             }else{                 sendMsg[i] = data[i - headInfoLength];             }         }         mChatService.write(sendMsg);     }     public String getConnectedDeviceName() {         return mDeviceName;     }     public String getConnectedDeviceAddress() {         return mDeviceAddress;     }     public String[] getPairedDeviceName() {         int c = 0;         Set devices = mBluetoothAdapter.getBondedDevices();         String[] name_list = new String[devices.size()];         for(BluetoothDevice device : devices) {             name_list[c] = device.getName();             c++;         }         return name_list;     }     public String[] getPairedDeviceAddress() {         int c = 0;         Set devices = mBluetoothAdapter.getBondedDevices();         String[] address_list = new String[devices.size()];         for(BluetoothDevice device : devices) {             address_list[c] = device.getAddress();             c++;         }         return address_list;     }     public void autoConnect(String keywordName) {         if(!isAutoConnectionEnabled) {             keyword = keywordName;             isAutoConnectionEnabled = true;             isAutoConnecting = true;             if(mAutoConnectionListener != null)                 mAutoConnectionListener.onAutoConnectionStarted();             final ArrayList arr_filter_address = new ArrayList();             final ArrayList arr_filter_name = new ArrayList();             String[] arr_name = getPairedDeviceName();             String[] arr_address = getPairedDeviceAddress();             for(int i = 0 ; i < arr_name.length ; i++) {                 if(arr_name[i].contains(keywordName)) {                     arr_filter_address.add(arr_address[i]);                     arr_filter_name.add(arr_name[i]);                 }             }             bcl = new BluetoothConnectionListener() {                 public void onDeviceConnected(String name, String address) {                     bcl = null;                     isAutoConnecting = false;                 }                 public void onDeviceDisconnected() { }                 public void onDeviceConnectionFailed() {                     Log.e("CHeck", "Failed");                     if(isServiceRunning) {                         if(isAutoConnectionEnabled) {                             c++;                             if(c >= arr_filter_address.size())                                 c = 0;                             connect(arr_filter_address.get(c));                             Log.e("CHeck", "Connect");                             if(mAutoConnectionListener != null)                                 mAutoConnectionListener.onNewConnection(arr_filter_name.get(c)                                         , arr_filter_address.get(c));                         } else {                             bcl = null;                             isAutoConnecting = false;                         }                     }                 }             };             setBluetoothConnectionListener(bcl);             c = 0;             if(mAutoConnectionListener != null)                 mAutoConnectionListener.onNewConnection(arr_name[c], arr_address[c]);             if(arr_filter_address.size() > 0)                 connect(arr_filter_address.get(c));             else                 Toast.makeText(mContext, "Device name mismatch", Toast.LENGTH_SHORT).show();         }     }     } 接收端的BluetoothService,核心部分是ConnectedThread这个线程     public class BluetoothService {     private static final String TAG = "Bluetooth Service";     private static final String NAME_SECURE = "Bluetooth Secure";     private static final UUID UUID_ANDROID_DEVICE =             UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");     private static final UUID UUID_OTHER_DEVICE =             UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");     private final BluetoothAdapter mAdapter;     private final Handler mHandler;     private AcceptThread mSecureAcceptThread;     private ConnectThread mConnectThread;     private ConnectedThread mConnectedThread;     private int mState;     private boolean isAndroid = BluetoothState.DEVICE_ANDROID;     public BluetoothService(Context context, Handler handler) {         mAdapter = BluetoothAdapter.getDefaultAdapter();         mState = BluetoothState.STATE_NONE;         mHandler = handler;     }     private synchronized void setState(int state) {         Log.d(TAG, "setState() " + mState + " -> " + state);         mState = state;         mHandler.obtainMessage(BluetoothState.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();     }     public synchronized int getState() {         return mState;     }     //开启子线程     public synchronized void start(boolean isAndroid) {         // Cancel any thread attempting to make a connection         if (mConnectThread != null) {             mConnectThread.cancel();             mConnectThread = null;         }         if (mConnectedThread != null) {             mConnectedThread.cancel();             mConnectedThread = null;         }         setState(BluetoothState.STATE_LISTEN);         //开启子线程         if (mSecureAcceptThread == null) {             mSecureAcceptThread = new AcceptThread(isAndroid);             mSecureAcceptThread.start();             BluetoothService.this.isAndroid = isAndroid;         }     }     public synchronized void connect(BluetoothDevice device) {         // Cancel any thread attempting to make a connection         if (mState == BluetoothState.STATE_CONNECTING) {             if (mConnectThread != null) {                 mConnectThread.cancel();                 mConnectThread = null;             }         }         // Cancel any thread currently running a connection         if (mConnectedThread != null) {             mConnectedThread.cancel();             mConnectedThread = null;         }         // Start the thread to connect with the given device         mConnectThread = new ConnectThread(device);         mConnectThread.start();         setState(BluetoothState.STATE_CONNECTING);     }     /**      * Start the ConnectedThread to begin managing a Bluetooth connection      *      * @param socket The BluetoothSocket on which the connection was made      * @param device The BluetoothDevice that has been connected      */     public synchronized void connected(BluetoothSocket socket, BluetoothDevice             device, final String socketType) {         if (mConnectThread != null) {             mConnectThread.cancel();             mConnectThread = null;         }         if (mConnectedThread != null) {             mConnectedThread.cancel();             mConnectedThread = null;         }         if (mSecureAcceptThread != null) {             mSecureAcceptThread.cancel();             mSecureAcceptThread = null;         }         mConnectedThread = new ConnectedThread(socket, socketType);         mConnectedThread.start();         Message msg = mHandler.obtainMessage(BluetoothState.MESSAGE_DEVICE_NAME);         Bundle bundle = new Bundle();         bundle.putString(BluetoothState.DEVICE_NAME, device.getName());         bundle.putString(BluetoothState.DEVICE_ADDRESS, device.getAddress());         msg.setData(bundle);         mHandler.sendMessage(msg);         setState(BluetoothState.STATE_CONNECTED);     }     public synchronized void stop() {         if (mConnectThread != null) {             mConnectThread.cancel();             mConnectThread = null;         }         if (mConnectedThread != null) {             mConnectedThread.cancel();             mConnectedThread = null;         }         if (mSecureAcceptThread != null) {             mSecureAcceptThread.cancel();             mSecureAcceptThread.kill();             mSecureAcceptThread = null;         }         setState(BluetoothState.STATE_NONE);     }     public void write(byte[] out) {         ConnectedThread r;         synchronized (this) {             if (mState != BluetoothState.STATE_CONNECTED) return;             r = mConnectedThread;         }         r.write(out);     }     private void connectionFailed() {         BluetoothService.this.start(BluetoothService.this.isAndroid);     }     private void connectionLost() {         BluetoothService.this.start(BluetoothService.this.isAndroid);     }     //监听蓝牙连接的线程     private class AcceptThread extends Thread {         private BluetoothServerSocket mmServerSocket;         private String mSocketType;         boolean isRunning = true;         public AcceptThread(boolean isAndroid) {             BluetoothServerSocket tmp = null;             try {                 if (isAndroid)                     //获取蓝牙socket                     tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_ANDROID_DEVICE);                 else                     tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_OTHER_DEVICE);             } catch (IOException e) {             }             mmServerSocket = tmp;         }         public void run() {             setName("AcceptThread" + mSocketType);             BluetoothSocket socket = null;             //死循环监听蓝牙连接状态,首次今进入一定满足条件,蓝牙连上后,循环停止             while (mState != BluetoothState.STATE_CONNECTED && isRunning) {                 try {                     socket = mmServerSocket.accept();                 } catch (IOException e) {                     break;                 }                 if (socket != null) {                     synchronized (BluetoothService.this) {                         switch (mState) {                             case BluetoothState.STATE_LISTEN:                             case BluetoothState.STATE_CONNECTING:                                 connected(socket, socket.getRemoteDevice(),                                         mSocketType);                                 break;                             case BluetoothState.STATE_NONE:                             case BluetoothState.STATE_CONNECTED:                                 try {                                     socket.close();                                 } catch (IOException e) {                                 }                                 break;                         }                     }                 }             }         }         public void cancel() {             try {                 mmServerSocket.close();                 mmServerSocket = null;             } catch (IOException e) {             }         }         public void kill() {             isRunning = false;         }     }     private class ConnectThread extends Thread {         private final BluetoothSocket mmSocket;         private final BluetoothDevice mmDevice;         private String mSocketType;         public ConnectThread(BluetoothDevice device) {             mmDevice = device;             BluetoothSocket tmp = null;             try {                 if (BluetoothService.this.isAndroid)                     tmp = device.createRfcommSocketToServiceRecord(UUID_ANDROID_DEVICE);                 else                     tmp = device.createRfcommSocketToServiceRecord(UUID_OTHER_DEVICE);             } catch (IOException e) {             }             mmSocket = tmp;         }         public void run() {             mAdapter.cancelDiscovery();             try {                 mmSocket.connect();             } catch (IOException e) {                 try {                     mmSocket.close();                 } catch (IOException e2) {                 }                 connectionFailed();                 return;             }             synchronized (BluetoothService.this) {                 mConnectThread = null;             }             connected(mmSocket, mmDevice, mSocketType);         }         public void cancel() {             try {                 mmSocket.close();             } catch (IOException e) {             }         }     }     public static int ByteArrayToInt(byte b[]) throws Exception {         ByteArrayInputStream buf = new ByteArrayInputStream(b);         DataInputStream dis = new DataInputStream(buf);         return dis.readInt();     }     private class ConnectedThread extends Thread {         private final BluetoothSocket mmSocket;         private final InputStream mmInStream;``         private final OutputStream mmOutStream;         public ConnectedThread(BluetoothSocket socket, String socketType) {             mmSocket = socket;             InputStream tmpIn = null;             OutputStream tmpOut = null;             try {                 tmpIn = socket.getInputStream();                 tmpOut = socket.getOutputStream();             } catch (IOException e) {             }             mmInStream = tmpIn;             mmOutStream = tmpOut;         }         public void run() {             byte[] buffer;             ArrayList arr_byte = new ArrayList();             while (true) {                 try {                     boolean valid = true;                     //判断前六位是不是12345                     for (int i = 0; i < 6; i++) {                         int t = mmInStream.read();                         if (t != i) {                             valid = false;                             break;                         }                     }                     if (valid) {                         byte[] bufLength = new byte[4];                         for (int i = 0; i < 4; i++) {                             bufLength[i] = ((Integer) mmInStream.read()).byteValue();                         }                         int textCount = 0;                         int photoCount = 0;                         int videoCount = 0;                         for (int i = 0; i < 4; i++) {                             int read = mmInStream.read();                             if (read == 0) {                                 textCount++;                             } else if (read == 1) {                                 photoCount++;                             } else if (read == 2) {                                 videoCount++;                             }                         }                         int length = ByteArrayToInt(bufLength);                         buffer = new byte[length];                         for (int i = 0; i < length; i++) {                             buffer[i] = ((Integer) mmInStream.read()).byteValue();                         }                         Message msg = Message.obtain();                         msg.what = BluetoothState.MESSAGE_READ;                         msg.obj = buffer;                         if (textCount == 4) {                             msg.arg1 = 0;                             mHandler.sendMessage(msg);                         } else if (photoCount == 4) {                             msg.arg1 = 1;                             mHandler.sendMessage(msg);                         } else if (videoCount == 4) {                             msg.arg1 = 2;                             mHandler.sendMessage(msg);                         }                     }                 } catch (IOException e) {                     connectionLost();                     BluetoothService.this.start(BluetoothService.this.isAndroid);                     break;                 } catch (Exception e) {                     e.printStackTrace();                 }             }         }         public void write(byte[] buffer) {             try {/*                 byte[] buffer2 = new byte[buffer.length + 2];                 for(int i = 0 ; i < buffer.length ; i++)                      buffer2[i] = buffer[i];                 buffer2[buffer2.length - 2] = 0x0A;                 buffer2[buffer2.length - 1] = 0x0D;*/                 mmOutStream.write(buffer);             } catch (IOException e) {             }         }         public void cancel() {             try {                 mmSocket.close();             } catch (IOException e) {             }         }     }

  }

权限:

            



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3