Android手机间使用socket进行文件互传实例

这是一个Android手机间文件传输的例子,两个手机同时装上此app,然后输入接收端的ip,选择文件,可以多选,点确定,就发送到另一个手机,一个简单快捷文件快传实例。可以直接运用到项目中。

下面是文件选择器: 

代码

首先加入文件选择库

 compile 'com.nononsenseapps:filepicker:2.5.2'

这个库的地址和用法在: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 = 0;
    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 0:
                        SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
                        txtEt.append("\n[" + format.format(new Date()) + "]" + msg.obj.toString());
                        break;
                    case 1:
                        tvMsg.setText("本机IP:" + GetIpAddress() + " 监听端口:" + msg.obj.toString());
                        break;
                    case 2:
                        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 = 0; i < clip.getItemCount(); i++) {
                            Uri uri = clip.getItemAt(i).getUri();
                            paths.add(uri.getPath());
                            fileNames.add(uri.getLastPathSegment());
                        }
                        Message.obtain(handler, 0, "正在发送至" + 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, 0, "正在发送至" + 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(0);
    }
    public String GetIpAddress() {
WifiManager wifiManager
= (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); int i = wifiInfo.getIpAddress(); return (i & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF)+ "." + ((i >> 24 ) & 0xFF ); } }

SocketManager.class

