一、綜述
android系統(tǒng)現(xiàn)多用于手持設備,為手機等設備應用提供了很好的系統(tǒng)級支持。但對于PC機常用的打印功能,android到目前并不支持,也沒有打印機廠家專門為android設備做打印機驅動。因此在android上實現(xiàn)usb打印功能有一點繁瑣。本文提供了androidjava應用程序實現(xiàn)usb打印的一種方案。這個方案在android系統(tǒng)中打開了一條實現(xiàn)usb打印的從上層應用到內核配置的通路。
由于android系統(tǒng)使用linux內核,而很多打印機都有在linux下的驅動,因此本文采用移植linux下相關開源驅動的方式實現(xiàn)android系統(tǒng)上的usb打印功能。本方案涉及到linux內核配置、linux下的兩個自由軟件ghostscript和foo2zjs的移植、iText在android程序中的應用,java應用程序調用ghostscript和foo2zjs。
二、Linux打印原理
Linux系統(tǒng)上的打印原理如下(注:圖片來自http://www.):

各種類型的文檔經(jīng)由一個(或一些)轉換程序轉換成用戶正在使用的打印機可以認識的格式,即用各種類型的打印機語言描述的流,系統(tǒng)將這個流直接發(fā)送到打印機端口,由打印機對其進行解釋并形成硬拷貝。
目前大多數(shù)Linux系統(tǒng)以下面的流程來實現(xiàn)文檔到打印機語言的轉換(注:圖片來自http://www.):

普通文本文件和各種類型的圖形由適當?shù)霓D換程序轉換成PostScript文件,有些應用程序將其輸出直接寫成PostScript文件,這些PostScript文件經(jīng)由一個作為打印機過濾器的應用程序Ghostscript轉換成打印機語言。因此,如果系統(tǒng)的打印系統(tǒng)已經(jīng)配置成使用Ghostsript作為打印過濾器,應用程序要實現(xiàn)的就是輸出合乎程序要求和語法的PostScript文件。
-
Ghostscript簡介
Ghostscript是一套Adobe系統(tǒng)的PostScript及PDF頁面描述語言的解釋器,是一款免費軟件。Ghostscript可打開Postscript或PDF格式文件,并可將其轉換成其他格式。Gs多用于將Postscript或PDF格式文件轉換成為打印機語言文件。
-
Foo2zjs簡介
Foo2zjs是linux下的一個通用打印程序,支持多種型號的打印機。foo2zjs包提供多個驅動,如foo2zjs、foo2hp、foo2lava、foo2xqx等,它們分別支持一系列打印機。在foo2zjs根目錄下的README文件中詳細說明了它所支持的打印機型號。
-
Itext簡介
iText是著名的開放源碼的站點sourceforge一個項目,是用于生成PDF文檔的一個java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉化為PDF文件。
四、Android系統(tǒng)的打印實現(xiàn)
三、使用工具介紹
-
內核配置
配置內核支持USB打印。
Android系統(tǒng)采用linux內核,因此完全可以根據(jù)Linux打印原理搭建一套打印系統(tǒng)。據(jù)此,作者配置內核支持USB打印,將Ghostscript移植到android下,結合linux的cat命令,搭建了一套打印系統(tǒng),實現(xiàn)了使用USB打印機打印PostScript或PDF文檔的功能。為了能在java程序中生成PDF文檔,需要使用iText.jar包作為從普通文本圖形到PDF文檔的轉換程序,后面會介紹iText在android程序中的使用。
作者發(fā)現(xiàn),在linux命令行下測試打印過程用cat命令向打印機發(fā)送過濾后的打印機語言文件時,等待時間約為10秒甚至更長。如果用android上層java軟件調用打印功能,又會多用幾秒時間。后面增加的這部分時間是android系統(tǒng)啟動服務產生的,我們無法避免,而且這段時間主要是開機后第一次啟動打印功能時才比較長,一但后臺服務啟動完成,之后的使用會消耗較短的時間了。
為了減少整體消耗時間,作者將cat命令換成了foo2zjs的foo2xqx。在linux命令行下測試打印過程,原來的10秒甚至更長縮為1秒左右,用android上層java軟件調用打印功能,也就5到6秒等待時間。
五、部署過程
makemenuconfig -->Device Drivers -->USB Support -->USB Printersupport
這里要強調一點,配置完內核后,將內核編譯并更新到開發(fā)板,運行。在編譯gs等之前,先試試驅動是否配置成功。有的朋友都把后面的完成了,因為這里卡住了。首先,不要忘記mknod一個打印機對應的節(jié)點,對USB打印機,linux提供的主設備號是180,子設備號是0-15,字符型設備。比如mknod /dev/lp0 c 180 0。然后連上打印機,可以用命令 “echo abc> /dev/lp0”測試,只要打印機有響應就行,不用管打印格式。
-
移植ghostscript
因為Android沒有glib庫,為了使程序能在開發(fā)板上運行,我們自己的C程序需要采用靜態(tài)編譯。
-
獲取源代碼
ghostscript的下載地址為http://downloads./public/。我用的是ghostscript-9.04。
解壓ghostscript-9.04.tar.gz,并將解壓后的ghostscript-9.04目錄拷貝成ghostscript-9.04-pc和ghostscript-9.04-arm兩分,分別用于編譯PC主機上的gs和arm-linux上的gs。
命令:
$ tarzxvf ghostscript-9.04.tar.gz
$ cpghostscript-9.04 ghostscript-9.04-pc -R
$ mvghostscript-9.04 ghostscript-9.04-arm
-
編譯
$ tarzxvf ghostscript-9.04.tar.gz
$ cd ghostscript-9.04
$ ./configure--host=arm-linux
修改Makefile:
320行:修改STDLIBS=-lpthread-lm
為STDLIBS=-lpthread-lm -static
387行:修改CCAUX=arm-linux-gcc
為CCAUX=gcc
$ make
-
移植foo2zjs(foo2xqx)
$ wget-O foo2zjs.tar.gz http://foo2zjs./foo2zjs.tar.gz
$ tarzxf foo2zjs.tar.gz
$ cdfoo2zjs
$ geditMakefile
在Makefile文件最開始插入下面兩行,分別用于指定編譯工具和指定靜態(tài)鏈接:
CC=arm-linux-gcc
CFLAGS+= -static
$ exportPATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin
$ make
-
java程序調用linux命令行方法
publicclass linux_cmd {
publicstatic String execute(String cmd)
{
ProcessBuilder pb =new ProcessBuilder("/system/bin/sh");
String str=new String();
pb.directory(newFile("/"));//設置shell的當前目錄。
try{
Processproc = pb.start();
//獲取輸入流,可以通過它獲取SHELL的輸出。
BufferedReaderin =new BufferedReader(newInputStreamReader(proc.getInputStream()));
BufferedReadererr =new BufferedReader(newInputStreamReader(proc.getErrorStream()));
//獲取輸出流,可以通過它向SHELL發(fā)送命令。
PrintWriterout =new PrintWriter(new BufferedWriter(newOutputStreamWriter(proc
.getOutputStream())),true);
out.println(cmd);
out.println("exit");
Stringline;
while((line = in.readLine()) !=null) {
str+=line;
}
while((line = err.readLine()) !=null) {
System.out.println(line); //打印錯誤輸出結果
str+=line;
}
in.close();
out.close();
proc.destroy();
}catch (Exception e) {
System.out.println("exception:"+ e);
}
returnstr;
}
}
-
Androidjava中使用iText的方法。
iText的安裝非常方便,在http:///網(wǎng)站上下載iText.jar文件后,只需要在系統(tǒng)的CLASSPATH中加入iText.jar的路徑,或將iText.jar添加到java工程中,就可以使用iText類庫了。
-
在工程中添加iText源文件
右擊項目-->New-->SourceFolder (取名itext)-->右擊itext-->import-->General-->ArchiveFile-->Next-->Browse(添加 itextpdf-5.1.2-sources.jar和itext-xtra-5.1.2-sources.jar)-->Finish
-
在工程中添加iText需要的庫(jar包)
右擊項目-->BuildPath -->Add Libraries -->User Library--> Next -->右側按鈕UserLibraries... -->New (新建,名字為lib_for_android_iText)-->AddJARs(添加所需要jar包)-->OK-->Finish
iText所依賴的jar包有:
bcmail-jdk16-1.38.jar
bcprov-jdk16-1.38.jar
bctsp-jdk16-1.38.jar
awt-jdk16-1.38.jar
imageio-jdk16-1.38.jar
其中bcmail-jdk16-1.38.jar、bcprov-jdk16-1.38.jar、bctsp-jdk16-1.38.jar是從網(wǎng)上下載的,awt-jdk16-1.38.jar、imageio-jdk16-1.38.jar是用JDK1.6/jre/lib/rt.jar中的java/awt和javax/imageio自己制作的.AndroidSDK中google對sun的類庫做了大量修改,awt和imageio這兩個庫就被裁剪掉了。
-
使用iText生成PDF文件
voidMakePDF(String fileName,String data,Font font)throwsFileNotFoundException, DocumentException
{
linux_cmd.execute("touch"+fileName);//不存在時創(chuàng)建
Documentdocument =new Document();
FileOutputStreamstream=new FileOutputStream(fileName);
PdfWriter.getInstance(document,stream);
document.open();
Paragraphpar =new Paragraph(data,font);
document.add(par);
document.close();
}
-
使用中文字體文件
以使用simfang.ttf為例。在window下找到font文件夾下的simfang.ttf文件(或下載),將它放在android系統(tǒng)的/system/fonts/路徑下,就可以使用它將中文字符寫入PDF了。Java代碼如下:
StringnameBase="/system/fonts/simfang.ttf";
String encoding=BaseFont.IDENTITY_H;
BaseFont bfChinese = BaseFont.createFont(nameBase, encoding,false);
Font fontChinese =newFont(bfChinese, 25, Font.NORMAL);
-
打印測試
將編譯好的新內核、gs、foo2xqx下載到開發(fā)板。如果沒有/dev/lp0 節(jié)點,需要用mknod命令生成一個:mknod /dev/lp0 c 180 0
StringfileName=“/var/Hello.PDF”;
Stringdata=”我的第一個打印測試”;
MakePDF(fileName,data,fontChinese);
Stringcmd="gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE -sPAPERSIZE=letter-r1200x600 -sDEVICE=pbmraw -sOutputFile=- - < "
+fileName+" | foo2xqx -r1200x600 -g10200x6600 -p1 >/dev/lp0";
linux_cmd.execute(cmd);





