title: How to print a text file using WiFi Direct
body: <p>I have a working Android app that displays user stats. I want to send a small report with plain text format (.txt) to a WiFi  Direct printer. I have downloaded the sample <a href="https://developer.android.com/guide/topics/connectivity/wifip2p.html" rel="noreferrer">demo</a> app from Android. I did the proper modification in order to look for .txt file. But I don't understand why my code is not working. After selecting the file I want to print, nothing happens.</p>
  
  <p><strong>The current configuration for my EPSON printer bellow.</strong></p>
  
  <ul>
  <li><p></p>
  
  <p>Wi-Fi Direct Mode : On </p></li>
  <li><p>Communication Mode: AP</p></li>
  <li><p>Operation    Mode: IEEE802.11g/n</p></li>
  <li><p>Communication Speed: Auto</p></li>
  <li>SSID: DIRECT-D3A36C54</li>
  <li>Channel: 7</li>
  <li><p>Security Level: WPA2-PSK(AES)</p></li>
  <li><p>Link Status: Unknown</p></li>
  </ul>
  
  <p><strong>This is the DeviceDetailFragment class</strong></p>
  
  <pre><code>public class DeviceDetailFragment extends Fragment implements WifiP2pManager.ConnectionInfoListener {
      protected static final int CHOOSE_FILE_RESULT_CODE = 20;
      private View mContentView = null;
      private WifiP2pDevice device;
      private WifiP2pInfo info;
      ProgressDialog progressDialog = null;
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
      }
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          mContentView = inflater.inflate(R.layout.device_detail, null);
          mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  WifiP2pConfig config = new WifiP2pConfig();
                  config.deviceAddress = device.deviceAddress;
                  config.wps.setup = WpsInfo.LABEL;
                  config.wps.pin = "12345677";
  //                config.groupOwnerIntent = 15;
                  if (progressDialog != null &amp;&amp; progressDialog.isShowing()) {
                      progressDialog.dismiss();
                  }
                  progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
                          "Connecting to :" + device.deviceAddress, true, true
  //                        new DialogInterface.OnCancelListener() {
  //
  //                            @Override
  //                            public void onCancel(DialogInterface dialog) {
  //                                ((DeviceActionListener) getActivity()).cancelDisconnect();
  //                            }
  //                        }
                  );
                  ((DeviceListFragment.DeviceActionListener) getActivity()).connect(config);
              }
          });
          mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          ((DeviceListFragment.DeviceActionListener) getActivity()).disconnect();
                      }
                  });
          mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          // Allow user to pick a text file from storage or other
                          // registered apps
                          Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                          intent.setType("text/*");
  //                        intent.setType("image/*");
                          startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
                      }
                  });
          return mContentView;
      }
      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
          // User has picked a text file. Transfer it to group owner i.e peer using
          // FileTransferService.
          Uri uri = data.getData();
          TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
          statusText.setText("Sending: " + uri);
          Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
          Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
          serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
          serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
          serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
                  info.groupOwnerAddress.getHostAddress());
          serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8315); //631
          getActivity().startService(serviceIntent);
      }
      @Override
      public void onConnectionInfoAvailable(final WifiP2pInfo info) {
          if (progressDialog != null &amp;&amp; progressDialog.isShowing()) {
              progressDialog.dismiss();
          }
          this.info = info;
          this.getView().setVisibility(View.VISIBLE);
          // The owner IP is now known.
          TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
          view.setText(getResources().getString(R.string.group_owner_text)
                  + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
                  : getResources().getString(R.string.no)));
          // InetAddress from WifiP2pInfo struct.
          view = (TextView) mContentView.findViewById(R.id.device_info);
          view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
          // After the group negotiation, we assign the group owner as the file
          // server. The file server is single threaded, single connection server
          // socket.
          if (info.groupFormed &amp;&amp; info.isGroupOwner) {
              new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
                      .execute();
          } else if (info.groupFormed) {
              // The other device acts as the client. In this case, we enable the
              // get file button.
              mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
              ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
                      .getString(R.string.client_text));
          }
          // hide the connect button
          mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
      }
      /**
       * Updates the UI with device data
       *
       * @param device the device to be displayed
       */
      public void showDetails(WifiP2pDevice device) {
          this.device = device;
          this.getView().setVisibility(View.VISIBLE);
          TextView view = (TextView) mContentView.findViewById(R.id.device_address);
          view.setText(device.deviceAddress);
          view = (TextView) mContentView.findViewById(R.id.device_info);
          view.setText(device.toString());
      }
      /**
       * Clears the UI fields after a disconnect or direct mode disable operation.
       */
      public void resetViews() {
          mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
          TextView view = (TextView) mContentView.findViewById(R.id.device_address);
          view.setText(R.string.empty);
          view = (TextView) mContentView.findViewById(R.id.device_info);
          view.setText(R.string.empty);
          view = (TextView) mContentView.findViewById(R.id.group_owner);
          view.setText(R.string.empty);
          view = (TextView) mContentView.findViewById(R.id.status_text);
          view.setText(R.string.empty);
          mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
          this.getView().setVisibility(View.GONE);
      }
      /**
       * A simple server socket that accepts connection and writes some data on
       * the stream.
       */
      public static class FileServerAsyncTask extends AsyncTask&lt;Void, Void, String&gt; {
          private Context context;
          private TextView statusText;
          /**
           * @param context
           * @param statusText
           */
          public FileServerAsyncTask(Context context, View statusText) {
              this.context = context;
              this.statusText = (TextView) statusText;
          }
          @Override
          protected String doInBackground(Void... params) {
              try {
                  ServerSocket serverSocket = new ServerSocket(8315); //631
                  Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
                  Socket client = serverSocket.accept();
  
                  Log.d(WiFiDirectActivity.TAG, "Server: connection done");
  //                final File f = new File(Environment.getExternalStorageDirectory() + "/"
  //                        + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
  //                        + ".txt");
  
  
                  final File f = new File(Environment.getExternalStorageDirectory() + "/"
                          + context.getPackageName() + "/wifip2pshared-" + ".txt");
                  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();
                  return f.getAbsolutePath();
              } catch (IOException e) {
                  Log.e(WiFiDirectActivity.TAG, e.getMessage());
                  return null;
              }
          }
          /*
           * (non-Javadoc)
           * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
           */
          @Override
          protected void onPostExecute(String result) {
              if (result != null) {
                  statusText.setText("File copied - " + result);
  //                Log.e("...File copied - ", result);
                  Intent intent = new Intent();
                  intent.setAction(android.content.Intent.ACTION_VIEW);
                  intent.setDataAndType(Uri.parse("file://" + result), "text/*");
                  context.startActivity(intent);
              } else {
                  Log.e("File copied is NULL- ", result);
              }
          }
          /*
           * (non-Javadoc)
           * @see android.os.AsyncTask#onPreExecute()
           */
          @Override
          protected void onPreExecute() {
              statusText.setText("Opening a server socket");
          }
      }
      public static boolean copyFile(InputStream inputStream, OutputStream out) {
          byte buf[] = new byte[1024];
          int len;
          try {
              while ((len = inputStream.read(buf)) != -1) {
                  out.write(buf, 0, len);
              }
              out.close();
              inputStream.close();
          } catch (IOException e) {
              Log.d(WiFiDirectActivity.TAG, e.toString());
              return false;
          }
          return true;
      }
  }
  </code></pre>
  
  <p><strong>EDIT #1</strong>
  This is my permission setting</p>
  
  <pre><code>&lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&gt;
  &lt;uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /&gt;
  &lt;uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /&gt;
  &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
  &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&gt;
  &lt;uses-permission android:name="android.permission.READ_PHONE_STATE" /&gt;
  &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&gt;
  &lt;uses-permission android:name="android.permission.BIND_PRINT_SERVICE" /&gt;
  &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
  </code></pre>
  
  <p>After connecting to the printer, I've got the UI to select the file, after I select it, nothing happens, I just got the below console output (the file I am picking up is located in the SD card)</p>
  
  <blockquote>
    <ul>
    <li><p>05-17 10:39:50.994 28659-28659/com.example.ccano.wifidirect       E/ViewRootImpl: sendUserActionEvent() mView == null</p></li>
    <li><p>05-17    10:39:52.314 28659-28659/com.example.ccano.wifidirect    D/ViewRootImpl:    ViewPostImeInputStage processPointer 0</p></li>
    <li><p>05-17 10:39:52.384    28659-28659/com.example.ccano.wifidirect    D/ViewRootImpl:    ViewPostImeInputStage processPointer 1</p></li>
    <li><p>05-17 10:39:56.484    28659-28659/com.example.ccano.wifidirect    D/wifidirectdemo:    Intent-----------<br>
    content://com.android.externalstorage.documents/document/9C33-6BBD%3Asample_file.txt</p></li>
    <li><p>05-17 10:39:56.514 28659-28659/com.example.ccano.wifidirect       D/wifidirectdemo: P2P state changed - 2</p></li>
    <li><p>05-17 10:39:56.514    28659-29309/com.example.ccano.wifidirect    D/wifidirectdemo: Opening    client socket -</p></li>
    <li><p>05-17 10:39:56.514    28659-28659/com.example.ccano.wifidirect    D/wifidirectdemo: Peer    status :0</p></li>
    <li>05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect       D/wifidirectdemo: Client socket - true</li>
    <li><p>05-17 10:39:56.524    28659-29309/com.example.ccano.wifidirect    E/ccano..copyfile: true</p></li>
    <li><p>05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect       D/wifidirectdemo: Client: Data written</p></li>
    <li>05-17 10:39:56.534    28659-28659/com.example.ccano.wifidirect    I/Timeline: Timeline:    Activity_idle id:<br>
    android.os.BinderProxy@75dd5e time:4602644</li>
    <li>05-17    10:41:01.714 28659-28659/com.example.ccano.wifidirect    D/ViewRootImpl:    ViewPostImeInputStage processPointer 0</li>
    <li>05-17 10:41:01.774    28659-28659/com.example.ccano.wifidirect    D/ViewRootImpl:    ViewPostImeInputStage processPointer 1</li>
    <li>05-17 10:41:02.564    28659-28659/com.example.ccano.wifidirect    D/wifidirectdemo: P2P peers    changed</li>
    <li>05-17 10:41:02.574 28659-28659/com.example.ccano.wifidirect       D/wifidirectdemo: Peer status :3</li>
    <li>05-17 10:41:02.594    28659-28659/com.example.ccano.wifidirect    D/wifidirectdemo: No devices    found</li>
    </ul>
  </blockquote>
  
  <p><strong>EDIT #2</strong></p>
  
  <p>After adding the below line into my manifiest, still I am getting same result, nothing happens.</p>
  
  <pre><code>&lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/isPP2.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/isPP2.jpg" alt="enter image description here"></a></p>
  
  <p><strong>Edit #3</strong></p>
  
  <p>After changing WpsInfo.Label to WpsInfo.PBC now, I am getting a different output on the debugger console. (see screen shot below). But, still I the printer is not sending the print job.</p>
  
  <p><a href="https://i.stack.imgur.com/WcVKe.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/WcVKe.jpg" alt="enter image description here"></a></p>