Android調用打印機


        打印機其實和Android沒有什么大的關系,和linux內核關聯才是比較強的。

       最終的結果是要在Android實現驅動打印機,但是一般調試一個新的驅動的流程是這樣的:1.先在linux PC上進行測試。2.在標准嵌入式linux上進行調試。3.改裝到Android中去。

       為什么這么安排?因為資源是遞減的,可以在第一階段確定設備有無問題,以及該設備在linux工作流程;在第二階段是因為標准的嵌入式linux還是遵循GNU規定的,包括大部分,這個階段驗證該設備能否在ARM架構的上順利編譯通過;第三階段就是實用階段了,因為最終要在這個不是怎么遵守GNU規定的Android系統上運行的。

 

第一階段

       我測試了3台打印機:1.Canon iP2780 2.Canon MX428 3.HP Deskjet 1000。由於的我作業系統就是Linux,在Linux PC上很快就逐個搞定。第1台用的是這里的驅動(包括deb包和部分開源源碼)加上這個《iP2700 series IJ Printer Driver Ver. 3.30 for Linux (操作說明)》,機器就可以正常使用了;第2台和第一台驅動模式都是一樣的只不過在這里;第3台用的是這里的一級一級選擇最終下載文件是:hplip-3.14.1.run,直接執行會把所缺失的東西全部安裝,可以成功使用。

       如果我僅僅是一個使用者,那么到現在可以就結束了。但是我是一個開發者,我最終的目標是移植到Android中,所以我的目的地不在這里,我要繼續深度挖掘。要挖掘的點很多,這里說一個最迫切的就是如何用命令打印一個文件?這個問題似乎很奇怪,但是我也不知道如何做。不過最終找到了就是:lp或者lpr加文件名,就可以打印出一個文件了。例如:

lp ~/hello.pdf

 

       找這么一個命令我就花費了幾個小時的時間,這里我就有一種很強的預感,前邊的路很還很遙遠。(整理文章的順序和實驗的步驟會稍有不同,其實這個命令在《iP2700 series IJ Printer Driver Ver. 3.30 for Linux (操作說明)》是有的,但是這個“操作說明”是后來才看到的)。

       現在看來我不應該草率進行去進行第二個階段,應該好好的研究一下Linux的打印系統。總結文章就按照最好的流程來吧。先說我是怎么了解了linux的打印系統的。

       意外發現的這個本書《Linux系統管理技術手冊》,真是對我了解Linux的打印系統幫助是最大的,涵蓋的知識面也是最全的,以后的階段中用到的自認為是新的東西,其實這本書上都詳細講解了。講解打印不是講解如何打印就好了,而是詳細的講解了打印機的原理,要經過哪些步驟,打印機語言等等,如果是國人寫的書一般會說“此內容不在本書要討論的范圍內”一句概括。那一章我反復看了一周時間才算有些眉目。

       一切終歸一張圖:

       其實到目前為止我應該好好規划一下我要設計的東西,實現中我急功近利了,並沒有做完全的規划就進行了第二階段。

小規划:

       打印機選擇:推薦選擇HP的,激光的噴墨的都可以,HP是全力支持Linux的。

       打印系統的選擇:

              大的架構是CUPS,主要的模塊有:

                     后台:

                     過濾器:

                     PPD:

       其實在圖中隨便從上到下連一條線,就可以組合成一套打印系統。下面進入第二階段吧。 

       在測試過程中還意外發現CUPS一個bug,或者是我還沒有已經有解決方案我還沒有發現而已。那就是CUPS缺少錯誤處理, 一台打印機,如果出現墨盒用完,墨盒實效等等問題的時候,CUPS是沒有告知用戶的。比如我的HP Deskjet 1000,在使用CUPS打印時出現了這個情況:打印機無響應,用lpstat -t查看到的狀態是“Rendering completed”。這就找不到問題所在了,不過同樣的情況下在Windows下找到了答案:

 

第二階段

       調試Canon的打印機的時候我選擇了這樣的架構:CUPS+cnijfilter-source-3.30-1.tar.gz.

1.配置Linux內核(作用:生成設備節點)

make menuconfig 選上USB打印機選項:
       Device Drivers  --->
                      [*] USB support  ---> 
                                   <*>   USB Printer support     
(配置成功后,插入打印機后設備節點會出現在/dev/usb/目錄下一般名字"lp0")  

 2.交叉編譯CUPS 1.3.9

#!/bin/sh

# 1.下載源碼
wget http://www.cups.org/software/1.3.9/cups-1.3.9-source.tar.gz &&

# 2.解壓並打開
tar xvzf cups-1.3.9-source.tar.gz && cd cups-1.3.9 &&

# 3.配置
./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar --disable-gnutls --disable-gssapi --disable-dbus --prefix=/ &&

# 4.修改Makefile使其不編譯man
sed -i '22s/locale man monitor/locale monitor/' ./Makefile &&

# 5.編譯並安裝
make && make install DSTROOT=/work/rootfs/rootfs_qtopia_qt4 &&

