首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 文件傳輸:手機與 PC 之間透過 USB 傳輸檔案的方法

     編輯:程式設計綜合問答

需求場景

在 Android 應用中實現「一鍵 USB 傳輸」功能,將手機儲存檔案同步至電腦。主要有兩種實現路徑:ADB 指令與 Socket 通訊。

方案一:ADB 指令 (適合開發/測試環境)

// 在應用中執行 ADB 指令 (需 USB 偵錯模式、電腦授權)
String command = "adb pull /sdcard/DCIM/photo.jpg D:/Backup/";
try {
    Process process = Runtime.getRuntime().exec(command);
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        Log.d("ADB", line);
    }
    process.waitFor();
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

限制:需電腦安裝 ADB、手機開啟 USB 偵錯、用戶授權,不適合一般消費者應用。

方案二:Socket 通訊 (適合產品級應用)

架構設計

  • 手機端 (Server):開啟 ServerSocket 監聽連線
  • 電腦端 (Client):連線手機 IP:Port,請求檔案清單與下載
  • 通訊協定:自訂簡單協定 (JSON/Protobuf) 傳輸檔案元資料與二進位資料

手機端 Server 實現

public class FileTransferServer extends Thread {
    private ServerSocket serverSocket;
    private boolean running = true;
    
    @Override public void run() {
        try {
            serverSocket = new ServerSocket(8888);
            while (running) {
                Socket client = serverSocket.accept();
                new Thread(() -> handleClient(client)).start();
            }
        } catch (IOException e) { e.printStackTrace(); }
    }
    
    private void handleClient(Socket socket) {
        try (DataInputStream in = new DataInputStream(socket.getInputStream());
             DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
            
            String cmd = in.readUTF(); // 如 "LIST" 或 "GET filename"
            if ("LIST".equals(cmd)) {
                sendFileList(out);
            } else if (cmd.startsWith("GET ")) {
                String filename = cmd.substring(4);
                sendFile(out, new File(Environment.getExternalStorageDirectory(), filename));
            }
        } catch (IOException e) { e.printStackTrace(); }
    }
    
    private void sendFileList(DataOutputStream out) throws IOException {
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
        File[] files = dir.listFiles();
        out.writeInt(files.length);
        for (File f : files) {
            out.writeUTF(f.getName());
            out.writeLong(f.length());
            out.writeLong(f.lastModified());
        }
    }
    
    private void sendFile(DataOutputStream out, File file) throws IOException {
        out.writeUTF("FILE_START");
        out.writeLong(file.length());
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[8192];
            int len;
            while ((len = fis.read(buffer)) > 0) out.write(buffer, 0, len);
        }
        out.writeUTF("FILE_END");
    }
}

電腦端 Client 簡易實現 (Java)

public class FileTransferClient {
    public static void main(String[] args) {
        try (Socket socket = new Socket("192.168.1.100", 8888);
             DataInputStream in = new DataInputStream(socket.getInputStream());
             DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
            
            out.writeUTF("LIST");
            out.flush();
            
            int count = in.readInt();
            for (int i = 0; i < count; i++) {
                String name = in.readUTF();
                long size = in.readLong();
                long modified = in.readLong();
                System.out.printf("%s (%d bytes)%n", name, size);
            }
            
            // 下載特定檔案
            out.writeUTF("GET photo.jpg");
            out.flush();
            
            String status = in.readUTF();
            if ("FILE_START".equals(status)) {
                long size = in.readLong();
                try (FileOutputStream fos = new FileOutputStream("download/photo.jpg")) {
                    byte[] buffer = new byte[8192];
                    long received = 0;
                    while (received < size) {
                        int len = in.read(buffer, 0, (int) Math.min(buffer.length, size - received));
                        fos.write(buffer, 0, len);
                        received += len;
                    }
                }
            }
        } catch (IOException e) { e.printStackTrace(); }
    }
}

關鍵技術點

  1. 端口轉發:手機熱點或 USB 連線時,電腦可透過 adb forward tcp:8888 tcp:8888 映射端口
  2. 權限:需 INTERNET、READ_EXTERNAL_STORAGE 權限
  3. 斷點續傳:支援 Range 請求,傳輸大檔案更可靠
  4. 加密傳輸:生產環境建議使用 TLS/SSL 加密 Socket

替代方案

  • MTP/PTP 協定:系統級檔案傳輸,需實現 MTP Server (複雜)
  • WebDAV / FTP Server:手機開啟 FTP/WebDAV 服務,電腦用瀏覽器/客戶端存取
  • 近場通訊:Android Beam / Nearby Share (現代替代方案)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved