通过 Wifi Direct 传输文件

Posted

技术标签:

【中文标题】通过 Wifi Direct 传输文件【英文标题】:file transfer through Wifi Direct 【发布时间】:2017-11-16 09:30:19 【问题描述】:

我正在尝试编写一个 android 应用程序,该应用程序将从第一台设备拍摄的图像通过摄像头传输到具有 WiFi Direct 的第二台设备。

我正在尝试使用这个 GitHub 项目,WiFiDIrectDemo,我设法连接了设备并只发送了一个文件。 当我尝试发送第二个文件时,我没有收到任何错误,并且从日志中,一切似乎都正常,但第二个设备没有收到任何文件。

这是一个已知问题吗?我试图在互联网上查找,但找不到任何可以帮助我的东西。

我正在附加我的文件传输服务类:

public class FileTransferService extends IntentService 

Handler mHandler;

public static final int SOCKET_TIMEOUT = 50000; //ms
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";

public static  int PORT = 8888;
public static final String inetaddress = "inetaddress";
public static final int ByteSize = 512;
public static final String Extension = "extension";
public static final String Filelength = "filelength";
public FileTransferService(String name) 
    super(name);


public FileTransferService() 
    super("FileTransferService");


@Override
public void onCreate() 
    // TODO Auto-generated method stub
    super.onCreate();
    mHandler = new Handler();


@Override
protected void onHandleIntent(Intent intent) 

    Context context = getApplicationContext();
    if (intent.getAction().equals(ACTION_SEND_FILE)) 
        String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);

        String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);

        Socket socket = new Socket();

        InputStream is = null;

        int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);

        String extension = intent.getExtras().getString(Extension);

        String filelength = intent.getExtras().getString(Filelength);


        try 
            if(!socket.isConnected())
            
                Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
                socket.bind(null);

                socket.setReuseAddress(true);

                socket.connect((new InetSocketAddress(host, port)),5000); // ..,socket_timeout)
                Log.e("File Transfer Service"," socket connect");

            

            Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());

            OutputStream stream = socket.getOutputStream();
            Log.e("file transfer" +
                    " service", "get output stream");
            ContentResolver cr = context.getContentResolver();


            Long FileLength = Long.parseLong(filelength);
            WiFiTransferModal transObj = null;
            ObjectOutputStream oos = new ObjectOutputStream(stream);
            if(transObj == null) transObj = new WiFiTransferModal();


            transObj = new WiFiTransferModal(extension,FileLength);
            oos.writeObject(transObj);

            try 
                is = cr.openInputStream(Uri.parse(fileUri));
             catch (FileNotFoundException e) 
                Log.d(WiFiDirectActivity.TAG, e.toString());
            
            DeviceDetailFragment.copyFile(is, stream);
            Log.d(WiFiDirectActivity.TAG, "Client: Data written");
            oos.flush();
            oos.close();    //close the ObjectOutputStream after sending data.
         catch (IOException e) 
            Log.e("file transfer service","unable to connect:  " + e.toString() );
         finally 
            if (socket != null) 
                if (socket.isConnected()) 
                    try 
                        socket.close();

                     catch (Exception e) 
                        // Give up
                        e.printStackTrace();
                        Log.e("File transfer service","exception socket.close:  " + e.toString());
                    
                
            
            else Log.e("file transfer service","socket is already null");
        

    


编辑

