以下代码都是可以实际运行的代码,包括文件上传,数据上传,数据下载,文件下载。需要使用的自行修修补补。
该代码pc端是笔记本电脑,可以正常运行。台式机+蓝牙适配器,失败了。
需要的jar包:barcode.jar 、 bluecove-2.1.1-SNAPSHOT.jar
下载地址:jar包下载地址(积分自动设置5.....)
参考文章:https://blog.csdn.net/zhangphil/article/details/83146705
参考文章:https://blog.csdn.net/peceoqicka/article/details/51979469
1、安卓端代码
package com.sdjxd.power.bluetooth;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.google.gson.Gson;
import com.sdjxd.hussar.android.utils.PublicTools;
import com.sdjxd.power.binzhou.mobile.R;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
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.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
@SuppressLint("NewApi")
public class BlueTooth extends Activity implements OnItemClickListener {
ProgressDialog progressDialog;
// 获取到蓝牙适配器
private BluetoothAdapter mBluetoothAdapter;
// 用来保存搜索到的设备信息
private List bluetoothDevices = new ArrayList();
// ListView组件
private ListView lvDevices;
// ListView的字符串数组适配器
private ArrayAdapter arrayAdapter;
// UUID,蓝牙建立链接需要的
private final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
// 为其链接创建一个名称
private final String NAME = "Bluetooth_Socket";
// 选中发送数据的蓝牙设备,全局变量,否则连接在方法执行完就结束了
private BluetoothDevice selectDevice;
// 获取到选中设备的客户端串口,全局变量,否则连接在方法执行完就结束了
private BluetoothSocket clientSocket;
// 获取到向设备写的输出流,全局变量,否则连接在方法执行完就结束了
private OutputStream os;
private InputStream is;
Upload upload = new Upload();
int num = 0;
public String path;
Map dataMap=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
// 获取由上一个Activity传递过来的Intent对象
Intent intent = getIntent();
// 获取这个Intent对象的Extra中对应键的值
path = intent.getStringExtra("path");
// 获取到蓝牙默认的适配器
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 开启手机蓝牙设备
bluetoothAction();
// 获取到ListView组件
lvDevices = (ListView) findViewById(R.id.lvDevices);
// 为listview设置字符换数组适配器
arrayAdapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
bluetoothDevices);
// 为listView绑定适配器
lvDevices.setAdapter(arrayAdapter);
// 为listView设置item点击事件侦听
lvDevices.setOnItemClickListener(this);
// 用Set集合保持已绑定的设备
Set devices = mBluetoothAdapter.getBondedDevices();
if (devices.size() > 0) {
for (BluetoothDevice bluetoothDevice : devices) {
// 保存到arrayList集合中
bluetoothDevices.add(bluetoothDevice.getName() + ":"
+ bluetoothDevice.getAddress() + "\n");
}
}
// 因为蓝牙搜索到设备和完成搜索都是通过广播来告诉其他应用的
// 这里注册找到设备和完成搜索广播
IntentFilter filter = new IntentFilter(
BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
}
public void onClick_Search(View view) {
setTitle("正在扫描...");
// 点击搜索周边设备,如果正在搜索,则暂停搜索
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
}
// 注册广播接收者
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent intent) {
// 获取到广播的action
String action = intent.getAction();
// 判断广播是搜索到设备还是搜索完成
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
// 找到设备后获取其设备
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 判断这个设备是否是之前已经绑定过了,如果是则不需要添加,在程序初始化的时候已经添加了
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
// 设备没有绑定过,则将其保持到arrayList集合中
// 如果已将在列表中
if (bluetoothDevices.contains(device.getName() + ":"
+ device.getAddress() + "\n") == false) {
bluetoothDevices.add(device.getName() + ":"
+ device.getAddress() + "\n");
// 更新字符串数组适配器,将内容显示在listView中
arrayAdapter.notifyDataSetChanged();
}
}
} else if (action
.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
setTitle("搜索完成");
}
}
};
// 点击listView中的设备,传送数据
@Override
public void onItemClick(AdapterView> parent, View view, int position,
long id) {
// 获取到这个设备的信息
String s = arrayAdapter.getItem(position);
// 对其进行分割,获取到这个设备的地址
String address = s.substring(s.indexOf(":") + 1).trim();
// 判断当前是否还是正在搜索周边设备,如果是则暂停搜索
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
// 如果选择设备为空则代表还没有选择设备
if (selectDevice == null) {
// 通过地址获取到该设备
selectDevice = mBluetoothAdapter.getRemoteDevice(address);
}
clientSocket=null;
progressDialog = new ProgressDialog(BlueTooth.this);
progressDialog.setTitle("提示");
progressDialog.setMessage("任务上传中请稍等......");
progressDialog.setCancelable(false);
progressDialog.show();
dataMap = upload.uploadTask(path);
if (dataMap == null) {
progressDialog.dismiss();
PublicTools.ShowErrMsg("没有需要上传的任务!", this);
} else {
//新建线程
new Thread(){
@Override
public void run() {
sendFile(dataMap);
}}.start();
}
}
private Handler uploadHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
progressDialog.dismiss();
Looper.prepare();
PublicTools.ShowErrMsg(msg.obj.toString(), BlueTooth.this);
Looper.loop();
}
};
/**
* 蓝牙开始 查询手机是否支持蓝牙,如果支持的话,进行下一步。 查看蓝牙设备是否已打开,如果否则打开。
*/
public void bluetoothAction() {
// 查看手机是否有蓝牙设备功能
if (hasAdapter(mBluetoothAdapter)) {
if (!mBluetoothAdapter.isEnabled()) {
// 开启蓝牙功能
mBluetoothAdapter.enable();
}
} else {
// 程序终止
this.finish();
}
}
/**
* 查看手机是否有蓝牙设备功能
*
* @param ba
* 蓝牙设备适配器
* @return boolean
*/
public boolean hasAdapter(BluetoothAdapter ba) {
if (ba != null) {
return true;
}
PublicTools.ShowErrMsg("该手机没有蓝牙功能!", this);
return false;
}
public static List getFile(List fileslist) {
List files = new ArrayList();
for (int n = 0; n < fileslist.size(); n++) {
String fileurl = (String) fileslist.get(n);
File file = new File(fileurl);
if (file.length() > 0) {
files.add(file);
}
}
return files;
}
protected void sendFile(Map dataMap) {
String msg = "上传失败!";
long totalSize = 0;
byte buf[] = new byte[8192];
int len;
DataOutputStream dout = null;
DataInputStream doin = null;
BufferedInputStream din = null;
try {
try {
// 判断客户端接口是否为空
if (clientSocket == null) {
// 根据UUID创建通信套接字
// 获取到客户端接口
clientSocket = selectDevice
.createRfcommSocketToServiceRecord(MY_UUID);
// 向服务端发送连接
clientSocket.connect();
// 获取到输出流,向外写数据
os = clientSocket.getOutputStream();
}
if(!clientSocket.isConnected()){
// 向服务端发送连接
clientSocket.connect();
// 获取到输出流,向外写数据
os = clientSocket.getOutputStream();
}
} catch (Exception e) {
Message message = new Message();
message.obj="蓝牙连接失败!";
uploadHandler.handleMessage(message);
return;
}
String type = "UPLOADTASK";
if (dataMap.containsKey("filesList")) {
type = "File";
}
dout = new DataOutputStream(os);
// 传达类型
dout.writeUTF(type);
dout.flush();
// 传输数据
Gson gson = new Gson();
String json = gson.toJson(dataMap);
String data = "&START&&" + json + "&&END&";
dout.writeUTF(data);
dout.flush();
// 上传文件
if (dataMap.containsKey("filesList")) {
List fileslist = (List) dataMap.get("filesList");
List files = getFile(fileslist);
dout.writeInt(files.size());
for (int i = 0; i < files.size(); i++) {
dout.writeUTF(files.get(i).getName());
dout.flush();
dout.writeLong(files.get(i).length());
dout.flush();
totalSize += files.get(i).length();
}
dout.writeLong(totalSize);
for (int i = 0; i < files.size(); i++) {
din = new BufferedInputStream(new FileInputStream(
files.get(i)));
len = -1;
while ((len = din.read(buf)) != -1) {
dout.write(buf, 0, len);
}
}
}
// 读取返回值
is = clientSocket.getInputStream();
if (is != null) {
while (is.available() <= 0) {
Thread.currentThread().sleep(500);// 毫秒
is = clientSocket.getInputStream();
}
doin = new DataInputStream(is);
msg = doin.readUTF();
}
upload.updateStatus(msg);
Message message = new Message();
message.obj=msg;
uploadHandler.handleMessage(message);
} catch (Exception e) {
e.printStackTrace();
Message message = new Message();
message.obj="上传失败!";
uploadHandler.handleMessage(message);
} finally {
try {
if (din != null) {
din.close();
}
if (doin != null) {
doin.close();
}
if (dout != null) {
dout.close();
}
if (os != null) {
os.close();
}
if(clientSocket!=null){
clientSocket.close();
clientSocket=null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、pc端代码
package com.sdjxd.bluetooth;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sdjxd.hussar.mobile.base.AppConfig;
import com.sdjxd.hussar.mobile.base.bo.MobileResponseBo;
import com.sdjxd.hussar.mobile.offline.data.bo.DataSet;
import com.sdjxd.hussar.mobile.offline.data.services.DataSyncServices;
import com.sdjxd.power.mobile.service.DownloadService;
import com.sdjxd.bluetooth.NewUploadService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class BTServer implements Runnable {
// 流连接通知 用于创建流连接
private StreamConnectionNotifier myPCConnNotifier = null;
// 流连接
private StreamConnection streamConn = null;
// 接受数据字节流
private byte[] acceptedByteArray = new byte[12];
// 读取(输入)流
private InputStream inputStream = null;
// 输出流
private OutputStream outputStream = null;
NewUploadService uploadService = new NewUploadService();
NewDownloadService downloadService = new NewDownloadService();
private FileOutputStream fos;
DataInputStream dis;
DataOutputStream dos;
BufferedInputStream bin ;
static FileServive fileServive = new FileServive();
/**
* 主线程
*
* @param args
*/
public static void main(String[] args) {
new BTServer();
}
public static void openBluetooth() {
new BTServer();
}
/**
* 构造方法
*/
public BTServer() {
try {
// 得到流连接通知,下面的UUID必须和手机客户端的UUID相一致。
myPCConnNotifier = (StreamConnectionNotifier) Connector
.open("btspp://localhost:0000110100001000800000805F9B34FB");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 打开连接通道并读取流线程
new Thread(this).start();
}
public void run() {
// 持续保持着监听客户端的连接请求
while (true) {
String inSTR = "";
String data = "";
List filesList = new ArrayList();
try {
// 获取流连接
streamConn = myPCConnNotifier.acceptAndOpen();
// 获取流通道
inputStream = streamConn.openInputStream();
outputStream = streamConn.openOutputStream();
dis = new DataInputStream(inputStream);
dos = new DataOutputStream(outputStream);
bin = new BufferedInputStream(inputStream);
// 数据类型
String type = dis.readUTF();
System.out.println(type);
if (type.equals("File")) { //上传任务带附件
// 获取所有的数据
String dataAll = dis.readUTF();
System.out.println(dataAll);
// 上传数据
boolean flag = uploadData(dataAll);
// 上传文件
if (flag == true) {
try {
int fileNum = dis.readInt();
System.out.println("传输的文件总个数:" + fileNum);
String[] fileNames = new String[fileNum];
long[] fileSizes = new long[fileNum];
for (int i = 0; i < fileNum; i++) {
// 文件名
String fileName = dis.readUTF();
// 文件大小
long filesLength = dis.readLong();
fileNames[i] = fileName;
fileSizes[i] = filesLength;
System.out.println("文件名:" + fileNames[i]);
System.out.println("文件大小:" + fileSizes[i]);
}
long totalSize = dis.readLong();
System.out.println("文件总大小:" + totalSize);
for (int m = 0; m < fileNum; m++) {
String fileName = fileNames[m];
long filelen = fileSizes[m];
File directory = new File(
"D:\\tomcat\\webapps\\dcmis\\blueToothRes");
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory
.getAbsolutePath()
+ File.separatorChar + fileName);
fos = new FileOutputStream(file);
System.out.println("file。。。。。。。。。。。。。。" + file);
System.out.println("fileName。。。。。。。。。。。。。。"
+ fileName);
System.out.println("======== 开始接收文件 ========");
int longnum = Integer.parseInt(String
.valueOf(filelen));
byte[] bytes = new byte[2048];
byte[] b = null;
int length = -1;
System.out.println("文件长度:" + longnum);
while (longnum > 0
&& (length = dis
.read(
bytes,
0,
longnum < bytes.length ? (int) longnum
: bytes.length)) != -1) {
fos.write(bytes, 0, length);
fos.flush();
// 每读取后,picLeng的值要减去len个,直到picLeng = 0
longnum -= length;
}
System.out.println("======== 文件接收成功 ========");
filesList.add(file);
}
} catch (Exception e) {
dos.writeUTF("附件上传失败!");
}
} else {
dos.writeUTF("上传失败!");
}
} else if (type.equals("UPLOADTASK")) { //上传任务不带附件
// 获取所有的数据
String dataAll = dis.readUTF();
System.out.println(dataAll);
// 上传数据
boolean flag = uploadData(dataAll);
if (flag) {
dos.writeUTF("上传成功!");
} else {
dos.writeUTF("上传失败!");
}
} else if (type.equals("DOWNTASK")) { //下载任务
// 获取所有的数据
String dataAll = dis.readUTF();
System.out.println(dataAll);
String[] datas = dataAll.split("&&");
Map map = new HashMap();
Gson gson = new Gson();
map = gson.fromJson(datas[1], new TypeToken