安卓通過藍牙與PC端互通數據

 以下代碼都是可以實際運行的代碼,包括文件上傳,數據上傳,數據下載,文件下載。需要使用的自行修修補補。

該代碼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<String> bluetoothDevices = new ArrayList<String>();
	// ListView組件
	private ListView lvDevices;
	// ListView的字符串數組適配器
	private ArrayAdapter<String> 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<String>(this,
				android.R.layout.simple_list_item_1, android.R.id.text1,
				bluetoothDevices);
		// 爲listView綁定適配器
		lvDevices.setAdapter(arrayAdapter);
		// 爲listView設置item點擊事件偵聽
		lvDevices.setOnItemClickListener(this);

		// 用Set集合保持已綁定的設備
		Set<BluetoothDevice> 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<File> getFile(List fileslist) {
		List<File> files = new ArrayList<File>();
		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<File> 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<File> filesList = new ArrayList<File>();
			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<Map>() {
					}.getType());
					String imei = (String) map.get("imei");
					String userid = (String) map.get("userid");
					Map tasks = downloadService.downLoadRenWu(imei, userid);
					String result = "&START&&" + gson.toJson(tasks) + "&&END&";
					dos.writeUTF(result);
				} else if (type.equals("INIT")) {  //初始化
					
					if(fileServive.down()){
						String result="初始化開始!";
						dos.writeUTF(result);
						// 獲取資源
						String url="D:\\tomcat\\webapps\\dcmis\\blueToothRes\\mobile_res.zip";
						File resource =  new File(url);
						dos.writeLong(resource.length());
						dos.flush();
						bin = new BufferedInputStream(new FileInputStream(resource));
						int len = -1;
						byte buf[] = new byte[2048];
						while ((len = bin.read(buf)) != -1) {
							dos.write(buf, 0, len);
							dos.flush();
						}
						System.out.println("資源傳輸成功:"+resource.length());
						result = dis.readUTF();
						System.out.println(result);
					}else{
						String result="初始化失敗!";
						dos.writeUTF(result);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (fos != null)
						fos.close();
					if (dis != null)
						dis.close();
					outputStream.close();
					inputStream.close();
					if (streamConn != null) {
						streamConn.close();
					}
					System.gc();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	/**
	 * 數據上傳
	 * 
	 * @param data
	 * @return
	 */
	public boolean uploadData(String data) {
		String[] datas = data.split("&&");
		Map map = new HashMap();
		Gson gson = new Gson();
		String myJson = gson.toJson(datas[1]);// 將gson轉化爲json
		map = gson.fromJson(datas[1], new TypeToken<Map>() {
		}.getType());

		List dataList = new ArrayList();
		dataList = (List) map.get("datasList");
		List<DataSet> dataSetList = new ArrayList<DataSet>();
		for (int j = 0; j < dataList.size(); j++) {
			String dataSetStr = (String) dataList.get(j);
			DataSet dataSet = gson.fromJson(dataSetStr, DataSet.class);
			dataSetList.add(dataSet);
		}
		String taskIds = (String) map.get("taskIds");
		String sheetidAndVersions = (String) map.get("sheetidAndVersion");
		Object flagStr = map.get("flag");

		boolean flag = false;
		if (flagStr.equals(true)) {
			flag = true;
		}
		Map msgMap = new HashMap();
		boolean uploagflag = uploadService.uploadTask(dataSetList, taskIds,sheetidAndVersions, flag);
		if (map.containsKey("filesinfo")) {
			List<Map<String, String>> filelist = (List<Map<String, String>>) map.get("filesinfo");
			uploadService.updaeFiles(filelist);
		}
		return flag;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章