echo "cups build install ok!"

 

3.交叉編譯ghostscript 8.15

#!/bin/sh

DESTDIR=/work/rootfs/rootfs_qtopia_qt4

# 1.下載源碼
wget http://iweb.dl.sourceforge.net/project/ghostscript/GPL%20Ghostscript/8.15/ghostscript-8.15.tar.gz &&

# 2.解壓源碼
tar xvzf ghostscript-8.15.tar.gz &&

# 3.分別拷貝為PC版本和ARM版本
cp ghostscript-8.15 ghostscript-8.15-arm -r && mv ghostscript-8.15 ghostscript-8.15-pc &&

# 4.編譯PC版本
# -DHAVE_SYS_TIME_H是解決warning: implicit declaration of function 'gettimeofday'
cd ghostscript-8.15-pc && ./configure && make XCFLAGS=-DHAVE_SYS_TIME_H=1 && cd ../ &&

# 5.配置arm版本
cd ghostscript-8.15-arm && ./configure --host=arm-linux &&

# 6.修改Makefile中STDLIBS=-lm 為STDLIBS=-lm -static
sed -i '257s/STDLIBS=-lm/STDLIBS=-lm -static/' ./Makefile &&

# 7.拷貝PC版本工具
mkdir obj && cp ../ghostscript-8.15-pc/obj/genarch ../ghostscript-8.15-pc/obj/genconf ../ghostscript-8.15-pc/obj/echogs ./obj/ &&

# 8.編譯
make XCFLAGS=-DHAVE_SYS_TIME_H=1 &&

# 9.安裝(這個版本不支持make install的DESTDIR指定根目錄所以要手動拷貝,以后要調整目錄)
mkdir -p ${DESTDIR}/usr/local/share/ghostscript/8.15/ &&
cp -r lib ${DESTDIR}/usr/local/share/ghostscript/8.15/ &&
cp -r Resource ${DESTDIR}/usr/local/share/ghostscript/8.15/ &&
cp bin/gs ${DESTDIR}/bin/

 

4.交叉編譯gutenprint 5.2.9

#!/bin/sh

# 1.下載源碼 項目地址:http://sourceforge.net/projects/gimp-print/files/gutenprint-5.2/5.2.9/
wget http://softlayer-ams.dl.sourceforge.net/project/gimp-print/gutenprint-5.2/5.2.9/gutenprint-5.2.9.tar.bz2 &&

# 2.解壓
tar xvjf gutenprint-5.2.9.tar.bz2 &&

# 3.分別拷貝為PC版本和ARM版本 
cp -r gutenprint-5.2.9 gutenprint-5.2.9-arm && mv gutenprint-5.2.9 gutenprint-5.2.9-pc &&

# 4.編譯PC版本
cd gutenprint-5.2.9-pc && ./configure && make && cd ../ &&

# 5.配置arm版本 
cd gutenprint-5.2.9-arm && ./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar --with-gimp2=no --without-gimp2 --enable-cups-ppds --enable-cups-level3-ppds --without-ghostscript --without-foomatic --disable-libgutenprintui2 &&

# 6.拷貝PC版本工具 
make || cp ../gutenprint-5.2.9-pc/src/xml/.libs/extract-strings ./src/xml/.libs/ &&

# 7.編譯並安裝
make && make install DSTROOT=/work/rootfs/rootfs_qtopia_qt4 &&

echo "gutenprint build install ok!"

 

5.交叉編譯hpijs-2.1.4

 

#!/bin/sh

# 1.下載源碼 項目地址:http://sourceforge.net/projects/hpinkjet/files/
wget http://superb-dca2.dl.sourceforge.net/project/hpinkjet/hpijs/2.1.4/hpijs-2.1.4.tar.gz

# 2.解壓源碼
tar xvzf hpijs-2.1.4.tar.gz && cd hpijs-2.1.4

# 3.配置
./configure --host=arm-linux --target=arm-linux --build=i686-linux CC=arm-linux-gcc CXX=arm-linux-g++ LD=arm-linux-ld RANLIB=arm-linux-ranlib AR=arm-linux-ar

# 4.修正語法錯誤 dj3320.cpp第403行和registry.cpp第249行 開頭的char改為const char
sed -i '249s/\tchar\t/\tconst char\t/' registry.cpp
sed -i '403s/ char/ const char/' dj3320.cpp

# 5.編譯並安裝
make && make install DESTDIR=/work/rootfs/rootfs_qtopia_qt4

 

6.啟動各個模塊

       以上是我編譯的源碼所有記錄,它們每個都是可以單獨運行驗證的。

啟動cups:$ /etc/init.d/cups start

CUPS可以將/etc/cups/cupsd.conf的日志級別LogLevel設置為debug,這樣如果啟動失敗會將原因打印到/var/log/cups/error_log中。我沒有遇到什么大的bug,遇到的都是缺少目錄問題。

 

