打印机其实和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

Android调用打印机的更多相关文章

  1. Java jacob调用打印机打印word文档

    前面说了Java如何生成复杂的Word文档,今年记录下Java如何调用打印机打印word文档. 起初用的是自带的PrintJob,但是系统提供的打印机制并不成熟完整.网上的代码也是千篇一律,在我的打印 ...

  2. android 调用地图

    有时候我们需要调用地图显示一下位置,这时候可能还需要导航,导航做起来有点麻烦,如果调用第三方的是不是很简单,本文就是写这个来的: 第一种方式:android Intent调用地图应用客户端 调用百度地 ...

  3. [转]JS调用Android里面的方法,Android调用JS里面的方法

    FROM : http://blog.csdn.net/hj563308597/article/details/45197709 Android WebView 在公司Android的开发过程中遇到一 ...

  4. Android调用Web服务

    现在大部分应用程序都把业务逻辑处理,数据调用等功能封装成了服务的形式,应用程序只需要调用这些web服务就好了,在这里就不赘述web服务的优点了.本文总结如何在android中调用Web服务,通过传递基 ...

  5. c# 调用打印机

    1.本地打印机 //添加引用并using System.Management; public static void AvailablePrinters() { ManagementScope ms ...

  6. Android调用系统相册和拍照的Demo

    最近我在群里看到有好几个人在交流说现在网上的一些Android调用系统相册和拍照的demo都有bug,有问题,没有一个完整的.确实是,我记得一个月前,我一同学也遇到了这样的问题,在低版本的系统中没问题 ...

  7. Android调用WebService(转)

    Android调用WebService WebService是一种基于SOAP协议的远程调用标准,通过 webservice可以将不同操作系统平台.不同语言.不同技术整合到一块.在Android SD ...

  8. ios 调用打印机

    源码 无意中玩一个demo发现调用了打印机  才发现ios有快速调用打印机的功能. if ([UIPrintInteractionController isPrintingAvailable] == ...

  9. Android调用天气预报的WebService简单例子

    下面例子改自网上例子:http://express.ruanko.com/ruanko-express_34/technologyexchange5.html 不过网上这个例子有些没有说明,有些情况不 ...

随机推荐

  1. 5G技术发展迅猛,亚博电竞(yabo055)搭上科技快车

    要说当前互联网科技最为令人期待的当属yabo055点康母的5G技术了.自2018年5G标准确定以来,民众就对5G非常的期待,而亚博电竞早已意识到了5G时代的来临势不可挡,早已着手将5G运用于网站和游戏 ...

  2. acwing 853. 有边数限制的最短路 模板

    地址 https://www.acwing.com/problem/content/description/855/ 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出 ...

  3. File Zilla server安装完报错could not load TLS libraries. aborting start of administration interface

    问题描述: 系统:Windows2008R2x64 安装完filezillaserver以后出现这个问题 解决方法: 需要安装个系统补丁:Windows6.1-KB2533623-x64 安装完重启服 ...

  4. Linux 指令学习

    查询java安装地址 which java ls -lrt /bin/java ls -lrt /etc/alternatives/java # 如果已经配好,则echo $JAVA_HOME 更改环 ...

  5. 图数据库 Nebula Graph 的安装部署

    Nebula Graph:一个开源的分布式图数据库.作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,还能够实现服务高可 ...

  6. C#属性方法 构造函数(不知道自己理解的对不对)

    using System; namespace test { class Program { static void Main(string[] args) { Cat kitty = new Cat ...

  7. 目前为止最简洁的C#文件夹Copy代码,不接受反驳

    private static void CopyEntireDir(string sourcePath, string destPath) { foreach (string dirPath in D ...

  8. Python3---标准库---urllib

    前言 该文章主要说明Python3 标准库urllib的使用. 修改时间:20191216 修改时间:20191217 修改时间:20191218 添加urllib.parse.urlencode,u ...

  9. IDEA中新建SpringBoot项目时提示:Artifact contains illegal characters

    场景 一步一步教你在IEDA中快速搭建SpringBoot项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/87688277 ...

  10. Cobalt Strike系列教程第一章:简介与安装

    Cobalt Strike是一款超级好用的渗透测试工具,拥有多种协议主机上线方式,集成了提权,凭据导出,端口转发,socket代理,office攻击,文件捆绑,钓鱼等多种功能.同时,Cobalt St ...