Sibainu Relax Room

愛犬の柴犬とともに過ごす部屋

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

昨日の夜の柴犬との散歩です。11月11日に始まるイルミネーションの試験的な点灯が気になってしばらく見つめていました。

概要

AndroidStudio がなかなか進みません。

PDF の調整と、WebView に画像を入れてみました。

画像はインターネットの画像しか使えないようです。

さらにいろいろ試してみたいと思います。

次に紹介する本はちょっと過激な表紙ですが、本の内容はまじめてよく理解できる書き方をしています。先の「Androidアプリ開発」で飛ばしているところを丁寧に説明しているので、これで理解が早まりました。お勧めです。

しかもこれが100円で買え、ボリュームがすごい量です。なので著者に感謝です。

PrintActivity.java

PDF の調整と WebView に画像を入れてみました。

スマホ本体に保存された画像を使う方法を今のところ見いだせていないので、ネットの画像を使って表示しています。

ですので、スマホ本体の画像がURLで表現できれば使えますので今後調べます。

copy

package siba.inu.android.sample;

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.Rect;
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;

public class MainActivity extends AppCompatActivity {

    private Context context=MainActivity.this;
    private TextView tvTellop1;
    private TextView tvTellop2;
    private TextView tvTellop3;
    private EditText etInput1;
    private EditText etInput2;
    private EditText etInput3;
    private Button btNext;
    private ClickListener listener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvTellop1=findViewById(R.id.tvTellop1);
        tvTellop2=findViewById(R.id.tvTellop2);
        tvTellop3=findViewById(R.id.tvTellop3);
        etInput1=findViewById(R.id.etInput1);
        etInput2=findViewById(R.id.etInput2);
        etInput3=findViewById(R.id.etInput3);
        btNext=findViewById(R.id.btnext);
        listener= new ClickListener();
        btNext.setOnClickListener(listener);

    }

// クリック時のリスナーを作成します。
    private class ClickListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            generatePdf();
            toNext();
        }
    }

// 画面を遷移させる関数です。
    public void toNext(){

        Intent i=new Intent(this, PrintActivity.class);

        // 遷移した画面で表現するHTML文を作成します。
        // 画像はスマホ本体に保存されたものを使えませんので、ネット経由で表示します。
        // ですので、スマホ本体の画像がURLで表現できれば使えますので今後調べます。
        String htmlDocument = "<html><body><h1>Test Content</h1>"
                + "<p>Testing, testing, testing...</p>"
                + "<p>" + tvTellop1.getText().toString() + ":" + etInput1.getText().toString() + "</p>"
                + "<p>" + tvTellop2.getText().toString() + ":" + etInput2.getText().toString() + "</p>"
                + "<p>" + tvTellop3.getText().toString() + ":" + etInput3.getText().toString() + "</p>"
                + "<img src=\"https://www.sibainu.org/wordpress/wp-content/uploads/2023/11/sibainu20231106eye.jpg\""
                + "width=\"50%\">"
                + "</body></html>";

        i.putExtra("printdoc",htmlDocument);

        startActivity(i);
    }

// PDFを作成する関数です。
    public void generatePdf() {
        // PDFドキュメント生成用のクラスを作成します。
        PdfDocument pdfDocument = new PdfDocument();
        Resources r;
        PdfDocument.Page page;
        Canvas canvas;
        int width;
        int height;
        Matrix matrix = new Matrix();
        Paint text = new Paint();
        Paint paint1 = new Paint();
        Paint paint2 = new Paint();
        Paint paint3 = new Paint();
        int pages = 0;
        r=getResources();
        Bitmap bitmap = BitmapFactory.decodeResource(r, R.drawable.sample);
        width = bitmap.getWidth();
        height = bitmap.getHeight();
        // A4横(72dpi)
        int a4X = 595;
        // A4縦(72dpi)
        int a4Y = 842;
        // roll1201横(72dpi)
        int roll1201X=90;
        // roll1201縦(72dpi)
        int roll1201Y=29;
        // 指定の縦横幅(ピクセル)でページを作ります。
        //page = pdfDocument.startPage(new PdfDocument.PageInfo.Builder(a4X, a4Y, pages).create());
        page = pdfDocument.startPage(new PdfDocument.PageInfo.Builder(roll1201X, roll1201Y, pages).create());
        // ページに書き込むためのキャンバスを取得する
        canvas = page.getCanvas();

        // 画像を書き込みます
        // 0.1倍調整
        matrix.postScale(0.1f, 0.1f);
        // canvas.drawBitmap(Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true),
        //         100, 100, null);
        canvas.drawBitmap(bitmap, new Rect(0, 0, width, height),
                new Rect(10, 10, width / 15 + 10, height / 15 + 10), null);

        // 文字を書き込みます。
        text.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
        text.setColor(context.getColor(R.color.theme500));
        text.setTextSize(5);
        text.setTextAlign(Paint.Align.LEFT);
        canvas.drawText("テスト!!テスト!!!",10, 5, text);

        paint1.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
        paint1.setColor(context.getColor(R.color.theme600));
        paint1.setTextSize(5);
        paint1.setTextAlign(Paint.Align.LEFT);
        String buf1 = tvTellop1.getText().toString() + ":" + etInput1.getText().toString();
        canvas.drawText(buf1,10, 12, paint1);

        paint2.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
        paint2.setColor(context.getColor(R.color.theme700));
        paint2.setTextSize(5);
        paint2.setTextAlign(Paint.Align.LEFT);
        String buf2 = tvTellop2.getText().toString() + ":" + etInput2.getText().toString();
        canvas.drawText(buf2,(roll1201X - (int) paint2.measureText(buf2))/ 2, 17, paint2);

        paint3.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));
        paint3.setColor(context.getColor(R.color.theme800));
        paint3.setTextSize(5);
        paint3.setTextAlign(Paint.Align.LEFT);
        String buf3 = tvTellop3.getText().toString() + ":" + etInput3.getText().toString();
        canvas.drawText(buf3, roll1201X- (int) paint3.measureText(buf3), 24, 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;
    }
}

メイン画面と遷移後の画面

左が起動直後で、右がボタン「次へ」を押下した後の遷移後の画面です。

作成された JPG と PDF

左が遷移後の画面をJPGで保存した画像で、右が横90dp・縦29dpで作成したPDFの閲覧をスナップショットしたものです。