takkaaaaaの日記

趣味について書いている個人ブログです

【Androidアプリ制作】targetSdkVersionを29や30に上げると、PDF出力できなくなった事象を解決しました。


公開日:
カテゴリ: プログラミング
タグ:
※本ブログには広告が含まれます

勉強も兼ねて、個人で開発・公開している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出力をしているのは、生活習慣記録表と残業・勤務時間ログになります)

takkaaaaaの日記トップページへ

私のブログを読んで頂き、ありがとうございます。管理人のtakkaaaaaです。

2013年から書き始めて、読んでくれた方に少しでもお役に立てればいいなと思って発信しています。よろしくお願いいたしますm(_ _)m

  • Location : 北海道の十勝地方出身、横浜市在住
  • Work : システムエンジニア・プログラマー(10年以上)
  • Interest :
    • ・音楽鑑賞(aikoのファンクラブに入ってます)
    • ・園芸・ガーデニング(観葉植物やイチゴやバジルなど)
    • ・投資・税金・節約(FP3級と日商簿記3級を保有)

詳しいプロフィールを見る
メッセージを送ろう