打印功能的实现
近期農(nóng)信項(xiàng)目后臺(tái)系統(tǒng)客戶(hù)新提出需求的其中一項(xiàng)涉及到“打印”功能,前期技術(shù)儲(chǔ)備時(shí),發(fā)現(xiàn)網(wǎng)上相關(guān)資源甚少且混雜,特別是有關(guān)web打印技術(shù),被碼農(nóng)們一致稱(chēng)為“老大難”。現(xiàn)整理了幾項(xiàng)經(jīng)本人驗(yàn)證的可行的打印方法,包括C/S和B/S的,供碼友們參考。
?
一、C/S
1.利用Java.awt中提供的打印API,繼承Printable實(shí)現(xiàn)接口方法print進(jìn)行打印。
參考文獻(xiàn):《Java實(shí)現(xiàn)打印功能》-----------百度文庫(kù)。
此方法實(shí)際是C/S的打印方法,但是在某些特殊情況下,B/S的打印依然可用,例如在某些特殊的管理系統(tǒng),操作此系統(tǒng)的用戶(hù)可以非常方便的設(shè)置發(fā)布此系統(tǒng)的服務(wù)器,那么將服務(wù)器所連接的打印機(jī)設(shè)置成用戶(hù)指定的打印機(jī),此時(shí)再將代碼設(shè)置成直接打印狀態(tài)(不彈出打印提示頁(yè)面),就可以順利完成打印操作。
該方法的弊端也比較明顯,java.awt所提供API實(shí)現(xiàn)接口的方法print,最后是用Graphics2D直接輸出,所以有關(guān)長(zhǎng)篇文字的格式只能手動(dòng)調(diào)整(可參考官方API文檔的格式調(diào)整算法),且參數(shù)中只有一個(gè)Graphics,以至于整篇文檔的字體、顏色都是統(tǒng)一格式,無(wú)法調(diào)整(也許是本人對(duì)Graphics實(shí)在不了解),且無(wú)法操作頁(yè)眉頁(yè)腳(當(dāng)以Word文檔格式時(shí));優(yōu)點(diǎn)不用說(shuō),一般的打印還是可以實(shí)現(xiàn)的,且Graphics能畫(huà)出來(lái)的也就都能打印出來(lái),所以,此種打印方式所適用的和不適用的情況也就比較明顯了吧。
?
以下是關(guān)鍵代碼,詳細(xì)請(qǐng)見(jiàn)文件夾下printHelp.java文件中內(nèi)容。
package com.hepow.cbrc.help;
?
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
importjava.awt.Image;
importjava.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
importjava.text.AttributedString;
?
publicclassprintHelpimplementsPrintable {
/**
* @param Graphic指明打印的圖形環(huán)境
* @param PageFormat指明打印頁(yè)格式(頁(yè)面大小以點(diǎn)為計(jì)量單位,1點(diǎn)為1英才的1/72,1英寸為25.4毫米。A4紙大致為595×842點(diǎn))
* @param pageIndex指明頁(yè)號(hào)
**/
??? ?? publicintprint(Graphicsgra,PageFormatpf,intpageIndex)throws PrinterException {
??? ?????? System.out.println("pageIndex="+pageIndex);
??? ?????? Component c =null;
??? ????? //print string
??? ?????? String test = "根據(jù)國(guó)家勞動(dòng)管理規(guī)定以及本公司員工聘用辦法,甲方招聘乙方為試用員<br/>工,雙方在平等、自愿的基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款"
??? ??? ???? ???+ "根據(jù)國(guó)家勞動(dòng)管理規(guī)定以及本公司員工聘用辦法,甲方招聘乙方為試用員工,雙方在平等、自愿的基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款"
??? ??? ???? ???+ "根據(jù)國(guó)家勞動(dòng)管理規(guī)定以及本公司員工聘用辦法,甲方招聘乙方為試用員工,雙<br/>方在平等、自愿的基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款"
??? ??? ???? ???+ "根據(jù)國(guó)家勞動(dòng)管理規(guī)定以及本公司員工聘用辦法,甲方招聘乙方為試用員工,雙方在平等、自愿的基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款";
??? ?????? String head ="勞動(dòng)合同范本(二)——試用期勞動(dòng)合同范本";
??????? ????? String str ="";
??????? ????? String str01 ="甲方:______________________";
??????? ????? String str02 ="乙方: (身份證號(hào))______________________";
??????? ????? String str03 ="?根據(jù)國(guó)家勞動(dòng)管理規(guī)定以及本公司員工聘用辦法,甲方招聘乙方為試用員工,雙方在平等、自愿的基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款";
??????? ????? String str033 ="基礎(chǔ)上,經(jīng)協(xié)商一致簽訂本試用合同,共同遵守本協(xié)議所列條款。";
??????? ????? String str04 ="一、試用合同期限:試用期為個(gè)月,自_____年_____月_____日至_____年_____月_____日止。";
??????? ????? String str05 ="二、根據(jù)甲方的工作安排,聘用乙方在_______________工作崗位。";
??????? ????? String str06 ="三、甲方聘用乙方的月薪為_(kāi)____元(含養(yǎng)老、醫(yī)療、住房公積金)。試用期滿(mǎn)后,并經(jīng)考核合格,可";
??????? ????? String str066 ="根據(jù)平等協(xié)商的原則,簽訂正式勞動(dòng)合同。";
??????? ????? String str07 ="四、甲方的基本權(quán)利與義務(wù):";
??????? ????? String str08 ="1.甲方的權(quán)利";
??????? ????? String str09 ="?有權(quán)要求乙方遵守國(guó)家法律和公司各項(xiàng)規(guī)章制度;";
??????? ????? String str10 ="?在試用期間,乙方如嚴(yán)重違反勞動(dòng)紀(jì)律或企業(yè)規(guī)章制度,甲方有權(quán)終止合同。乙方的行為給甲方";
??????? ????? String str100 ="造成損失的,由乙方賠償,情節(jié)嚴(yán)重的追究法律責(zé)任;";
??????? ????? String str11 ="?試用期間,乙方由于個(gè)人原因所發(fā)生的疾病以及傷殘等意外事故,乙方自行負(fù)責(zé);";
??????? ????? String str12 ="2.甲方的義務(wù)";
??????? ????? String str13 ="?為乙方提供必要的工作條件;";
??????? ????? String str14 ="?負(fù)責(zé)對(duì)乙方進(jìn)行職業(yè)道德、業(yè)務(wù)技能及公司規(guī)章制度的教育和培訓(xùn);";
??????? ????? String str15 ="五、乙方的基本權(quán)利和義務(wù)。";
??????? ????? String str16 ="1.乙方的權(quán)利";
??? ????????? String str17 ="?享有國(guó)家法律法規(guī)賦予的一切公民權(quán)利;";
??? ????????? String str18 ="?享有公司規(guī)章制度規(guī)定可以享有的福利待遇的權(quán)利;";
??? ????????? String str19 ="?試用期間如變更單位,須提前一個(gè)月通知甲方,雙方協(xié)商終止試用合同;";
??? ????????? String str20 ="2.乙方的義務(wù)";
??? ????????? String str21 ="?遵守國(guó)家法律法規(guī)、當(dāng)?shù)卣?guī)定的公民義務(wù);";
??? ????????? String str22 ="?遵守公司的各項(xiàng)規(guī)章制度、員工手冊(cè)、行為規(guī)范的義務(wù);";
??? ????????? String str23 ="?維護(hù)公司的聲譽(yù)、利益的義務(wù)。";
??? ????????? String str24 ="六、甲方的其他權(quán)利、義務(wù)";
??? ????????? String str25 ="?試用期間,乙方不能勝任工作或弄虛作假不符合錄用條件,甲方有權(quán)提前解除本合同;";
??? ????????? String str26 ="?乙方有突出表現(xiàn),甲方可提前結(jié)束試用,與乙方簽訂正式勞動(dòng)合同;";
??? ?????? ???String str27 ="七、乙方的其他權(quán)利、義務(wù)";
??? ????????? String str28 ="?試用期滿(mǎn),有權(quán)決定是否簽訂正式勞動(dòng)合同;";
??? ????????? String str29 ="?具有參與公司民主管理、提出合理化建議的權(quán)利;";
??? ????????? String str30 ="?反對(duì)和投訴對(duì)乙方試用身份不公平的歧視。";
??? ????????? String str31 ="八、本合同如有未盡事宜,雙方本著友好協(xié)商原則處理。";
??? ????????? String str32 ="九、本合同一式兩份,甲、乙雙方各執(zhí)一份,具有同等效力,經(jīng)甲乙雙方簽章生效。";
??? ????????? String str33 ="甲方(蓋章)?????????????????????乙方(蓋章)";
??? ????????? String str35 ="法定代表人簽字:";
??? ????????? String str36 ="簽約日期:_____年_____月_____日";
??? ????????? String str37 ="簽約地點(diǎn):";
??? ????? //轉(zhuǎn)換成Graphics2D
??? ????? Graphics2D g2 = (Graphics2D) gra;
??? ????? //設(shè)置打印顏色為黑色
??? ????? g2.setColor(Color.black);
??? ?????
??? ????? /*Paper paper =pf.getPaper();//得到頁(yè)面格式的紙張
??? ????? paper.setSize(500,500);//紙張大小
??? ????? paper.setImageableArea(0,0,500,500); //設(shè)置打印區(qū)域的大小
??? ????? System.out.println(paper.getWidth());
??? ????? System.out.println(paper.getHeight());
??? ????? pf.setPaper(paper);//將該紙張作為格式 */
?
??? ????? //打印起點(diǎn)坐標(biāo)
??? ????? doublex =pf.getImageableX();
??? ????? doubley =pf.getImageableY();
??? ??????
??? ????? switch(pageIndex){
??? ???????? case 0:
??? ?????????? //設(shè)置打印字體(字體名稱(chēng)、樣式和點(diǎn)大小)(字體名稱(chēng)可以是物理或者邏輯名稱(chēng))
??? ?????????? //Java平臺(tái)所定義的五種字體系列:Serif、SansSerif、Monospaced、Dialog和 DialogInput
??? ?????????? Font font = new Font("新宋體", Font.PLAIN, 9);
??? ?????????? g2.setFont(font);//設(shè)置字體
??? ?????????? float[]dash1 = {4.0f};
??? ?????????? g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,4.0f,dash1,0.0f));
??? ?????????? floatheigth =font.getSize2D();//字體高度
??? ?????????? /*g2.drawString(head, 3*(float)x, (float)y + 1*heigth);
??? ?????????? g2.drawString(str, (float)x,(float)y + 2*heigth);
??? ?????????? g2.drawString(str01, (float)x,(float)y + 3*heigth+2);
??? ?????????? g2.drawString(str02, (float)x,(float)y + 4*heigth+2);
??? ?????????? g2.drawString(str03, (float)x,(float)y + 5*heigth+2);
??? ?????????? g2.drawString(str033, (float)x,(float)y + 6*heigth+2);
??? ?????????? g2.drawString(str04, (float)x,(float)y + 7*heigth+2);
??? ?????????? g2.drawString(str05, (float)x, (float)y+ 8*heigth+2);
??? ?????????? g2.drawString(str06, (float)x,(float)y + 9*heigth+2);
??? ?????????? g2.drawString(str066, (float)x,(float)y + 10*heigth+2);
??? ?????????? g2.drawString(str07, (float)x,(float)y + 11*heigth+2);
??? ?????????? g2.drawString(str08, (float)x,(float)y + 12*heigth+2);
??? ?????????? g2.drawString(str09, (float)x,(float)y + 13*heigth+2);
??? ?????????? g2.drawString(str10, (float)x,(float)y + 14*heigth+2);
??? ?????????? g2.drawString(str100, (float)x,(float)y + 15*heigth+2);
??? ?????????? g2.drawString(str11, (float)x,(float)y + 16*heigth+2);
??? ?????????? g2.drawString(str12, (float)x,(float)y + 17*heigth+2);
??? ?????????? g2.drawString(str13, (float)x,(float)y + 18*heigth+2);
??? ?????????? g2.drawString(str14, (float)x,(float)y + 19*heigth+2);
??? ?????????? g2.drawString(str15, (float)x,(float)y + 20*heigth+2);
??? ?????????? g2.drawString(str16, (float)x,(float)y + 21*heigth+2);
??? ?????????? g2.drawString(str17, (float)x,(float)y + 22*heigth+2);
??? ?????????? g2.drawString(str18, (float)x,(float)y + 23*heigth+2);
??? ?????????? g2.drawString(str19, (float)x,(float)y + 24*heigth+2);
??? ?????????? g2.drawString(str20, (float)x,(float)y + 25*heigth+2);
??? ?????????? g2.drawString(str21, (float)x,(float)y + 26*heigth+2);
??? ?????????? g2.drawString(str22, (float)x,(float)y + 27*heigth+2);
??? ?????????? g2.drawString(str23, (float)x,(float)y + 28*heigth+2);
??? ?????????? g2.drawString(str24, (float)x,(float)y + 29*heigth+2);
??? ?????????? g2.drawString(str25, (float)x,(float)y + 30*heigth+2);
??? ?????????? g2.drawString(str26, (float)x,(float)y + 31*heigth+2);
??? ?????????? g2.drawString(str27, (float)x,(float)y + 32*heigth+2);
??? ?????????? g2.drawString(str28, (float)x,(float)y + 33*heigth+2);
??? ?????????? g2.drawString(str29, (float)x,(float)y + 34*heigth+2);
??? ?????????? g2.drawString(str30, (float)x,(float)y + 35*heigth+2);
??? ?????????? g2.drawString(str31, (float)x,(float)y + 36*heigth+2);
??? ?????????? g2.drawString(str32, (float)x,(float)y + 37*heigth+2);
??? ??? ???????g2.drawString(str33, (float)x, (float)y+ 39*heigth+2);
??? ?????????? g2.drawString(str, (float)x,(float)y + 43*heigth);
??? ?????????? g2.drawString(str35, (float)x,(float)y + 44*heigth+2);
??? ?????????? g2.drawString(str36, (float)x,(float)y + 45*heigth+2);
??? ?????????? g2.drawString(str37, (float)x,(float)y + 46*heigth+2);*/
??? ?????????
??? ?????????? FontRenderContextfrc =g2.getFontRenderContext();
??? ?????????? TextLayout layout = new TextLayout(test,font,frc);
??? ?????????? AttributedString text = new AttributedString(test);
??? ?????????? text.addAttribute(TextAttribute.FONT,font);
??? ?????????? LineBreakMeasurerlineBreaker =new LineBreakMeasurer(text.getIterator(),frc);
??? ?????????? doublewidth =pf.getImageableWidth();????????????????????????????????????????//每行字符顯示長(zhǎng)度(點(diǎn))
??? ?????????? Point2D.Double pen = new Point2D.Double (100,y+3*heigth);????????????????????//首字符的基線(xiàn)位于用戶(hù)空間中的 (x, y)位置處
??? ?????????? while ( (layout =lineBreaker.nextLayout((float)width)) != null){
??? ????????????? layout.draw(g2, (float)x, (float)pen.y);
??? ????????????? pen.y +=layout.getAscent();
??? ?????????? }
??? ???????? returnPAGE_EXISTS;
??? ???????? default:
??? ???????? returnNO_SUCH_PAGE;
??? ????? }
??? ?}
}
?
調(diào)用時(shí):
//獲取打印服務(wù)對(duì)象方法1
Book book =new Book();
PageFormat pageFormat =new PageFormat();????????//設(shè)置成豎打
pageFormat.setOrientation(PageFormat.PORTRAIT);
//通過(guò)Paper設(shè)置頁(yè)面的空白邊距和可打印區(qū)域。必須與實(shí)際打印紙張大小相符。
Paper pager =new Paper();???????????????????????
pager.setSize(590,840);??????????????????????????//紙張大小
//A4(595 X 842)設(shè)置打印區(qū)域,其實(shí)0,0應(yīng)該是72,72,因?yàn)?/span>A4紙的默認(rèn)X,Y邊距是72
pager.setImageableArea(72,72, 590, 840);????????
pageFormat.setPaper(pager);
//把 PageFormat和 Printable添加到書(shū)中,組成一個(gè)頁(yè)面
book.append(new printHelp(),pageFormat);????????
PrinterJob job = PrinterJob.getPrinterJob();?????//獲取打印服務(wù)對(duì)象
job.setPageable(book);???????????????????????????//設(shè)置打印類(lèi)
try {
//Boolean a = job.printDialog();//顯示打印提示窗口
//if(a) {
job.print();
//}
?
} catch (Exceptione) {
e.printStackTrace();
}
?
//獲取打印服務(wù)對(duì)象方法2
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat pageFormat =job.defaultPage();//得到默認(rèn)頁(yè)格式
job.setPrintable(new printHelp());//設(shè)置打印類(lèi)
?
try {
//Boolean a = job.printDialog();//顯示打印提示窗口
//if(a) {
job.print();
//}
} catch (PrinterExceptione) {
e.printStackTrace();
}
?
以上方法的弊端催生了關(guān)于打印的另一種思路,那就是利用Java操作Word(或其他文件),然后讓W(xué)ord去打印這種曲線(xiàn)救國(guó)思路。一開(kāi)始我真的以為這是個(gè)好想法,但是后來(lái)我發(fā)現(xiàn)確實(shí)只是個(gè)好的“想法”而已,我可以用Java POI實(shí)現(xiàn)對(duì)Word內(nèi)容的讀取寫(xiě)入,但是我實(shí)現(xiàn)不了通過(guò)java讓W(xué)ord自己去觸發(fā)打印動(dòng)作(網(wǎng)上資料說(shuō)java不支持這種方法<純代碼方式實(shí)現(xiàn)>,可作者依然堅(jiān)信這種方法是有大神可以實(shí)現(xiàn)的)。
對(duì)于該技術(shù)研究到此時(shí)算是遇到了瓶頸,作者不免在辦公室里小發(fā)牢騷目的是尋求身邊其他碼友的幫助,此時(shí)王琦(本社iOS碼神)幫我找到了網(wǎng)上的一份資源,讓我不禁感慨碼界里還是神多。不再啰嗦,請(qǐng)看:
?
2.史上最強(qiáng)大java Word(文件)打印方案
參考文獻(xiàn):(1)《史上最強(qiáng)大Java Word打印方案》------- http://blog.csdn.net/ylz2007/article/details/41172653
(2)http://stackoverflow.com/questions/2446721/how-to-get-print-out-of-a-ms-word-file-from-java-application
?
publicvoidprintWordFile(Stringfilename){
try{
Runtime.getRuntime().exec("cmd.exe /c start /min winword " +filename+" /q /n /f /mFilePrint/mFileExit");
}catch(Exceptione){
logger.info("打印異常:" +e.getMessage());}}
?
調(diào)用代碼:
printWordFile("D:\\Users\\Desktop\\tomcat部署文檔-new.docx");
?
這個(gè)的具體解釋我就不再多說(shuō)了,C/S打印中終極中的終極,曲線(xiàn)中的曲線(xiàn)!
?
小結(jié):
利用com組件進(jìn)行打印功能的實(shí)現(xiàn)由于本人沒(méi)有親試過(guò),所以也就不敢造次,還請(qǐng)路過(guò)的你親自研究。
?
二、B/S
1.最直接,最科普的打印方式:window.print()以及WB.execWB()
用window.print()可以直接打印整個(gè)頁(yè)面的內(nèi)容,也可以打印指定部分的內(nèi)容。這個(gè)是比較科普的方式,但是,其功能之簡(jiǎn)陋也是比較科普的。
網(wǎng)頁(yè)WB.ExecWB控件打印方法:
4,1保存網(wǎng)頁(yè)??
4,2保存網(wǎng)頁(yè)(可以重新命名)??
6,1直接打印??
6,2直接打印??
7,1打印預(yù)覽?
7,2 打印預(yù)覽??
8,1選擇參數(shù)??
8,2選擇參數(shù)??
10,1查看頁(yè)面屬性??
10,2查看頁(yè)面屬性??
17,1全選??
17,2全選??
22,1重新載入當(dāng)前頁(yè)??
22,2重新載入當(dāng)前頁(yè)
?
<OBJECT???classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2??? height=0???id=WebBrowser??? width=0></OBJECT>???
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(1,1)??? type=button??? value=打開(kāi)>??
?? <input???name=Button??? onClick=document.all.WebBrowser.ExecWB(2,1)??? type=button??? value=關(guān)閉所有>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(4,1)??? type=button??? value=另存為>????
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(6,1)??? type=button??? value=打印>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(6,6)??? type=button??? value=直接打印>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(8,1)??? type=button??? value=頁(yè)面設(shè)置>??
?? <input???name=Button? ??onClick=document.all.WebBrowser.ExecWB(10,1)??? type=button??? value=屬性>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(17,1)??? type=button??? value=全選>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(22,1)? ??type=button???value=刷新>??
?? <input???name=Button???onClick=document.all.WebBrowser.ExecWB(45,1)??? type=button??? value=關(guān)閉>
?
開(kāi)篇里提到web 打印是“老大難”,這個(gè)難度究竟如何?這么說(shuō)吧,有一個(gè)公司為了解決WEB打印的問(wèn)題,專(zhuān)門(mén)組織了一個(gè)強(qiáng)大的團(tuán)隊(duì),并得到全國(guó)1000多家軟件公司的技術(shù)支持,經(jīng)N年嘔心瀝血,制作出了“露肚皮”,開(kāi)發(fā)團(tuán)隊(duì)稱(chēng):“她是全國(guó)1000多家軟件公司的智慧結(jié)晶,誕生7年了,幾乎每個(gè)功能細(xì)節(jié)都蘊(yùn)藏著無(wú)數(shù)開(kāi)發(fā)者的期待和汗水”。
2. 作者推薦:WEB開(kāi)發(fā)必選伴侶 ——LODOP
泰安夢(mèng)泰爾軟件有限公司旗下產(chǎn)品,Lodop(標(biāo)音:勞道譜,俗稱(chēng):露肚皮)是專(zhuān)業(yè)WEB控件,用它既可裁剪輸出頁(yè)面內(nèi)容,又可用程序代碼直接實(shí)現(xiàn)復(fù)雜打印。控件功能強(qiáng)大,支持頁(yè)面打印、報(bào)表打印、條碼打印、圖表打印、套打等,簡(jiǎn)單易用。
<script language="JavaScript"src="<s:url value="/style/script/LodopFuncs.js"/>"></script>
<object? id="LODOP_OB" classid="clsid:2105C259-1E0C-4534-8141-A753534CB4CA" width=0 height=0>
<embed id="LODOP_EM"type="application/x-print-lodop" width=0 height=0></embed>
</object>
function prn3_preview(){
LODOP=getLodop();
LODOP.PRINT_INIT("打印控件功能演示_Lodop功能_全頁(yè)");
LODOP.ADD_PRINT_HTM(0,0,"100%","100%",document.getElementById("print").innerHTML);
LODOP.PREVIEW();
};
?
幾行簡(jiǎn)單的JS,便實(shí)現(xiàn)了復(fù)雜的WEB打印。
其具體使用方法以及例子請(qǐng)見(jiàn)LODOP文件夾內(nèi)的文件。
?
總結(jié)
- 上一篇: 安卓9.0添加服务修改SELinux
- 下一篇: 走了,又回来了