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

本文介绍了一个简单的Android应用示例,该应用允许两台Android设备之间进行文件传输。通过输入目标设备的IP地址及端口号,用户可以选择并发送文件。文章提供了完整的代码实现。

这是一个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());
        } 
    }
}

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

 

 

 

 

转载于:https://www.cnblogs.com/zhujiabin/p/7139644.html

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 } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值