通过 Wifi Direct 传输文件

file transfer through Wifi Direct

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

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

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

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

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);
        }
    }
}

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

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

你的代码不会出现在那里。

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