Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print a text file using WiFi Direct

Tags:

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 demo 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.

The current configuration for my EPSON printer bellow.

  • Wi-Fi Direct Mode : On

  • Communication Mode: AP

  • Operation Mode: IEEE802.11g/n

  • Communication Speed: Auto

  • SSID: DIRECT-D3A36C54
  • Channel: 7
  • Security Level: WPA2-PSK(AES)

  • Link Status: Unknown

This is the DeviceDetailFragment class

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 && 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 && 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 && 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<Void, Void, String> {         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;     } } 

EDIT #1 This is my permission setting

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.BIND_PRINT_SERVICE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

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)

  • 05-17 10:39:50.994 28659-28659/com.example.ccano.wifidirect E/ViewRootImpl: sendUserActionEvent() mView == null

  • 05-17 10:39:52.314 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 0

  • 05-17 10:39:52.384 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 1

  • 05-17 10:39:56.484 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: Intent-----------
    content://com.android.externalstorage.documents/document/9C33-6BBD%3Asample_file.txt

  • 05-17 10:39:56.514 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: P2P state changed - 2

  • 05-17 10:39:56.514 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo: Opening client socket -

  • 05-17 10:39:56.514 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: Peer status :0

  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo: Client socket - true
  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect E/ccano..copyfile: true

  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo: Client: Data written

  • 05-17 10:39:56.534 28659-28659/com.example.ccano.wifidirect I/Timeline: Timeline: Activity_idle id:
    android.os.BinderProxy@75dd5e time:4602644
  • 05-17 10:41:01.714 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 0
  • 05-17 10:41:01.774 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 1
  • 05-17 10:41:02.564 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: P2P peers changed
  • 05-17 10:41:02.574 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: Peer status :3
  • 05-17 10:41:02.594 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: No devices found

EDIT #2

After adding the below line into my manifiest, still I am getting same result, nothing happens.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

enter image description here

Edit #3

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.

enter image description here

like image 512
Carlos Avatar asked May 08 '17 14:05

Carlos


People also ask

Can a TXT file be printed?

Is there any way to print the original txt file by the browser? Printers cannot print plaintext files. Files containing text must first undergo a rasterization process (in which the text data is set into a specific font, amongst other things) before they can be physically printed.


1 Answers

It turned out that my code was fine, after several days of testing and doing research, I found out that the issue was the socket class, I was using the default one that Google provides in the demo code (which is the one I was using) but, after reading the official documentation from Wi-Fi.org I could understand that port number matters and, in order to make it work with WiFi Direct only you have to target port #631 and the printer will ask you about the PIN password in case that it is enabled. Now, if you want to use P2P and by-passing the password, you have to use the port #9100.

So, I did it using both ports 9100 and 631 and now I am printing txt files.

Now, if you want to print PDF, you just need to add:

intent.setType("application/pdf");  

and

intent.setDataAndType(Uri.parse("file://" + result), "application/pdf"); 

to the DeviceDetailFragment class (the one is posted above).

I hope this post will provide a good understanding and inside about Android printing with P2P communication.

like image 109
Carlos Avatar answered Oct 12 '22 17:10

Carlos