【Androidアプリ制作】targetSdkVersionを29や30に上げると、PDF出力できなくなった事象を解決しました。
公開日:
カテゴリ: プログラミング
タグ: Androidアプリ制作
※本ブログには広告が含まれます
勉強も兼ねて、個人で開発・公開しているAndroidアプリがあるのですが、そのアプリの中でPDFファイルを出力する機能を実装していました。
Androidアプリが対象とするバージョン(targetSdkVersion)が28(Android Q)までだと正常にPDF出力できていたのですが、29(Android 10)や30(Android 11)に上げるとPDF出力ができず、そのため、targetSdkVersionを上げずに28のままにしていました。
ググっても解決できず放置していたのですが、先日もう一度調べてみたら解決できたので、同じことを悩んでいる方がいるかもしれませんし、自分のブログに書いておきます。
PDF出力できなくなった件の修正
アプリをコンパイルするAPIのバージョン(compileSdkVersion)は29や30にあげても大丈夫だったのですが、targetSdkVersionを29や30に上げると、PDF出力できなくなってしまったことがありました。
事象としては、Androidアプリを実行した際に、そのアプリのPDF出力機能を実行しようとすると、画面が真っ白になってPDFファイルに内容が何も出力されませんでした。特にエラーも出てませんでした。
その当時は調べても原因がわからず、結局諦めてtargetSdkVersionは28のままにしていましたが、先日もう一度調べて見ました。
技術的には、私が実装したAndroidアプリからのPDFファイル出力は
1. 表示したい内容の文字列(String型、HTML形式)を作成する
↓
2. webView.loadData()で、webViewに出力したいHTMLを読み込む。
↓
3. PrintDocumentAdapterやPrintManagerを使って、webViewで表示した内容をPDFで印刷する
という流れにしていました(参考・・・AndroidのPrintManagerを使って画面を印刷する方法 – Qiita)
今回調査したところ、こちらのページ(Android Target29に設定するとWebViewで#以降が表示されない – Qiita)を見つけました。
私もHTMLの中で色を指定する際に「#」を使っていたために、webViewの中に何も表示されなかったと思われます。
最初は、自分の調べ方が甘くて、「Android PDF出力できない」的な調べ方をしていましたが、PDFではなくWebViewの方に原因があったことになりますね。
修正後のソースを一部抜粋するとこんな感じになりました。赤字が修正部分です。
//WebView取得
WebView webView = findViewById(R.id.webView);
//PDF出力内容作成
String html = ・・・;
//WebViewに出力内容を設定(targetSdkVersion29以降で#文字以降が表示されない問題があるので、base64エンコードする必要がある)
// webView.loadData(html, "text/html; charset=utf-8", "utf-8");
String base64String = Base64.encodeToString(html.getBytes(), Base64.DEFAULT);
webView.loadData(base64String, null, "base64");
//印刷ファイルのタイトル
String title = "PDFのファイル名.pdf";
//PDFで印刷する
PrintDocumentAdapter printDocumentAdapter = new MyPrintDocumentAdapter(webView.createPrintDocumentAdapter(title));
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintAttributes attributes = new PrintAttributes.Builder()
.setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.build();
Objects.requireNonNull(printManager).print("プリントジョブ名", printDocumentAdapter, attributes);
おわりに
Androidアプリですが、targetSdkVersionが低いとGooglePlayに登録できなくなることが考えられるので(2020/6時点では28以上だったはず)、どこかでtargetSdkVersionを上げる必要があると思います。
とりあえず、自分が公開している下記アプリはこれでtargetSdkVersionを30まで上げてしまうことできたので、一安心です。(PDF出力をしているのは、生活習慣記録表と残業・勤務時間ログになります)