天天看點

(高效開發)Android手機間使用socket進行檔案互傳執行個體

說明

這是一個Android手機間檔案傳輸的例子,兩個手機同時裝上此app,然後輸入接收端的ip,選擇檔案,可以多選,點确定,就發送到另一個手機,一個簡單快捷檔案快傳執行個體。可以直接運用到項目中。

(高效開發)Android手機間使用socket進行檔案互傳執行個體
(高效開發)Android手機間使用socket進行檔案互傳執行個體

下面是檔案選擇器:

(高效開發)Android手機間使用socket進行檔案互傳執行個體

代碼

首先加入檔案選擇庫

這個庫的位址和用法在:https://github.com/spacecowboy/NoNonsense-FilePicker

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tvMsg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        android:textColor="#AAA" />

    <EditText
        android:id="@+id/txtIP"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvMsg"
        android:layout_centerVertical="true"
        android:contentDescription="目标IP位址"
        android:ems="10"
        android:text="192.168.1.100" />

    <EditText
        android:id="@+id/txtPort"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/txtIP"
        android:layout_below="@+id/txtIP"
        android:ems="10"
        android:text="9999" />

    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:layout_alignLeft="@+id/txtIP"
        android:layout_below="@+id/txtPort"
        android:clickable="false"
        android:editable="false"
        android:ems="10"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:gravity="center_vertical|left|top"
        android:inputType="textMultiLine"
        android:longClickable="false"
        android:scrollbarAlwaysDrawVerticalTrack="true"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:textSize="15dp" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/btnSend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/txtPort"
        android:layout_below="@+id/et"
        android:text="選擇檔案并發送" />

</RelativeLayout>
           

MainActivity.class

public class MainActivity extends AppCompatActivity {
    private static final int FILE_CODE = ;
    private TextView tvMsg;
    private EditText txtIP, txtPort, txtEt;
    private Button btnSend;
    private Handler handler;
    private SocketManager socketManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvMsg = (TextView)findViewById(R.id.tvMsg);
        txtIP = (EditText)findViewById(R.id.txtIP);
        txtPort = (EditText)findViewById(R.id.txtPort);
        txtEt = (EditText)findViewById(R.id.et);
        btnSend = (Button)findViewById(R.id.btnSend);
        btnSend.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this, FilePickerActivity.class);
                i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, true);
                i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false);
                i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE);
                i.putExtra(FilePickerActivity.EXTRA_START_PATH, Environment.getExternalStorageDirectory().getPath());

                startActivityForResult(i, FILE_CODE);
            }
        });
        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                switch(msg.what){
                    case :
                        SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
                        txtEt.append("\n[" + format.format(new Date()) + "]" + msg.obj.toString());
                        break;
                    case :
                        tvMsg.setText("本機IP:" + GetIpAddress() + " 監聽端口:" + msg.obj.toString());
                        break;
                    case :
                        Toast.makeText(getApplicationContext(), msg.obj.toString(), Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        };
        socketManager = new SocketManager(handler);
    }



    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == FILE_CODE && resultCode == Activity.RESULT_OK) {
            final String ipAddress = txtIP.getText().toString();
            final int port = Integer.parseInt(txtPort.getText().toString());
            if (data.getBooleanExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, true)) {
                // For JellyBean and above
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    ClipData clip = data.getClipData();
                    final ArrayList<String> fileNames = new ArrayList<>();
                    final ArrayList<String> paths = new ArrayList<>();
                    if (clip != null) {
                        for (int i = ; i < clip.getItemCount(); i++) {
                            Uri uri = clip.getItemAt(i).getUri();
                            paths.add(uri.getPath());
                            fileNames.add(uri.getLastPathSegment());
                        }
                        Message.obtain(handler, , "正在發送至" + ipAddress + ":" +  port).sendToTarget();
                        Thread sendThread = new Thread(new Runnable(){
                            @Override
                            public void run() {
                                socketManager.SendFile(fileNames, paths, ipAddress, port);
                            }
                        });
                        sendThread.start();
                    }
                } else {
                    final ArrayList<String> paths = data.getStringArrayListExtra
                            (FilePickerActivity.EXTRA_PATHS);
                    final ArrayList<String> fileNames = new ArrayList<>();
                    if (paths != null) {
                        for (String path: paths) {
                            Uri uri = Uri.parse(path);
                            paths.add(uri.getPath());
                            fileNames.add(uri.getLastPathSegment());
                            socketManager.SendFile(fileNames, paths, ipAddress, port);
                        }
                        Message.obtain(handler, , "正在發送至" + ipAddress + ":" +  port).sendToTarget();
                        Thread sendThread = new Thread(new Runnable(){
                            @Override
                            public void run() {
                                socketManager.SendFile(fileNames, paths, ipAddress, port);
                            }
                        });
                        sendThread.start();
                    }
                }

            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.exit();
    }
    public String GetIpAddress() {
        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int i = wifiInfo.getIpAddress();
        return (i & ) + "." +
                ((i >>  ) & ) + "." +
                ((i >>  ) & )+ "." +
                ((i >>  ) &  );
    }
}
           

