Android通過Bluetooth藍芽傳送手機照片檔案到Windows PC:Java實現
阿新 • • 發佈:2018-11-08
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輸出: