Recently, bluetooth printing is needed in the project. Baidu has provided a lot of information, but the articles about Android mobile printing are not very detailed. It’s a lot of work to write your own Bluetooth print module, and it needs to be compatible with any printer on the market. Here I quote an article for you to see:

First, Android client printing technology status quo

Cloud print

Before Android KitKat, Google introduced cloud printing, in which users upload the data they need to print to the server and fill in their contact information. The printed image is mailed to the user. It’s a business model, not a technology. That said, Until Android KitKat, Google didn’t have a solution for Android printing. In addition to Google’s cloud printing solution, there are many third-party companies that also provide similar solutions (see: 2).

Print the framework

KitKat was released, and Google launched a printing framework. As an interface between the applications that need to use printing service and the applications that implement printing service, the framework facilitates the use of printing function by developers. Applications that need to use printing services apply for services using the printing framework API, and the specific printing services are provided by the printer OEM. In essence, this framework facilitates the use of application printing function, but in fact, the creation of the most critical printing data stream is still done by the APK provided by the printer manufacturer. (Reference: 3)

The third party

In addition to the printing APK provided by major printer manufacturers, there are also third-party applications that can print, such as PrinterShare. The implementation of this application is unclear, but it is speculated that it has obtained PDL support from various vendors and has specific PDL development reference data.

Products on the market

Take Kingsoft’S WPS as an example. This application supports the printing of common office documents. There are two options for printing: first, use the printing service of the system, that is, the printing framework after KitKat mentioned above; Second, generate a.ps file. It is important to note that the contents of this file are PostScript, which, as described above, is not supported by all printers. So, what the application does is provide printing functionality by using a printing framework, while also providing support for some printers. In addition, a search shows that there are very few printing applications on the market. (Reference: 4)

Two, feasible plan

Based on the previous understanding, two schemes are identified

  • Method 1: An application operates an Excel file and fills in data. The printing function is implemented by a third-party application
  • Method 2: Use PDL to print

Methods a

  1. Apply the update and download the print template (.xsl file)
  2. The application uses the third-party SDK to operate the template file and fill in the corresponding data
  3. Print target files are generated, after the completion of the user through a third party application implementation of printing Third-party applications: 1) the manufacturer provides the APK, support some type of printer (support range is not wide) 2) third party APK, such as PrintShare (support a wider range of reference: 5) about the choice of the printer, support the printer: a. Easy to carry b. plug-in support C. price within a certain range

Way 2

  1. Same as method 1, but the downloaded file is a.txt file
  2. The application combines the template TXT with the data
  3. The application generates print data and sends it to the printer via Bluetooth

To compare

Way of print

Printing effect

Development and maintenance difficulty

Difficulty of using the app

Methods a

good

simple

After comparing

Way 2

bad

complex

low

In terms of printing effect, the printing effect of method one is almost the same as that of PC printing, while the printing effect of method two has problems such as font ambiguity and style can not be fully reflected. In terms of technical implementation, method one can use existing mature Excel files to operate SDK; Method two needs to deal with format conversion, file splicing and print data generation.

Actual selection: Method two.

HP PCL 3 printing language

For details, please refer to pcl3_developers_guide.pdf

Here is a brief introduction to the basics of the language

  1. The language is made up of instructions, similar to assembly language, and each function is implemented by specific instructions. For example, the size is set by a directive
  2. There are several versions of this instruction. The version used by the target printer is PCL 3 GUI, which is the third version of PCL. Compared with PCL 3, it has better support for graphic printing and its language instruction is a superset of PCL 3.

As you can see, it’s complicated. Today, we will call PrinterShare to realize printing and leave the printing work to PrinterShare. We just need to pass the file to PrinterShare. The specific implementation process is as follows:

1, download the official APK, do not go to the domestic market to download, PS: I download the apk package name in the domestic market is not the same as the official (/ / \] com. Dynamixsoftware. Printershareoaj, is the latest version of the com. Dynamixsoftware. Printershare

2. Decompile APK, which everyone can do without saying;

3. Looking at the manifest file we need to pay attention to:

1) Package name

There are many printing modes: picture, PDF, Word, doc, XLS, PPT, etc. I printed TXT text and selected this activity

4, the code…

1) Copy the APK installation package to assets

2) Install APK and check whether it has been installed:

public static boolean isInstallApp(Context context, String packageName) { return ! RxDataUtils.isNullString(packageName) && RxIntentUtils.getLaunchAppIntent(context, packageName) ! = null; }Copy the code

Set the package name, action pass, file type, and set the data:

// If file sharing is 7.0 or higher, If (buildconfig.version_code > build.version_codes.m) {new Thread({File shareFilePath = new File(filesDir, "external_files"); shareFilePath .mkdir(); File shareFile = new File(shareFilePath.getPath(), "test.txt") ; // Copy the test file from the sd card root directory to the App directory. Copy files method can baidu FileUtils. Used by copyFile (Environment. External.getexternalstoragedirectory () getPath () + "/ test. TXT", shareFile .getPath()); Uri Uri = FileProvider. GetUriForFile (this, "your APP package name" + ". FileProvider ", shareFile); ComponentName comp = ComponentName("com.dynamixsoftware.printershare", "com.dynamixsoftware.printershare.ActivityPrintDocuments"); Intent intent =new Intent(); intent.setComponent(comp); intent.setAction("android.intent.action.VIEW"); intent.setType("text/plain"); intent.setData(uri); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); }).start(); }else{ ComponentName comp = new ComponentName("com.dynamixsoftware.printershare","com.dynamixsoftware.printershare.ActivityPrintDocuments"); Intent intent = new Intent(); intent.setComponent(comp); intent.setAction("android.intent.action.VIEW"); intent.setType("text/plain"); intent.setData(Uri.parse(Environment.getExternalStorageDirectory().getPath()+"/test.txt")); startActivity(intent); }Copy the code

