Wireless Printing in b4a

AndyDroid2012

Member
Licensed User
Longtime User
I am a newbie, but from reading the b4a forum I may have misunderstood if it is "easy" to print to wireless network printers, or not.

I downloaded from Google Play Store the free app "Lets Print Droid" which seems to say it can do so, plus in the help file it says how to handle
android.intents

Here is the section from their installed help file, and I would welcome comments from anyone who has tried to print from b4a natively.

B4X:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 

Printing from Another App using LPD

Let’s Print Droid (LPD) can be used by other Android apps to allow them to print. 
This is done via Android Intents. Using the “android.intent.action.SEND” or VIEW Intent 
and a properly formed URI you can programmatically send a file to LPD to be printed.

Before you begin you must ensure the user has installed the LPD app.

Here is a short example that gives the user a choice of apps with which to print. 
It would include LPD if installed:

Intent i = new Intent(android.content.Intent.ACTION_SEND);

i.setType("application/pdf");

i.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://dir/file.pdf"));

startActivity(Intent.createChooser(i, "Print file.pdf"));

If you know that the user will have the LPD app pre-installed you can be more direct and 
avoid the app chooser dialog:

Intent i = new Intent(Intent.ACTION_VIEW);

i.setClassName("com.blackspruce.lpd","com.blackspruce.lpd.ReceiveSentFile");

i.setData( Uri.parse("file://dir/file.jpg"));

startActivityForResult(i, 99);

LPD will print the file and return control to your app via the onActivityResult method :

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// returning from Let’s Print Droid

if (data != null&& requestCode == 99 && resultCode == RESULT_OK) {

// the file printed OK if resultCode == RESULT_OK

}

But WAIT, there’s more! If you act now we’ll include the ability to specify the printer details 
in the intent. LPD will look for Extended Data in the intent so that the user does not need 
to configure the LPD App printer in advance. All you need to do is call “android.content.Intent.putExtra()” and pass a string of JSON data to the LPD app. 
Here is an example:

Intent i = new Intent(Intent.ACTION_VIEW);

i.setClassName("com.blackspruce.lpd","com.blackspruce.lpd.ReceiveSentFile");

i.setData( Uri.parse("file://dir/file.jpg"));

JSONObject object = new JSONObject();

try {

object.put("name", "My Cool App - Print Server" );

object.put("port", 631 ); // standard CUPS/IPP port

object.put("address", "192.164.0.10" ); // IP addr or full DNS name

object.put("queue", "/printers/MyPrinter" ); // CUPS printer/class for IPP

object.put("protocol", "IPP" ); // valid values : IPP(S), LPR,HTTP, etc.

object.put("PDL", "PCL" ); // valid values : JPG, PCL, PCL-C, PS, PDF

} catch (JSONException e) {

e.printStackTrace();

}

i.putExtra("jsonPrinter",object.toString());

startActivityForResult(i, 99);

There are plenty of options for the Protocol and PDL (Page Definition Language) and consequently plenty of ways to screw up, so a little caution and plenty of testing may be required.

Here is a quick list of the protocols:

IPP | IPPS – CUPS Internet Printing Protocol and CUPS with SSL encryption. Standard port 631.

LPR – Line Printer Remote. Standard Port 515.

RAW – Jet Direct / RAW. Standard Port 9100.

SMB – SAMBA / Server Message Block (Microsoft Printer Sharing protocol). Standard port 445.

GCP – Google Cloud Print. Standard port 443. (This is not a full integration to Google Cloud Print ; just a pass thru to their web client.)

HTTPS | HTTPS – Hyper Text Transfer Protocol (POST command) and 
HTTP with SSL. Ports are 80 for HTTP and 443 for HTTPS.

FTP | FTPS – File Transfer Protocol and FTP with SSL.

SHARE – Generate a Send Intent with selection dialog, instead of actually printing the 
output PDL. Use Port 0 and IP Address “null”. Queue =”Select Dialog”.

In all cases the meaning of the “queue” JSON value morphs to reflect what is needed by 
the protocol. It may help to think of the JSON string as an URL and envision it this way 
(The PDL will represent the format of the actual data being sent):

protocol://address:port/queue

For IPP the queue is typically like “/printers/MyPrinter”.

For LPR it will be an actual printer name similar to the Unix LPR command ; 
e.g. “lpr –H IPAddress:Port –P “QueueName” file.ext”

For RAW, it is a queue name

for SMB, the shared printer name

for GCP, it is ignored

for HTTP it is the URL path

for FTP the remote directory.

The options for PDL (Page Definition Language) are :

JPG – Really just RAW format. Send the document to be printed as it exists; if it is a JPG 
send the JPG, if PDF send the PDF and assume the destination printer can handle 
the rendering and rasterization. You would be surprised what some modern laser printers
 understand. Most CUPS installations using Foomatic/Ghostscript will understand this format.

PCL – HP Printer Command Language level 5. Generic black and white PCL with dithered images.

PCL-C – HP PCL level 5C. Generic colour PCL.

PS – Generic Postscript level 2.

PDF – Portable Document Format (Adobe) level 1.3

One important note: some types of source input files cannot be converted to some destination
 PDL formats. In particular this version of LPD does not yet contain rendering and raster-ization
 of source PDF, MS Word Docs , etc. Only JPG, PNG, GIF, TXT and HTML can be converted to
 PDL.

Rendering/raster-ization of source input PDF will appear in later levels of the app. Future
 versions will also accept a JSON string specifying print job parameters such as, pages to print,
 duplexing , portrait/landscape, etc.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 

mangojack

Well-Known Member
Licensed User
Longtime User
for personal use I use PrinterShare which works very well, but not really a good option if your eventually pushing your app out to the masses ..

Cheers mj
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
I am a newbie, but from reading the b4a forum I may have misunderstood if it is "easy" to print to wireless network printers, or not.

I downloaded from Google Play Store the free app "Lets Print Droid" which seems to say it can do so, plus in the help file it says how to handle
android.intents

Here is the section from their installed help file, and I would welcome comments from anyone who has tried to print from b4a natively.

AndyDroid2012:

Did you give a try on priting using this method?

I am looking for a way to print reports on android.

I have talked with the creator of this apk you mentioned and he said that was not going to work with cheap inkjet printers, because they do not have a compatible protocol (each model is something different)

However I was looking around and checked on internet many of these printers DO understand PCL at some level.

I believe vast majority of printers in use are cheap inkjet printers. am I wrong?

At least in my country they prefer to buy cheap ones for simple needs. Few pages per week usage.

Well, please, I wanted to know if you tested this app, if you could call the intent from b4a and if you could tell me with wich printers you tested?

sorry to ask that much, however I am really in need to find an answer.
 
Upvote 0

luke2012

Well-Known Member
Licensed User
Longtime User
Try this intent:
B4X:
Dim i As Intent
i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(...))
i.SetComponent("com.blackspruce.lpd/.ReceiveSentFile")
StartActivity(i)

@Erel how to know which modules expose an app via intent?

Es.

SetComponent("com.blackspruce.lpd/.ReceiveSentFile")

I understand that the left string before / is the app package name but how to know the strings that we can use after the / (in this specific case is .ReceiveSentFile) ?
 
Upvote 0
Top