接收代码:

 public class FileServerAsyncTask extends AsyncTask<String, String, String> 

    //        private TextView statusText;
    private Context mFilecontext;
    private String Extension, Key;
    private File EncryptedFile;
    private long ReceivedFileLength;
    private int PORT;

    public FileServerAsyncTask(Context context, int port) 
        this.mFilecontext = context;
        handler = new Handler();
        this.PORT = port;

    


    @Override
    protected String doInBackground(String... params) 
        try 
            Log.e("device detail fragment", "File Async task port-> " + PORT);

            ServerSocket serverSocket = new ServerSocket();
            Log.e("device detail fragment"," new server");

            serverSocket.setReuseAddress(true);
            Log.e("device detail fragment","set reuse address");

            serverSocket.bind(new InetSocketAddress(PORT));
            Log.e("device detail fragment","socket bind");

            Socket client = serverSocket.accept();
            Log.e("device detail fragment "," socket client accept");

            Log.e("Device detail fragment ", "client inet address" + client.getInetAddress());

            WiFiClientIp = client.getInetAddress().getHostAddress();
            Log.e("device detail fragment"," get client ip: " + WiFiClientIp);

            ObjectInputStream ois = new ObjectInputStream(
                    client.getInputStream());
            Log.e("device detail fragment","object input stream + " + ois.toString());

            WiFiTransferModal obj = null;
            String InetAddress;

            try 
                obj = (WiFiTransferModal) ois.readObject();
                Log.e("device detail fragment"," read object");

                if (obj != null) 
                    Log.e("device detail fragment"," obj != null ");
                    InetAddress = obj.getInetAddress();
                    Log.e("device detail fragment"," get inet address: " +
                    InetAddress);
                    if (InetAddress != null
                            && InetAddress
                            .equalsIgnoreCase(FileTransferService.inetaddress)) 

                        SharedPreferencesHandler.setStringValues(mFilecontext,
                                mFilecontext.getString(R.string.pref_WiFiClientIp), WiFiClientIp);


                        //set boolean true which identify that this device will act as server.
                        SharedPreferencesHandler.setStringValues(mFilecontext,
                                mFilecontext.getString(R.string.pref_ServerBoolean), "true");

                        ois.close(); // close the ObjectOutputStream object
                        Log.e("device detail fragment"," output stream close");
                        // after saving
                        serverSocket.close();
                        Log.e("device detail fragment","close");
                        return "Demo";
                    

                    Log.e("device detail fragment","FileName got from socket on other side->>> "+
                            obj.getFileName());
                

                final File f = new File(
                        Environment.getExternalStorageDirectory() + "/"
                                + FolderName + "/"
                                + obj.getFileName());
                Log.e("background"," new file f from inputstream");

                File dirs = new File(f.getParent());
                Log.e("device detail fragment"," f get parent()");
                if (!dirs.exists())
                    dirs.mkdirs();
                f.createNewFile();
                Log.e("device detail fragment","create new file");

            /**
             * Receive file length and copy after it
             */
                this.ReceivedFileLength = obj.getFileLength();

                InputStream inputstream = client.getInputStream();
                Log.e("device detail fragment","input stream client get input");
                Message msg = Message.obtain();
                msg.what = 1;
                try
                
                    // send the images to the image view through handler
                    Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
                    Log.e("device detail fragment", "decode stream");
                    Bundle b = new Bundle();
                    b.putParcelable("bitmap", bitmap);
                    msg.setData(b);
                    Log.e("device detail fragment","message: " + msg.toString());
                    messageHandler.sendMessage(msg);
                
                catch (Exception e)
                
                    Log.e("device detail fragment","stream not decoded into bitmap with" +
                    "exception:   " + e.toString());
                

                copyRecievedFile(inputstream, new FileOutputStream(f),
                        ReceivedFileLength);
                Log.e("device detail fragment","copy input stream into file");
                ois.close(); // close the ObjectOutputStream object after saving
                // file to storage.
                Log.e("device detail fragment","ois close");

                /**
                 *  Set file related data and decrypt file in postExecute.
                 *  */
                this.Extension = obj.getFileName();
                this.EncryptedFile = f;
                final Uri uri = Uri.fromFile(f);
                return f.getAbsolutePath();
            
            catch (ClassNotFoundException e) 
                e.printStackTrace();
            
            catch (Exception e) 
                e.printStackTrace();
                Log.e("device detail fragment", e.getMessage());
            

            return "";
         catch (IOException e) 
            Log.e("device detail fragment", e.getMessage());
            return null;
        
    


    @Override
    protected void onPostExecute(String result) 

        if (result != null) 
            if (!result.equalsIgnoreCase("Demo")) 
                Log.e("On Post Execute","result  +" + result);
             else if (!TextUtils.isEmpty(result)) 
                /**
                 * To initiate socket again we are initiating async task
                 * in this condition.
                 */
                FileServerAsyncTask FileServerobj = new
                        FileServerAsyncTask(mFilecontext, FileTransferService.PORT);
                if (FileServerobj != null) 
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
                        FileServerobj.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]null);
                        Log.e("Post Execute", "FileServerobj.execute on executor");

                     else
                        
                            FileServerobj.execute();
                            Log.e("Post Execute", "FileServerobj.execute");
                        
                
            
        

    

    @Override
    protected void onPreExecute() 
        if (mProgressDialog == null) 
            mProgressDialog = new ProgressDialog(mFilecontext);
        
        if(imageView == null)
            imageView = new ImageView(mFilecontext);
        
    

【问题讨论】:

您发布的代码中有很多我不明白的地方。但是如果接收方没有收到第二个文件,那么在接收方看到你使用的代码也不错。 感谢您的回答,很抱歉我没有写一个完整的问题。我将编辑问题并将接收方也放入。 只发布服务器异步任务。不是完整的活动或片段。 服务器将接收一个文件,然后通过让用户选择一个应用程序来显示该文件来打开它。你能证实这一点吗?然后服务器异步任务完成。因此无法接收到新文件。因此,如果您说日志表明一切正常,我不相信您。您的客户端套接字无法连接。一切都是有目的的行为。 一开始服务器收到一个文件,然后用另一个函数打开它,我已经更改了代码,现在,接收到的应该是图像的文件被处理为图像视图.您是在建议我以错误的方式使用此任务?所以我应该修改它,使它不会结束连接和结束? 【参考方案1】:

服务器将接收一个文件,然后通过让用户选择一个应用程序来显示该文件来打开它。然后服务器异步任务完成。因此无法接收到新文件。因此,如果您说日志表明一切正常,我不相信您。您的客户端套接字无法连接。一切都是有目的的行为。

* To initiate socket again we are initiating async task * in this condition.. 

您的代码没有出现。

您必须再次启动异步任务才能接收下一个文件。

【讨论】:

再次感谢,我将修改代码并寻找解决方案:) 得到它我会尽快发布它 很简单:再次启动异步任务并显示文件。

以上是关于通过 Wifi Direct 传输文件的主要内容,如果未能解决你的问题,请参考以下文章

通过 wifi 传输数据

通过 Wi-Fi Direct 传输文件时是不是可以使用移动数据?

使用 WiFi Direct 或 Air/AS3 中的热点连接应用程序

如何在android中获取通过wifi直接传输的文件的文件名?

WIFI-Direct(Wifi直连)AirPlayDLANMiracast功能介绍

Wifi Direct 科尔多瓦