[英]Print existing pdf file in android
大家好,我正在尝试在 android 上构建一个小型示例打印应用程序,但似乎无法打印现有的 pdf。 有很多关于使用画布创建自定义文档的文档,但我已经有了该文档。 基本上,我只想能够读取 pdf 文档并将其作为文件输出流直接发送到要打印的打印机。 任何帮助表示赞赏。
我们可以通过创建自定义PrintDocumentAdapter
来简单地实现这一点
文档适配器.java
public class PdfDocumentAdapter extends PrintDocumentAdapter {
Context context = null;
String pathName = "";
public PdfDocumentAdapter(Context ctxt, String pathName) {
context = ctxt;
this.pathName = pathName;
}
@Override
public void onLayout(PrintAttributes printAttributes, PrintAttributes printAttributes1, CancellationSignal cancellationSignal, LayoutResultCallback layoutResultCallback, Bundle bundle) {
if (cancellationSignal.isCanceled()) {
layoutResultCallback.onLayoutCancelled();
}
else {
PrintDocumentInfo.Builder builder=
new PrintDocumentInfo.Builder(" file name");
builder.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
.build();
layoutResultCallback.onLayoutFinished(builder.build(),
!printAttributes1.equals(printAttributes));
}
}
@Override
public void onWrite(PageRange[] pageRanges, ParcelFileDescriptor parcelFileDescriptor, CancellationSignal cancellationSignal, WriteResultCallback writeResultCallback) {
InputStream in=null;
OutputStream out=null;
try {
File file = new File(pathName);
in = new FileInputStream(file);
out=new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
byte[] buf=new byte[16384];
int size;
while ((size=in.read(buf)) >= 0
&& !cancellationSignal.isCanceled()) {
out.write(buf, 0, size);
}
if (cancellationSignal.isCanceled()) {
writeResultCallback.onWriteCancelled();
}
else {
writeResultCallback.onWriteFinished(new PageRange[] { PageRange.ALL_PAGES });
}
}
catch (Exception e) {
writeResultCallback.onWriteFailed(e.getMessage());
Logger.logError( e);
}
finally {
try {
in.close();
out.close();
}
catch (IOException e) {
Logger.logError( e);
}
}
}}
现在使用PrintManager
调用打印
PrintManager printManager=(PrintManager) getActivityContext().getSystemService(Context.PRINT_SERVICE);
try
{
PrintDocumentAdapter printAdapter = new PdfDocumentAdapter(Settings.sharedPref.context,filePath );
}
printManager.print("Document", printAdapter,new PrintAttributes.Builder().build());
}
catch (Exception e)
{
Logger.logError(e);
}
基本上,我只想能够读取 pdf 文档并将其作为文件输出流直接发送到要打印的打印机。
这不是绝对可能的,除非您找到某些特定的打印机为 Android 提供此类 API。
如果您希望使用 Android 打印框架,则需要创建一个可以处理现有 PDF 文件的PrintDocumentAdapter
。 这个示例项目演示了一个这样的PrintDocumentAdapter
,尽管它不是通用的。
对于那些对Karthik Bollisetti的 kotlin 版本感兴趣的人,答案就在这里。
PdfDocumentAdapter
重写为这样
class PdfDocumentAdapter(private val pathName: String) : PrintDocumentAdapter() {
override fun onLayout(
oldAttributes: PrintAttributes?,
newAttributes: PrintAttributes,
cancellationSignal: CancellationSignal?,
callback: LayoutResultCallback,
bundle: Bundle
) {
if (cancellationSignal?.isCanceled == true) {
callback.onLayoutCancelled()
return
} else {
val builder = PrintDocumentInfo.Builder(" file name")
builder.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
.build()
callback.onLayoutFinished(builder.build(), newAttributes == oldAttributes)
}
}
override fun onWrite(
pageRanges: Array<out PageRange>,
destination: ParcelFileDescriptor,
cancellationSignal: CancellationSignal?,
callback: WriteResultCallback
) {
try {
// copy file from the input stream to the output stream
FileInputStream(File(pathName)).use { inStream ->
FileOutputStream(destination.fileDescriptor).use { outStream ->
inStream.copyTo(outStream)
}
}
if (cancellationSignal?.isCanceled == true) {
callback.onWriteCancelled()
} else {
callback.onWriteFinished(arrayOf(PageRange.ALL_PAGES))
}
} catch (e: Exception) {
callback.onWriteFailed(e.message)
}
}
}
然后像这样在您的代码中调用 PrintManager
val printManager : PrintManager = requireContext().getSystemService(Context.PRINT_SERVICE) as PrintManager
try {
val printAdapter = PdfDocumentAdapter(file.absolutePath)
printManager.print("Document", printAdapter, PrintAttributes.Builder().build())
} catch (e : Exception) {
Timber.e(e)
}
对于支持 ipp 和 pdf 的打印机用例,您可以使用我的库https://github.com/gmuth/ipp-client-kotlin将 pdf 直接发送到打印机:
Kotlin:
val printer = IppPrinter(URI.create("ipp://myprinter/ipp"))
val job = printer.printJob(File("mydocument.pdf"))
job.waitForTermination()
不涉及打印对话框。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.