code: public synchronized void sendFile(final File file, final String description)
              throws SmackException {
          checkTransferThread();
          if (file == null || !file.exists() || !file.canRead()) {
              throw new IllegalArgumentException("Could not read file");
          } else {
              setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
          }
  
          transferThread = new Thread(new Runnable() {
              @Override
              public void run() {
                  try {
                      outputStream = negotiateStream(file.getName(), file
                              .length(), description);
                  } catch (XMPPErrorException e) {
                      handleXMPPException(e);
                      return;
                  }
                  catch (Exception e) {
                      setException(e);
                  }
                  if (outputStream == null) {
                      return;
                  }
  
                  if (!updateStatus(Status.negotiated, Status.in_progress)) {
                      return;
                  }
  
                  InputStream inputStream = null;
                  try {
                      inputStream = new FileInputStream(file);
                      writeToStream(inputStream, outputStream);
                  } catch (FileNotFoundException e) {
                      setStatus(FileTransfer.Status.error);
                      setError(Error.bad_file);
                      setException(e);
                  } catch (IOException e) {
                      setStatus(FileTransfer.Status.error);
                      setException(e);
                  } finally {
                      CloseableUtil.maybeClose(inputStream, LOGGER);
                      CloseableUtil.maybeClose(outputStream, LOGGER);
                  }
                  updateStatus(Status.in_progress, FileTransfer.Status.complete);
                  }
  
          }, "File Transfer " + streamID);
          transferThread.start();
      }
docs: This method handles the stream negotiation process and transmits the file
  to the remote user. It returns immediately and the progress of the file
  transfer can be monitored through several methods:
  
  <UL>
  <LI>{@link FileTransfer#getStatus()}
  <LI>{@link FileTransfer#getProgress()}
  <LI>{@link FileTransfer#isDone()}
  </UL>
  
  @param file the file to transfer to the remote entity.
  @param description a description for the file to transfer.
  @throws SmackException
  If there is an error during the negotiation process or the
  sending of the file.