您现在的位置是:网站首页> Android
Android 基于打印服务的打印的实现
- Android
- 2022-04-09
- 917人已阅读
Android打印实现
赋予权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qdian.testmyapp" >
<uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Context.getExternalFilesDir() ;//取代android:requestLegacyExternalStorage="true"
import android.print.PrintAttributes;
import android.print.PrintManager;
void doPrint()
{
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintAttributes.Builder builder = new PrintAttributes.Builder();
builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);
printManager.print("test pdf print", new MyPrintDocumentAdapterEx(this,filePath), builder.build());
}
package com.qdian.testmyapp;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.pdf.PrintedPdfDocument;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MyPrintDocumentAdapterEx extends PrintDocumentAdapter {
private Context context;
private int pageHeight;
private int pageWidth;
private PdfDocument mPdfDocument;
private int totalpages = 1;
private String pdfPath;
private List<Bitmap> mlist;
public MyPrintDocumentAdapterEx(Context context, String pdfPath) {
this.context = context;
this.pdfPath = pdfPath;
}
@Override
//在onLayout()方法中,你的适配器需要告诉系统框架文本类型,总页数等信息
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,
LayoutResultCallback callback,
Bundle metadata) {
mPdfDocument = new PrintedPdfDocument(context, newAttributes); //创建可打印PDF文档对象
pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000; //设置尺寸
pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
totalpages=2;
if (totalpages > 0) {
PrintDocumentInfo.Builder builder = new PrintDocumentInfo
.Builder("快速入门.pdf")
.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(totalpages); //构建文档配置信息
PrintDocumentInfo info = builder.build();
callback.onLayoutFinished(info, true);
} else {
callback.onLayoutFailed("Page count is zero.");
}
}
@Override
//当需要将打印结果输出到文件中时,系统会调用onWrite()方法,该方法的参数指明要打印的页以及结果写入的文件,你的方法实现需要将页面的内容写入到一个多页面的PDF文档中,当这个过程完成时,需要调用onWriteFinished
public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,
final WriteResultCallback callback) {
for(int i=0;i<2;i++){
PdfDocument.PageInfo newPage = new PdfDocument.PageInfo.Builder(pageWidth,
pageHeight, i).create();
PdfDocument.Page page =
mPdfDocument.startPage(newPage); //创建新页面
if (cancellationSignal.isCanceled()) { //取消信号
callback.onWriteCancelled();
mPdfDocument.close();
mPdfDocument = null;
return;
}
drawPage(page, i); //将内容绘制到页面Canvas上
mPdfDocument.finishPage(page);
}
try {
mPdfDocument.writeTo(new FileOutputStream(
destination.getFileDescriptor()));
} catch (IOException e) {
callback.onWriteFailed(e.toString());
return;
} finally {
mPdfDocument.close();
mPdfDocument = null;
}
callback.onWriteFinished(pageRanges);
}
//页面绘制(渲染)
private void drawPage(PdfDocument.Page page, int pagenumber) {
Canvas canvas = page.getCanvas();
/*
Paint paint = new Paint();
paint.setTextSize(100);
canvas.drawText("打印测试",20,20,paint);
*/
int titleBaseLine = 72;
int leftMargin = 54;
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setTextSize(36);
canvas.drawText("Hello Title", leftMargin, titleBaseLine, paint);
paint.setTextSize(11);
canvas.drawText("Hello paragraph", leftMargin, titleBaseLine + 25, paint);
paint.setColor(Color.BLUE);
canvas.drawRect(100, 100, 172, 172, paint);
}
}
1.打印网页
PrintManager printManager = (PrintManager)mContext.getSystemService(Context.PRINT_SERVICE);
//打印任务的名字
String jobName = getString(R.string.app_name) + " 处方打印";
//这里需要webview创建PrintDocumentAdapter
PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter();
PrintAttributes.Builder builder = new PrintAttributes.Builder();
//选择A5纸张横向打印
builder.setMediaSize(PrintAttributes.MediaSize.ISO_A5.asLandscape());
printManager.print(jobName, printAdapter,builder.build());
上面的方法需要个你当前的webview,将当前的webview传给他他们,执行上面的方法就会跳转到系统的打印页面,非常简单
2、打印图片
try {
PrintHelper printHelper = new PrintHelper(this);
printHelper.printBitmap("jobName", BitmapFactory.decodeStream(getAssets().open("timg.jpg")));
} catch (IOException e) {
e.printStackTrace();
}
直接传给该方法一个bitmap,就直接跳转到预览打印页面,你就可以选择相应的打印机进行打印了
打印PDF文件
赋予权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qdian.testmyapp" >
<uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Context.getExternalFilesDir() ;//取代android:requestLegacyExternalStorage="true"
动态获取权限
MainActivity.java
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
verifyStoragePermissions(this);
findViewById(R.id.mybt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
String[] strArray=new String[1];
strArray[0]="application/pdf";
intent.putExtra(Intent.EXTRA_MIME_TYPES,strArray);
intent.setType("*/*");//无类型限制
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
}
});
}
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it Or Log it.
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri uri = data.getData();
filePath = uri.getPath();
try {
filePath=getPath(MainActivity.this,uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
doPrint();
}
}
void doPrint() {
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintAttributes.Builder builder = new PrintAttributes.Builder();
builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);
printManager.print("test pdf print", new MyPrintDocumentAdapterPDF(this,filePath), builder.build());
}
MyPrintDocumentAdapterPDF.java
package com.qdian.testmyapp;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.pdf.PrintedPdfDocument;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class MyPrintDocumentAdapterPDF extends PrintDocumentAdapter {
private Context context;
private int pageHeight;
private int pageWidth;
private PdfDocument mPdfDocument;
private int totalpages = 1;
private String pdfPath;
private List<Bitmap> mlist;
public MyPrintDocumentAdapterPDF(Context context, String pdfPath) {
this.context = context;
this.pdfPath = pdfPath;
}
@Override
//在onLayout()方法中,你的适配器需要告诉系统框架文本类型,总页数等信息
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,
LayoutResultCallback callback,
Bundle metadata) {
mPdfDocument = new PrintedPdfDocument(context, newAttributes); //创建可打印PDF文档对象
pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000; //设置尺寸
pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
ParcelFileDescriptor mFileDescriptor = null;
PdfRenderer pdfRender = null;
PdfRenderer.Page page = null;
try {
mFileDescriptor = ParcelFileDescriptor.open(new File(pdfPath), ParcelFileDescriptor.MODE_READ_ONLY);
if (mFileDescriptor != null)
pdfRender = new PdfRenderer(mFileDescriptor);
mlist = new ArrayList<>();
if (pdfRender.getPageCount() > 0) {
totalpages = pdfRender.getPageCount();
for (int i = 0; i < pdfRender.getPageCount(); i++) {
if(null != page)
page.close();
page = pdfRender.openPage(i);
Bitmap bmp = Bitmap.createBitmap(page.getWidth()*2,page.getHeight()*2, Bitmap.Config.ARGB_8888);
page.render(bmp, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
mlist.add(bmp);
}
}
if(null != page)
page.close();
if(null != mFileDescriptor)
mFileDescriptor.close();
if (null != pdfRender)
pdfRender.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (totalpages > 0) {
PrintDocumentInfo.Builder builder = new PrintDocumentInfo
.Builder("快速入门.pdf")
.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(totalpages); //构建文档配置信息
PrintDocumentInfo info = builder.build();
callback.onLayoutFinished(info, true);
} else {
callback.onLayoutFailed("Page count is zero.");
}
}
@Override
public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,
final WriteResultCallback callback) {
for (int i = 0; i < totalpages; i++) {
if (pageInRange(pageRanges, i)) //保证页码正确
{
PdfDocument.PageInfo newPage = new PdfDocument.PageInfo.Builder(pageWidth,
pageHeight, i).create();
PdfDocument.Page page =
mPdfDocument.startPage(newPage); //创建新页面
if (cancellationSignal.isCanceled()) { //取消信号
callback.onWriteCancelled();
mPdfDocument.close();
mPdfDocument = null;
return;
}
drawPage(page, i); //将内容绘制到页面Canvas上
mPdfDocument.finishPage(page);
}
}
try {
mPdfDocument.writeTo(new FileOutputStream(
destination.getFileDescriptor()));
} catch (IOException e) {
callback.onWriteFailed(e.toString());
return;
} finally {
mPdfDocument.close();
mPdfDocument = null;
}
callback.onWriteFinished(pageRanges);
}
private boolean pageInRange(PageRange[] pageRanges, int page) {
for (int i = 0; i < pageRanges.length; i++) {
if ((page >= pageRanges[i].getStart()) &&
(page <= pageRanges[i].getEnd()))
return true;
}
return false;
}
//页面绘制(渲染)
private void drawPage(PdfDocument.Page page,int pagenumber) {
Canvas canvas = page.getCanvas();
if(mlist != null){
Paint paint = new Paint();
Bitmap bitmap = mlist.get(pagenumber);
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
// 计算缩放比例
float scale = (float)pageWidth/(float)bitmapWidth;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
canvas.drawBitmap(bitmap,matrix,paint);
}
}
}
下一篇:常用界面XML