public class SocketManager {
    private ServerSocket server;
    private Handler handler = null;
    public SocketManager(Handler handler){
        this.handler = handler;
        int port = 9999;
        while(port > 9000){
            try {
                server = new ServerSocket(port);
                break;
            } catch (Exception e) {
                port--;
            }
        }
        SendMessage(1, 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(0, "正在接收:" + 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[1024];
            int size = -1;
            while ((size = dataStream.read(buffer)) != -1){
                file.write(buffer, 0 ,size);
            }
            file.close();
            dataStream.close();
            data.close();
            SendMessage(0, fileName + "接收完成");
        }catch(Exception e){
            SendMessage(0, "接收错误:\n" + e.getMessage());
        }
    }
    public void SendFile(ArrayList<String> fileName, ArrayList<String> path, String ipAddress, int port){
        try {
            for (int i = 0; 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(0, "正在发送" + fileName.get(i));

                Socket data = new Socket(ipAddress, port);
                OutputStream outputData = data.getOutputStream();
                FileInputStream fileInput = new FileInputStream(path.get(i));
                int size = -1;
                byte[] buffer = new byte[1024];
                while((size = fileInput.read(buffer, 0, 1024)) != -1){
                    outputData.write(buffer, 0, size);
                }
                outputData.close();
                fileInput.close();
                data.close();
                SendMessage(0, fileName.get(i) + "  发送完成");
            }
            SendMessage(0, "所有文件发送完成");
        } catch (Exception e) {
            SendMessage(0, "发送错误:\n" + e.getMessage());
        } 
    }
}

以上就是全部代码。 
下载地址:点这里

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NoNonsense-FilePicker有如下特点: 1.可扩展以适应不同的数据源。 2.支持多选。 3.可以选择目录或者是文件。 4.可以在选择器中新建目录。 NoNonsense-FilePicker不只是另外一个文件选择器而已 我需要的是这样一个文件选择器: 1.容易扩展,文件来源既可以是本地sdcard,也可以是来自云端的dropboxapi。 2.可以在选择器中创建目录。 本项目具备上述的两个要求,同时很好的适配了平板和手机两种UI效果。项目的核心是在一个abstract 类中,因此你可以很方便的继承以实现自己需要的选择器。 项目本身已经包含了一个能够选择本地sdcard文件的实现,但你完全可以扩展实现一个文件列表来源于云端的选择器,比如Dropbox, ftp,ssh等。 选择器是基于activity,在屏幕较小的设备上全屏显示,而在较大的屏幕上则显示成dialog的方式,这个特性是系统主题中做到的,因此为activity选择一个正确的主题至关重要。 使用说明: 该库的核心思想是做到可扩展,但是你只是想选择sdcard中的文件,只需阅读关于如何使用sdcard文件选择器就可以了。 首选需要加上文件访问权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 将选择器的app注册到AndroidManifest.xml <activity android:name="com.nononsenseapps.filepicker.FilePickerActivity" android:label="@string/app_name" android:theme="@style/FilePicker.Theme"> <intent-filter> <action android:name="android.intent.action.GET_CONTENT"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> 在java代码中调用选择器: // This always works Intent i = newIntent(context, FilePickerActivity.class); // This works if you defined the intent filter // Intent i = new Intent(Intent.ACTION_GET_CONTENT); // Set these depending on your use case. These are the defaults. i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false); i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false); i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE); startActivityForResult(i, FILE_CODE); 获取选择的返回值: @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == FILE_CODE && resultCode == Activity.RESULT_OK) { if(data.getBooleanExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false)) { // For JellyBean and above if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { ClipData clip = data.getClipData(); if(clip != null) { for(int i = 0; i < clip.getItemCount(); i++) { Uri uri = clip.getItemAt(i).getUri(); // Do something with the URI } } // For Ice Cream Sandwich } else{ ArrayList<String> paths = data.getStringArrayListExtra (FilePickerActivity.EXTRA_PATHS); if(paths != null) { for(String path: paths) { Uri uri = Uri.parse(path); // Do something with the URI } } } } else{ Uri uri = data.getData(); // Do something with the URI } } }
### 回答1: Android使用Socket进行图片互传实例可以按照以下步骤进行: 1. 在发送端(Client端)中,首先创建一个Socket对象,并指定服务器的IP地址和端口号。 2. 创建一个用于获取图片的输入流,并将图片数据读取到内存中。 3. 通过Socket的输出流将图片数据发送给服务器。 4. 在接收端(Server端)中,创建一个ServerSocket对象,并指定监听的端口号。 5. 循环等待客户端的连接请求,当有客户端连接时,接受到客户端的Socket对象。 6. 创建一个用于接收图片的输出流,将从客户端接收到的图片数据写入到指定文件中。 7. 当图片数据传输完成后,关闭Socket和ServerSocket对象。 具体的代码实现如下所示: 发送端: ```java try { // 创建客户端Socket,指定服务器IP地址和端口号 Socket clientSocket = new Socket("服务器IP地址", 端口号); // 获取图片文件的输入流 InputStream inputStream = new FileInputStream("图片文件路径"); // 创建Socket的输出流 OutputStream outputStream = clientSocket.getOutputStream(); // 定义一个字节数组用于保存图片数据 byte[] buffer = new byte[1024]; int len; // 从输入流中读取图片数据并发送给服务器 while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } // 关闭输入流、输出流和Socket连接 inputStream.close(); outputStream.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } ``` 接收端: ```java try { // 创建服务器端的ServerSocket,指定监听端口号 ServerSocket serverSocket = new ServerSocket(端口号); // 等待客户端的连接请求 Socket clientSocket = serverSocket.accept(); // 创建用于接收图片的输出流 OutputStream outputStream = new FileOutputStream("保存图片的路径"); // 获取客户端Socket的输入流 InputStream inputStream = clientSocket.getInputStream(); // 定义一个字节数组用于保存图片数据 byte[] buffer = new byte[1024]; int len; // 从输入流中读取图片数据并写入到文件中 while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } // 关闭输入流、输出流和Socket连接 inputStream.close(); outputStream.close(); clientSocket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } ``` 以上就是使用Socket进行Android图片互传的简单示例。你可以根据实际需求,在发送端和接收端的代码中做相应的修改和扩展。 ### 回答2: Android使用Socket进行图片互传是一种常见的网络通信方式。下面以客户端和服务器端的实例介绍其具体使用方法。 服务端: 1. 创建一个服务器端的Socket对象,并指定监听的端口号。 2. 使用ServerSocket的accept()方法监听客户端连接请求,并获取客户端的Socket对象。 3. 通过InputStream读取客户端发来的图片数据。 4. 将接收到的图片数据保存到本地。 客户端: 1. 创建一个客户端的Socket对象,并指定服务端的IP地址和端口号。 2. 使用OutputStream发送图片数据到服务器端。 3. 关闭Socket。 以上是一个简单的图片传输的示例,具体的实现过程中还可以增加异常处理和代码优化。另外,图片的传输还可以使用HTTP协议,通过在请求头中添加Content-Type字段来传输图片。在服务端,可以使用HTTP服务器框架如Spring Boot等来接收和处理请求,并将图片保存到本地。 总结:使用Socket进行图片互传是一种基于TCP/IP协议的通信方式,通过在服务端和客户端之建立Socket连接,并传输图片数据实现互传功能。在具体的实现过程中,要注意代码的健壮性和异常处理,以确保通信的稳定和准确。 ### 回答3: android使用socket进行图片互传实例的步骤如下: 1. 创建一个Socket服务器端和一个Socket客户端,通过TCP连接两者之通信。 2. 服务器端创建一个ServerSocket来监听客户端的连接请求。 3. 当客户端连接至服务器时,服务器端接受该连接并创建一个Socket对象。 4. 服务器端读取图片文件,并将其转换为字节数组。 5. 服务器端使用Socket的输出流将字节数组发送给客户端。 6. 客户端接收到服务器端发送的字节数组,将其转换为图片文件。 7. 客户端保存接收到的图片文件,并在界面上显示出来。 以下是一个简单的Android使用Socket进行图片互传的示例代码: 服务器端代码: ``` try { // 创建ServerSocket监听指定端口 ServerSocket serverSocket = new ServerSocket(8888); // 等待客户端连接 Socket socket = serverSocket.accept(); // 读取图片文件并转换为字节数组 File file = new File("/path/to/image.jpg"); FileInputStream fileInputStream = new FileInputStream(file); byte[] buffer = new byte[(int) file.length()]; fileInputStream.read(buffer); // 发送字节数组给客户端 OutputStream outputStream = socket.getOutputStream(); outputStream.write(buffer); // 关闭连接 outputStream.flush(); outputStream.close(); fileInputStream.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } ``` 客户端代码: ``` try { // 创建与服务器连接的Socket Socket socket = new Socket("服务器IP地址", 8888); // 读取字节数组并转换为图片文件 InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int bytesRead; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); while ((bytesRead = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, bytesRead); } byte[] imageBytes = byteArrayOutputStream.toByteArray(); // 将字节数组转换为图片文件并保存 Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); File file = new File("/path/to/save/image.jpg"); FileOutputStream fileOutputStream = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); // 关闭连接 fileOutputStream.close(); inputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } ``` 以上是一个基本的Android使用Socket进行图片互传的示例。通过服务器端将图片转换为字节数组并发送给客户端,客户端接收到字节数组后将其转换为图片文件并保存。具体实现可根据项目需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值