Android Studio でスマホアプリを作ってみた3

銀杏パークに行ってきました。この異常の暑さで銀杏の葉は青々していました。柴犬もこの暑さでくたびれた顔しています。
概要
前回は、「WebView」を利用して「JPG」ファイルと書き出しましたが、「PDF」ファイルの書き出しを試みました。
何とかできましたので記録することにしました。
調べてみたところ Android にも「Canvas」がありました。
よく調べないといけないですね。
今回お世話になりました本です。
WINGSプロジェクト 齊藤 新三(著), 山田 祥寛(監修)
2023年10月26日現在
次に紹介する本はちょっと過激な表紙ですが、本の内容はまじめてよく理解できる書き方をしています。先の「Androidアプリ開発」で飛ばしているところを丁寧に説明しているので、これで理解が早まりました。お勧めです。
しかもこれが100円で買え、ボリュームがすごい量です。なので著者に感謝です。
MainActivity.javaに追加したコード
public void generatePdf() {
// PDFドキュメント生成用のクラスを作成
PdfDocument pdfDocument = new PdfDocument();
PdfDocument.Page page;
Canvas canvas;
Matrix matrix = new Matrix();
Paint paint1 = new Paint();
Paint paint2 = new Paint();
Paint paint3 = new Paint();
int pos = 0;
int pages = 0;
int[] bitmapSize = { 400, 400 };
Bitmap bitmap = BitmapFactory.decodeResource( getResources(), R.drawable.sample);
// A4横(72dpi)
int a4X = 595;
// A4縦(72dpi)
int a4Y = 842;
// 指定の縦横幅(ピクセル)でページを作る
page = pdfDocument.startPage(new PdfDocument.PageInfo.Builder(a4X, a4Y, pages).create());
// ページに書き込むためのキャンバスを取得する
canvas = page.getCanvas();
// 画像を書き込む
Paint paint = new Paint();
canvas.drawBitmap(Bitmap.createBitmap(bitmap, 0, 0, bitmapSize[0], bitmapSize[1], matrix, true),
100, 100, null);
// 文字を書き込む
Paint text = new Paint();
text.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
text.setColor(context.getColor(R.color.theme500));
text.setTextSize(20);
text.setTextAlign(Paint.Align.LEFT);
canvas.drawText("テスト!!テスト!!!",10, 100, text);
paint1.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
paint1.setColor(context.getColor(R.color.theme600));
paint1.setTextSize(20);
paint1.setTextAlign(Paint.Align.LEFT);
String buf1 = tvTellop1.getText().toString() + ":" + etInput1.getText().toString();
canvas.drawText(buf1,10, 200, paint1);
paint2.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
paint2.setColor(context.getColor(R.color.theme700));
paint2.setTextSize(30);
paint2.setTextAlign(Paint.Align.CENTER);
String buf2 = tvTellop2.getText().toString() + ":" + etInput2.getText().toString();
canvas.drawText(buf2,10, 300, paint2);
paint3.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
paint3.setColor(context.getColor(R.color.theme800));
paint3.setTextSize(15);
paint3.setTextAlign(Paint.Align.RIGHT);
String buf3 = tvTellop3.getText().toString() + ":" + etInput3.getText().toString();
canvas.drawText(buf3,10, 400, paint3);
// ページを閉じる
pdfDocument.finishPage(page);
try {
// ファイルを開いてPDFを書き込む
// FileOutputStream fileOutputStream = (FileOutputStream) context.getContentResolver().openOutputStream(uri, "wt");
// pdfDocument.writeTo(fileOutputStream);
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS);
path.mkdirs();
File file = new File(path, getPicFileName());
pdfDocument.writeTo(new FileOutputStream(file));
Toast toast = Toast.makeText(context, context.getString(R.string.export_pdf), Toast.LENGTH_SHORT);
toast.show();
} catch (IOException e) {
e.printStackTrace();
}
pdfDocument.close();
}
// 書き込むファイル名を作成します
protected String getPicFileName(){
Calendar c = Calendar.getInstance();
String s = c.get(Calendar.YEAR)
+ "_" + (c.get(Calendar.MONTH)+1)
+ "_" + c.get(Calendar.DAY_OF_MONTH)
+ "_" + c.get(Calendar.HOUR_OF_DAY)
+ "_" + c.get(Calendar.MINUTE)
+ "_" + c.get(Calendar.SECOND)
+ ".pdf";
return s;
}
「import」部分です。
import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.pdf.PdfDocument; import android.net.Uri; import android.os.Environment; import android.print.PrintDocumentInfo; import android.print.pdf.PrintedPdfDocument; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.os.Bundle; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Calendar;
sample.bmp
PDFは少し欠けてしまいました。設定がまずかったです。

strings.xml
<resources>
<string name="app_name">Main</string>
<string name="print_page">Print</string>
<string name="bt_next">次へ</string>
<string name="bt_print">プリント</string>
<string name="tv_tellop1">項目1</string>
<string name="et_input1">入力1</string>
<string name="tv_tellop2">項目2</string>
<string name="et_input2">入力2</string>
<string name="tv_tellop3">項目3</string>
<string name="et_input3">入力3</string>
<string name="pdf_error">PDF出力するデータがありません</string>
<string name="menu_pdf">PDF出力</string>
<string name="export_pdf">PDFファイルを出力しました</string>
</resources>
colors.xml
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="theme500">#FF5722</color>
<color name="theme600">#2247FF</color>
<color name="theme700">#43FF22</color>
<color name="theme800">#FFE922</color>
<color name="grey800">#404040</color>
<color name="grey002">#20FEFEFE</color>
</resources>
カラーの設定は楽です。
左の色のついた四角をクリックすれば色の作成ダイヤログが開きます。

結果
左はスマホの「Document」を開いたところです。
テストで何回か実行していますのでPDFが溜まっています。
右はその中の一つを開いてみました。
少しテキストの位置の設定が悪いところがありますが調整すれば使えます。