SocketManager.class

public class SocketManager {
    private ServerSocket server;
    private Handler handler = null;
    public SocketManager(Handler handler){
        this.handler = handler;
        int port = ;
        while(port > ){
            try {
                server = new ServerSocket(port);
                break;
            } catch (Exception e) {
                port--;
            }
        }
        SendMessage(, port);
        Thread receiveFileThread = new Thread(new Runnable(){
            @Override
            public void run() {
                while(true){
                    ReceiveFile();
                }
            }
        });
        receiveFileThread.start();
    }
    void SendMessage(int what, Object obj){
        if (handler != null){
            Message.obtain(handler, what, obj).sendToTarget();
        }
    }

    void ReceiveFile(){
        try{

            Socket name = server.accept();
            InputStream nameStream = name.getInputStream();
            InputStreamReader streamReader = new InputStreamReader(nameStream);
            BufferedReader br = new BufferedReader(streamReader);
            String fileName = br.readLine();
            br.close();
            streamReader.close();
            nameStream.close();
            name.close();
            SendMessage(, "正在接收:" + fileName);

            Socket data = server.accept();
            InputStream dataStream = data.getInputStream();
            String savePath = Environment.getExternalStorageDirectory().getPath() + "/" + fileName;
            FileOutputStream file = new FileOutputStream(savePath, false);
            byte[] buffer = new byte[];
            int size = -;
            while ((size = dataStream.read(buffer)) != -){
                file.write(buffer,  ,size);
            }
            file.close();
            dataStream.close();
            data.close();
            SendMessage(, fileName + "接收完成");
        }catch(Exception e){
            SendMessage(, "接收錯誤:\n" + e.getMessage());
        }
    }
    public void SendFile(ArrayList<String> fileName, ArrayList<String> path, String ipAddress, int port){
        try {
            for (int i = ; i < fileName.size(); i++){
                Socket name = new Socket(ipAddress, port);
                OutputStream outputName = name.getOutputStream();
                OutputStreamWriter outputWriter = new OutputStreamWriter(outputName);
                BufferedWriter bwName = new BufferedWriter(outputWriter);
                bwName.write(fileName.get(i));
                bwName.close();
                outputWriter.close();
                outputName.close();
                name.close();
                SendMessage(, "正在發送" + fileName.get(i));

                Socket data = new Socket(ipAddress, port);
                OutputStream outputData = data.getOutputStream();
                FileInputStream fileInput = new FileInputStream(path.get(i));
                int size = -;
                byte[] buffer = new byte[];
                while((size = fileInput.read(buffer, , )) != -){
                    outputData.write(buffer, , size);
                }
                outputData.close();
                fileInput.close();
                data.close();
                SendMessage(, fileName.get(i) + "  發送完成");
            }
            SendMessage(, "所有檔案發送完成");
        } catch (Exception e) {
            SendMessage(, "發送錯誤:\n" + e.getMessage());
        } 
    }
}
           

以上就是全部代碼。

下載下傳位址:點這裡。