7.最簡的打印系統ghostscript+hpijs

       這個方案主要是參考了《基於嵌入式Linux的打印控制系統的設計》,這個是比較適合嵌入式打印機的,不占資源,不需要一些相比比較雞肋的功能。保存了一份到資源中,下載(注:最好是自己源碼編譯,不保證對所有cpu可用,必須是ARM架構且在ARMv7以上)直接可以用。可以直接安裝主到Android中或者普通的嵌入式Linux中。

 

8.無系統的打印機實現

       這個是更簡的,就是沒有操作系統的控制器來操作打印機,是我在調試這個HP Deskjet 1000意外發現一個牛人實現的《USB HOST+HP DeskJet 1000打印機》。當然我是真實的實驗了他提供的BIN文件,他用是TQ2440,我在MINI2440上直接測試也是沒有問題的,打印出來的內容是“HP802黑色墨盒加墨方法”,這兩款開發板都是采用的S3C2440這個ARM的CPU。雖然沒有提供源碼,不過也算是提供了一種可能,如果以后有這方面的需求可以順這條路研究下去。

 

第三階段 移植到Android中預留

1. 最簡打印移植到Android中

       首先強扭過去,庫不用擔心,都是才用的靜態鏈接編譯的。關鍵是“文件系統層次結構標准”Android沒有遵守,經過實驗強制建立了兩個目錄,才能正常使用/usr和/tmp目錄。
       需要優化的幾點:1.關於/tmp目錄的調整 2.關於/usr目錄的調整 3.設備節點的動態創建,。。。。
               1.關於/tmp目錄的調整 在stackoverflow上討論出一個解決方案是用/data/local/tmp來代替;
               2.關於/usr目錄的調整 重新編譯ghostscript調整的/system/usr/..目錄;
               3.設備節點 還沒有調試;

    4.打印中英文字庫的問題;

Fix /tmp目錄問題:

       為了按照功能區別開來,最終選用/data/misc/printer/tmp/目錄作為/tmp目錄。將gs代碼gp_unifs.c中tmp/目錄更換。

       $ sed -i '74s/"\/tmp\/"/"\/data\/misc\/printer\/tmp\/"/' ./src/gp_unifs.c

Fix /usr目錄問題:

  一般是usr是在根目錄下的,Android中是在/system/上的,ghostscript編譯時要進行調整,調整的結果是在配置時添加:--prefix=/system/那么ghostscript就會把資源文件調整到/system/usr/share/....目錄下,這樣剛好可以解決問題。

Fix設備節點問題:

  根據《Android與標准Linux對比》經驗和實驗得出:Android中用ueventd+VOLD來完成了普通Linux中udev的工作,前者負責創建設備節點,后者用於處理。插入打印機后,會自動創建設備節點/dev/usb/lp0。、
ueventd默認創建出來的是只有root用戶才能夠訪問的權限,Android中改變權限的方法是在uevent.${BOARD}.rc中添加如下:

#For USB printer
/dev/usb/lp0 0666 system system

再次查看設備節點權限,正常。


Fix字體問題:

  一直測試打印的都圖片,打印中英文的時候會報錯,根據具體報錯原因打到解決方法。

#!/bin/sh
# 說明:本腳本下載並打包GS所需字庫
# 版本:2013-01-17
# 將打包好的字庫放到
# Android: /system/usr/share/ghostscript/8.15/Resource/ 中解壓
# Linux : /usr/local/share/ghostscript/8.15/Resource/ 中解壓
# * 解決了常用中英文打印所需的字庫

DESTDIR=${PWD}/system

# 1.下載gs-fonts源碼 項目地址:http://sourceforge.net/projects/gs-fonts/
wget http://superb-dca2.dl.sourceforge.net/project/gs-fonts/gs-fonts/8.11%20%28base%2035%2C%20GPL%29/ghostscript-fonts-std-8.11.tar.gz &&

# 2.解壓gs-fonts源碼
tar xvzf ghostscript-fonts-std-8.11.tar.gz &&

# 3.下載gs-9.04,獲取其中的字庫 項目地址:http://sourceforge.net/projects/ghostscript/files/GPL%20Ghostscript/9.04/
wget http://softlayer-ams.dl.sourceforge.net/project/ghostscript/GPL%20Ghostscript/9.04/ghostscript-9.04.tar.bz2 &&

# 4.解壓gs-9.04源碼
tar xvjf ghostscript-9.04.tar.bz2 &&

# 5.建立字庫目錄 Font
test -d ./Font && rm -rf ./Font ; mkdir ./Font &&

# 6.拷貝字庫到Font目錄中
# 拷貝gs-fonts
cp -rf fonts/* ./Font &&
# 拷貝gs-9.04的字庫 
cp -rf ghostscript-9.04/Resource/Font/* ./Font &&

# 7.打包字庫
tar cvzf Font.tar.gz Font &&

echo "Fonts ok!"

 

  字體的問題解決了,Android中也有自己的字體位於/system/fonts中,其中ttf格式居多,而這里用的大多都是pfb格式的。


---------------------
作者:kangear
來源:CSDN
原文:https://blog.csdn.net/kangear/article/details/18141741 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM