近期由于公司需求,需要在APP中優化保存文件功能,對除了jpg,png格式外,還需提供PDF格式,主要是為了將多個頁面的內容生成一個文件,而不是保存多個圖片文件到存儲卡中,于是查了很多資料,看到更多的是通過第三方庫進行導出的,但是由于時間緊迫,第三方庫需要了解接口同時還需要配置庫文件。且了解到android在19版本就提供了相關的PDF接口,于是直接去查看官方的文檔:
developer.android.google.cn/reference/index.html
這個鏈接在國內也可以訪問的,是google專門提供給中國開發者的。
具體的類的使用在官方文檔中已經講述的非常清楚:
// 創建一個PDF文本對象
PdfDocument? document=new?? PdfDocument();
//創建當前頁的信息,Builder中的參數表示頁面的寬高,以及第幾頁
PageInfo? pageInfo=newPageInfo.Builder(newRect(0,0,100,100),1).create();
// 生成當前頁
Page? page=document.startPage(pageInfo);
// 在當前頁上畫畫,即把所需要的view的視圖畫到page的畫布上
View? content=getContentView();
content.draw(page.getCanvas());
// 結束當前頁
document.finishPage(page);
...
// 此處在還未調用writeTo()函數之前,可以繼續添加頁面步驟跟上述PageInfo開始的一樣
...
//將PDF文本對象寫到一個輸出流中,getOutputStream()可以是FileOutputStream
document.writeTo(getOutputStream());
// close the document
document.close();
注:其中getContentView()表示當前需要保存的視圖,可以是Layout、Button等View對象
本人在使用的時候遇到了一個問題,就是當這個View是SurfaceView的時候,保存的內容是空白的,因此特地的查了下SurfaceView的源碼。因為SurfaceView繪圖不是在UI主線程上繪制的,而是通過getHolder(),再通過lockCanvas()取得畫布后再繪圖,繪制完畢還需要調用unlockCanvasAndPost()解鎖并刷新畫布。而原本的View中的方法則被處理掉了。
于是只能換種方式了,下面附上代碼,思路還是與官方的一致,但代碼有區別:
//先判斷系統的版本信息
if(android.os.Build.VERSION.SDK_INT>= android.os.Build.VERSION_CODES.KITKAT) {
File sdcarddir = android.os.Environment.getExternalStorageDirectory();
FileOutputStream outputStream =null;
try{
outputStream =newFileOutputStream(newFile(sdcarddir.getPath() +"/123.pdf"));
PdfDocument document =newPdfDocument();
for(inti=1;i<=20;i++) {?? //循壞表示生成20頁PDF
PdfDocument.PageInfo pageInfo =newPdfDocument.PageInfo.Builder(
Constants.displayWidth, Constants.displayHeight, i).create();
PdfDocument.Page page = document.startPage(pageInfo); ??
//此處是與官方的不同之處,官方的view.draw(page.getCanvas()) 無非也是在page返回的canvas對象上繪圖,那么我們可以獲取SurfaceView對象的Bitmap后再繪制到page的//canvas上即可? ? ? ? ??
page.getCanvas().drawBitmap(this.mSurfaceView.getDrawingBitmap(),0,0,newPaint());
document.finishPage(page);
}
document.writeTo(outputStream);
document.close();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
使用過程中還發現了一些缺點,即當視圖的內容比較豐富的時候,存儲的速度會較慢,因此建議另外建一個線程,避免阻塞UI主線程。另Android在21版本后添加了PdfRenderer類,此類可以用于查閱PDF文件內容,大家有空的不妨試試。