For Android 7.0 and later: create an XML folder in the res directory and place the file_paths_public file

The code inside looks like this

<? The XML version = "1.0" encoding = "utf-8"? > <paths> <files-path name="share" path="external_files"/> </paths>Copy the code

The manifest file then configures the Provider

< the provider of the android: name = "androidx. Core. Content. FileProvider" android: authorities = "your APP package name. FileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths_public" /> </provider>Copy the code

Ps: HERE I directly placed a test text in the SD card and directory.

For ComponentName you can look it up, you can open a component for another application.

If not, copy the file and install it again:

Copy files from assets:

public File getAssetFileToCacheDir( String fileName) { try { File cacheDir = FileUtil.getCacheDir(MyApp.getApplictaion()); final String cachePath = cacheDir.getAbsolutePath()+ File.separator + fileName; InputStream is = MyApp.getApplictaion().getAssets().open(fileName); File file = new File(cachePath); file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); byte[] temp = new byte[1024]; int i = 0; while ((i = is.read(temp)) > 0) { fos.write(temp, 0, i); } fos.close(); is.close(); getActivity().runOnUiThread(new Runnable() { @Override public void run() { mRxDialogLoading.cancel(); }}); return file; } catch (IOException e) { e.printStackTrace(); } return null; }Copy the code

Installation:

Intent I = new Intent(intent.action_view); public static void InstallAPK(Context Context, String APK_PATH) { i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setDataAndType(Uri.parse("file://" + APK_PATH), "application/vnd.android.package-archive"); context.startActivity(i); }Copy the code

At this point, the entire PrinterShare print is complete. Let’s look at the effect:

Click the print prompt to install APK:

Install successfully, then click the “Print” button

Click “ps” and wait for it to finish loading

Final preview:

The original text of test looks like this:

Fun, PrinterShare’s UI is really ugly ~~~~~

Line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — –

Update:

The above part is to print TXT text, but the actual demand is certainly not to print TXT, print TXT text typesetting is very bad font is not good control, and special characters can not be displayed, generally print PDF, Word, HTML…

My actual project requirement is to print a ticket, which is fairly simple, or print an electronic bill… At first I wanted to use IText to transfer the text content to PDF for printing, ps: Itext is really powerful, PC performance is very strong, interested friends can go to study, 5, and 7, a community version of a commercial version, address ~ ~ ~, but then think of first (1), add jars, apk volume increase, (2) the performance, the android platform and PC platforms are understand it, shortage of resources! Java version of the project is mostly in the PC, although there are big cattle abroad to transplant the project to Android, but directly get android to use there are still a lot of pits… (3) In combination with their own project needs, there is no need to ~~~

All right, let’s get down to business

1, create a new HTML and put it in assets directory (or sd card directory or on the server)

This is the content I need to print, just like this for the time being, it is simple and not fancy, and I need to add a seal at the back ~~~ the general effect is like this.

Ps: in order not to disturb the front-end big guy I began to write, I will not front-end will not front-end ah! ~~~~~ this allows the front end to write nice HTML based on the printed content.

2. Find our manifest file above and this time we are using ActivityWeb

3, masturbation code

Note: this is not the same as we printed TXT, activity component, Type, Data are not the same

ActivityWeb uses the WebView to load the web page and then print it. The WebView loads the web page and the local HTML. I will not say here…

// If file sharing is 7.0 or higher, If (buildconfig.version_code > build.version_codes. M) {new Thread({File shareFilePath = new File(filesDir, "external_files"); shareFilePath .mkdir(); File shareFile = new File(shareFilePath.getPath(), "test2.html"); // Copy the test file from the sd card root directory to the App directory. Copy files method can baidu FileUtils. Used by copyFile (Environment. External.getexternalstoragedirectory () getPath () + "/ test2. HTML", ShareFile. GetPath ()) = FileProvider Uri Uri. GetUriForFile (this, "your APP package name" + ". FileProvider ", shareFile); ComponentName comp = ComponentName("com.dynamixsoftware.printershare", "com.dynamixsoftware.printershare.ActivityPrintDocuments"); Intent intent =new Intent(); intent.setComponent(comp); intent.setAction("android.intent.action.VIEW"); intent.setType("text/html"); intent.setData(uri); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); }).start(); }else{ ComponentName comp = new ComponentName("com.dynamixsoftware.printershare","com.dynamixsoftware.printershare.ActivityWeb"); Intent intent = new Intent(); intent.setComponent(comp); intent.setAction("android.intent.action.VIEW"); intent.setType("text/html"); intent.setData(Uri.parse("file:///"+Environment.getExternalStorageDirectory().getPath()+"/test2.html")); startActivity(intent); }Copy the code

Ps: here I directly put test2.html in the SD card directory, the actual scenario needs to be further considered ~~~~~ anyway complete the function ok~~~~~ if the HTML is stored in the server then pass a print HTML address.

Ok, let’s have a look at the results:

Click “Print” to jump to preview

OK, isn’t PrinterShare powerful? Text, PDF, doc, Word, web pages, forms, pictures and so on can be printed, we can study other functions ~~~ match the filter conditions of its list file to achieve wireless printing function.