8

我必须在 Android 4.4 中开发打印功能 我想开发以下功能: - 使用 Android 4.4 打印框架 - 从 SD 卡打印 pdf(无需重新生成) - 配置如:份数,页面选择

我知道在 Android 4.4 中是可能的。但我想以编程方式从 SD 卡打印 pdf。

4

3 回答 3

9

我们可以通过创建自定义来简单地实现这一点PrintDocumentAdapter

PdfDocumentAdapter.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);
        }
    }
}}

现在使用 print 调用PrintManager

PrintManager printManager=(PrintManager) SurefoxBrowserScreen.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);
}
于 2018-03-15T11:54:10.417 回答
7

我已经为任何需要它的人重写了 Kotlin 中 Karthik 的答案。

class PDFDocumentAdapter(private val file: File) : PrintDocumentAdapter() {

    override fun onLayout(oldAttributes: PrintAttributes?, newAttributes: PrintAttributes?, cancellationSignal: CancellationSignal, callback: LayoutResultCallback, extras: Bundle?) {
        if (cancellationSignal.isCanceled) {
            callback.onLayoutCancelled()
            return
        }

        val info = PrintDocumentInfo.Builder(" file name")
                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
                .build()

        callback.onLayoutFinished(info, oldAttributes != newAttributes)
    }

    override fun onWrite(pages: Array<out PageRange>, destination: ParcelFileDescriptor, cancellationSignal: CancellationSignal, callback: WriteResultCallback) {
        var inputStream: InputStream? = null
        var outputStream: OutputStream? = null

        try {
            inputStream = FileInputStream(file)
            outputStream = FileOutputStream(destination.fileDescriptor)

            inputStream.copyTo(outputStream)

            if (cancellationSignal.isCanceled) {
                callback.onWriteCancelled()
            } else {
                callback.onWriteFinished(arrayOf(PageRange.ALL_PAGES))
            }
        } catch (ex: Exception) {
            callback.onWriteFailed(ex.message)
            Log.e("PDFDocumentAdapter", "Could not write: ${ex.localizedMessage}")
        } finally {
            inputStream?.close()
            outputStream?.close()
        }
    }
}

并使用PDFDocumentAdapter

private fun print(file: File) {
    val manager = getSystemService(Context.PRINT_SERVICE) as PrintManager

    val adapter = PDFDocumentAdapter(file)
    val attributes = PrintAttributes.Builder().build()
    manager.print("Document", adapter, attributes)
}
于 2020-02-21T21:56:33.370 回答
0

就我而言,只是将aaptOptions { cruncherEnabled = false }添加到构建文件中

android {
compileSdkVersion 31

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
    // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
    applicationId "com."
    minSdkVersion 21
    targetSdkVersion 31
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    ndkVersion = "23.0.7599858"
}
signingConfigs {
    release {
        /*keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
        storePassword keystoreProperties['storePassword']*/
    }
}

buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}
aaptOptions { cruncherEnabled = false }
}
于 2021-11-28T07:00:52.547 回答