如何在安卓系统中通过WiFi直连模式找到传输的文件名?

8
你好,我的最终目标是在安卓设备之间使用wifi直连API传输文件。一台设备作为客户端,另一台设备作为服务器,就像wifi直连SDK演示中一样。为此,在客户端使用服务器端口和主机地址创建套接字。我想要传输多个文件。在接收端接受客户端套接字连接时,我必须创建一个文件,文件名与从客户端发送的文件名相同。但是我不知道服务器端的文件名。
那么,如何在此wifi直连传输模式中使用套接字连接发送文件名以进行多个文件传输呢? 在客户端使用服务器端口和主机地址创建套接字:
fileUris = intent.getExtras().getParcelableArrayList(EXTRA_STREAM);
        String host = intent.getExtras().getString(
                EXTRAS_GROUP_OWNER_ADDRESS);
        Socket socket = new Socket();
        int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);

        try {
            Log.d(WifiDirectActivity.TAG, "Opening client socket - ");
            socket.bind(null);
            socket.connect((new InetSocketAddress(host, port)),
                    SOCKET_TIMEOUT);

            Log.d(WifiDirectActivity.TAG,
                    "Client socket - " + socket.isConnected());
            OutputStream stream = socket.getOutputStream();
            ContentResolver cr = context.getContentResolver();
            InputStream is = null;
            for (int i = 0; i < fileUris.size(); i++) {
                Uri uri = fileUris.get(0);

                try {
                    is = cr.openInputStream(Uri.parse(uri.toString()));
                } catch (FileNotFoundException e) {
                    Log.d(WifiDirectActivity.TAG, e.toString());
                }
                DeviceDetailFragment.copyFile(is, stream);
                Log.d(WifiDirectActivity.TAG, "Client: Data written");
            }

接受来自服务器端的客户端套接字连接:

    ServerSocket serverSocket = new ServerSocket(8988);
            Log.d(WifiDirectActivity.TAG, "Server: Socket opened");
            Socket client = serverSocket.accept();

            Log.d(WifiDirectActivity.TAG,
                    "Server: connection done with client");

            final File f = new File(
                    Environment.getExternalStorageDirectory() + "/"
                            + context.getPackageName() + "/wifip2pshared-"
                            + "sample");
            File dirs = new File(f.getParent());
            if (!dirs.exists())
                dirs.mkdirs();
            f.createNewFile();

            Log.d(WifiDirectActivity.TAG,
                    "server: copying files " + f.toString());
            InputStream inputstream = client.getInputStream();                          

            copyFile(inputstream, new FileOutputStream(f));
            serverSocket.close();

在创建文件时,接收方非常关注文件名。有没有办法将文件名与文件一起发送呢? 请帮忙解决这个问题,谢谢。


如果我的方法符合您的需求,请标记它为被接受的答案,这样它也可以成为其他人的参考。谢谢。 - Sebastiano
1个回答

2
您可以创建一个捆绑对象,将文件名和实际数据嵌入其中。代码示例如下:

    public class WiFiDirectBundle extends Serializable {
        private String fileName;
        private String mimeType;
        private Long fileSize;
        private byte[] fileContent;

        public WiFiDirectBundle() {}

        // adds a file to the bundle, given its URI
        public void setFile(Uri uri) {
            File f = new File(Uri.parse(uri.toString()));

            fileName = f.getName();
            mimeType = MimeTypeMap.getFileExtensionFromUrl(f.getAbsolutePath());
            fileSize = f.length();

            FileInputStream fin = new FileInputStream(f);        
            fileContent = new byte[(int) f.length()];
            fin.read(fileContent);
        }

        // restores the file of the bundle, given its directory (change to whatever
        // fits you better)
        public String restoreFile(String baseDir) {
            File f = new File(baseDir + "/" + fileName);
            try {
                FileOutputStream fos = new FileOutputStream(f);
                if (fileContent != null) {
                    fos.write(fileContent);
                }

                fos.close();
                return f.getAbsolutePath();

            } catch (IOException e) {
                    e.printStackTrace();
            }

            return null;
        }

        public String getFileName() {
            return fileName;
        }

        public String getMimeType() {
            return mimeType;
        }

        public Long getFileSize() {
            return fileSize;
        }
    }

然后,您可以通过简单地使用输入和输出流来来回传递WiFiDirectBundle实例。当您接收到一个对象时,您必须显式地将其强制转换为WiFiDirectBundle类。

我知道这不太优雅,但它确实有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接