Android通过Bluetooth蓝牙发送手机照片文件到Windows PC:Java实现

版权声明:本文为Zhang Phil原创文章,请不要转载! https://blog.csdn.net/zhangphil/article/details/83177275

Android通过Bluetooth蓝牙发送手机照片文件到Windows PC:Java实现

本文在《Android通过蓝牙发送数据到Windows PC电脑:Java实现(链接地址:https://blog.csdn.net/zhangphil/article/details/83146705 )》基础上改进代码,还是用Java实现把Android手机上的一张照片,通过Bluetooth蓝牙连接,发送到Windows PC电脑上,实现上仍区分为Windows电脑端的蓝牙服务器端BluetoothJavaServer:

import java.io.BufferedInputStream;
import java.io.FileOutputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;

/**
 * BluetoothJavaServer是蓝牙的服务器端。部署在Windows操作系统(PC电脑上)。 等待手机客户端或者其他蓝牙设备的连接。
 * 
 * @author fly
 *
 */
public class BluetoothJavaServer {
	// 蓝牙服务器端的UUID必须和手机端的UUID一致。
	// 手机端的UUID需要去掉中间的-分割符。
	private String MY_UUID = "0000110100001000800000805F9B34FB";

	public static void main(String[] args) {
		new BluetoothJavaServer();
	}

	public BluetoothJavaServer() {
		StreamConnectionNotifier mStreamConnectionNotifier = null;

		try {
			mStreamConnectionNotifier = (StreamConnectionNotifier) Connector.open("btspp://localhost:" + MY_UUID);
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			System.out.println("服务器端开始监听客户端连接请求...");
			while (true) {
				StreamConnection connection = mStreamConnectionNotifier.acceptAndOpen();
				System.out.println("接受客户端连接");

				new ClientThread(connection).start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 开启一个线程专门从与客户端蓝牙设备中读取文件数据,并把文件数据存储到本地。
	 * 
	 * @author fly
	 *
	 */
	private class ClientThread extends Thread {
		private StreamConnection mStreamConnection = null;

		public ClientThread(StreamConnection sc) {
			mStreamConnection = sc;
		}

		@Override
		public void run() {
			try {
				BufferedInputStream bis = new BufferedInputStream(mStreamConnection.openInputStream());

				// 本地创建一个image.jpg文件接收来自于手机客户端发来的图片文件数据。
				FileOutputStream fos = new FileOutputStream("image.jpg");

				int c = 0;
				byte[] buffer = new byte[1024];

				System.out.println("开始读数据...");
				while (true) {
					c = bis.read(buffer);
					if (c == -1) {
						System.out.println("读取数据结束");
						break;
					} else {
						fos.write(buffer, 0, c);
					}
				}

				fos.flush();

				fos.close();
				bis.close();
				mStreamConnection.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}


Android手机端的蓝牙客户端BluetoothClientActivity:

package zhangphil.test;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Set;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;

public class BluetoothClientActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;

    //要连接的目标蓝牙设备(Windows PC电脑的名字)。
    private final String TARGET_DEVICE_NAME = "PHIL-PC";

    private final String TAG = "蓝牙调试";

    //UUID必须是Android蓝牙客户端和Windows PC电脑端一致。
    private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";

    // 通过广播接收系统发送出来的蓝牙设备发现通知。
    private BroadcastReceiver mBroadcastReceiver = 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);

                String name = device.getName();
                if (name != null)
                    Log.d(TAG, "发现蓝牙设备:" + name);

                if (name != null && name.equals("PHIL-PC")) {
                    Log.d(TAG, "发现目标蓝牙设备,开始线程连接");
                    new Thread(new ClientThread(device)).start();

                    // 蓝牙搜索是非常消耗系统资源开销的过程,一旦发现了目标感兴趣的设备,可以关闭扫描。
                    mBluetoothAdapter.cancelDiscovery();
                }
            }
        }
    };

    /**
     * 该线程往蓝牙服务器端发送文件数据。
     */
    private class ClientThread extends Thread {
        private BluetoothDevice device;

        public ClientThread(BluetoothDevice device) {
            this.device = device;
        }

        @Override
        public void run() {
            BluetoothSocket socket;

            try {
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));

                Log.d(TAG, "连接蓝牙服务端...");
                socket.connect();
                Log.d(TAG, "连接建立.");

                // 开始往服务器端发送数据。
                Log.d(TAG, "开始往蓝牙服务器发送数据...");
                sendDataToServer(socket);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void sendDataToServer(BluetoothSocket socket) {
            try {
                FileInputStream fis = new FileInputStream(getFile());
                BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

                byte[] buffer = new byte[1024];
                int c;
                while (true) {
                    c = fis.read(buffer);
                    if (c == -1) {
                        Log.d(TAG, "读取结束");
                        break;
                    } else {
                        bos.write(buffer, 0, c);
                    }
                }

                bos.flush();

                fis.close();
                bos.close();

                Log.d(TAG, "发送文件成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发给给蓝牙服务器的文件。
     * 本例发送一张位于存储器根目录下名为 image.jpg 的照片。
     *
     * @return
     */
    private File getFile() {
        File root = Environment.getExternalStorageDirectory();
        File file = new File(root, "image.jpg");
        return file;
    }

    /**
     * 获得和当前Android蓝牙已经配对的蓝牙设备。
     *
     * @return
     */
    private BluetoothDevice getPairedDevices() {
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        if (pairedDevices != null && pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                // 把已经取得配对的蓝牙设备名字和地址打印出来。
                Log.d(TAG, device.getName() + " : " + device.getAddress());

                //如果已经发现目标蓝牙设备和Android蓝牙已经配对,则直接返回。
                if (TextUtils.equals(TARGET_DEVICE_NAME, device.getName())) {
                    Log.d(TAG, "已配对目标设备 -> " + TARGET_DEVICE_NAME);
                    return device;
                }
            }
        }

        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = getPairedDevices();
        if (device == null) {
            // 注册广播接收器。
            // 接收系统发送的蓝牙发现通知事件。
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            registerReceiver(mBroadcastReceiver, filter);

            if (mBluetoothAdapter.startDiscovery()) {
                Log.d(TAG, "搜索蓝牙设备...");
            }
        } else {
            new ClientThread(device).start();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mBroadcastReceiver);
    }
}


本例出于简单演示功能的目的,省去了Android客户端选择文件的代码实现,事先作为测试文件,先在Android手机的存储器根目录放置一张名为image.jpg的图片。
务必保证Windows电脑和Android手机上的蓝牙均处于打开状态。然后先启动服务器端程序,再启动Android手机客户端程序。
Windows电脑端输出:


Android studio的logcat输出:

猜你喜欢

转载自blog.csdn.net/zhangphil/article/details/83177275
今日推荐