投稿者「shoarai」のアーカイブ

源泉徴収票に書いてあること

は、勤務先から受け取る給与や賞与の1年間の合計金額です。
給与を渡す会社側の視点なので”支払”金額となってますが、受け取る側から見ると”収入”金額になります。1年間の収入なので、いわゆる「年収」はこれのことです。

は、収入のうち税金を計算する前の金額です。
の金額」と「以下の表」を使って求められます。

画像の例でいうと、は 400万円 なので、以下の表の5行目にあたります。これを計算すると、「400万円 ✕ 20% + 44万円 = 124万円」です。からこの金額を引くと、になります。

 440万円()ー 124万円 = 216万円(

収入金額給与取得控除額
〜 162.5万円55万円
162.5万円 〜 180万円収入金額 ✕ 40% ー 10万円
180万円 〜 360万円収入金額 ✕ 30% + 8万円
360万円 〜 660万円収入金額 ✕ 20% +44万円
660万円 〜 850万円収入金額 ✕ 10% + 110万円
850万円 〜 195万円
給与所得控除額

は、安くなる税金の金額です。
保険料を払っていたり、子供がいる場合に税金が安くなることがあります。

画像の例でいうと、「の金額」と48万円を足すとになります。

 90万円()+ 48万円 = 138万円(

※この48万円は年によって金額が違います。2020年から48万円ですが、それ以前は38万円です。

は、払う税金の金額です。
この金額は、ベースとなる税金(所得税)と、東日本大震災からの復興のための税金(復興特別所得税)の合計です。
復興特別所得税は、2013年から2037年までかかります。

まずはこれまでの金額を使って、税金の対象となる金額を計算します。画像の例でいうと、「216万円()ー 138万円()= 78万円」です。次に、以下の表を使って所得税を計算します。

 78万円 ✕ 5% = 3万9,000円(所得税)

課税所得金額税率控除額
〜 195万円5%なし
195万円 〜 330万円10%9万7,000円
330万円 〜 695万円20%42万7,000円
695万円 〜 900万円23%63万6,000円
所得税の速算票(一部抜粋)

そして、所得税から復興特別所得税を計算します。

 3万9,000円(所得税) ✕ 2.1% = 819円復興特別所得税)

所得税と復興特別所得税を足すと、になります。

 3万9,000円(所得税) + 819円(復興特別所得税)= 3万9,819円
                         → 3万9,800円(
                         (100円未満は切り捨て)

※本記事は、2021年11月1日時点の情報です。税金の金額や計算式は、今後変わる可能性があります。

M5StickC Plusで在宅勤務用の環境モニターを作った

先日、M5StickC Plusを使ってCO2を測りました。この記事ではその続きとして、温度、湿度、気圧も測りました。

完成形

完成形はこちらです。M5EnvMonitorと名付けました。

ソースコードはGitHubで公開しています。

https://github.com/shoarai/M5EnvMonitor

開発過程

CO2の計測までは、以下の記事で紹介しています。

追加の部品

PlatformIOの環境構築

以前は開発環境としてArduino IDEを使っていたのですが、今回からPlatformIOとVisual Studio Code(VSCode)を使うことにしました。フォーマットの自動化やGitとの連携をしたかったのが理由です。

1. VSCodeと、PlatformIOというVSCode拡張機能をインストールする。

2. PlatformIOを開き、Home画面のNew Projectボタンから新規プロジェクトを作成する。

  • Name: プロジェクト名。ここではM5EnvMonitorとする。
  • Board:M5Stick-C(M5Stack)
  • Framework:Arduino
  • Location:任意のディレクトリ

これでプロジェクトが作成できました。この時点でGitを初期化、コミットしておきます。

Env IIの利用

Libraries画面で必要なプラグインを検索し、プロジェクトにインストールする。

ライブラリのインストールは、platform.ioファイルのlib_depsに直接記載することも可能です。また、Arduinoライブラリとして公開されていなくても、GitHubで公開されているライブラリをインストールすることもできます。以下の最後の行のように、GitHubのURLを記載すればOKです。

[env:m5stick-c]
platform = espressif32
board = m5stick-c
framework = arduino
lib_deps =
	m5stack/M5StickCPlus@^0.0.2
	adafruit/Adafruit Unified Sensor@^1.1.4
	adafruit/Adafruit BMP280 Library@^2.4.2
	ambientdatainc/Ambient ESP32 ESP8266 lib@^1.0.1
	https://github.com/nara256/mhz19_uart

ENV IIの利用

ENV IIのサンプルコードを使って、ENV IIの測定値を表示します。Adafruit_Sensor.hはAdafruit Unified Sensorライブラリに含まれていたので、ライブラリをインストールしました。ENVII.inoの内容をsrc/main.cppコピーしてビルド、アップロードします。

カスタマイズ

計測値の表示レイアウトを調整したり、M5StickC Plusの情報表示を追加しました。
※CO2センサーが壊れているので、繋いでいない状態です;なのでCO2は-1になってます。

画面仕様は以下の通り。

  • 画面右上:充電状態。”Full”は満充電。”USB”は充電中。
  • 画面右上:電池の残量。
  • 画面左の色:測定値が快適かどうか。緑なら問題なし。赤は問題あり。
          ・17℃ < 温度 < 28℃なら緑、それ以外は赤
          ・40% < 湿度 < 60なら緑、それ以外は赤
  • 画面右下:Ambientへのデータ送信の結果。成功なら表示なし、失敗なら”Send NG”

使っていくうちにまたいろいろ変えるかもしれません。

WordPressをAMP化し、Gistの埋め込みに対応した

このサイトはWordPressを使って作成していますが、表示速度の向上やSEO対策のためにAMP化しました。

WordPressのAMP化

AMP化は、以下のWordPress公式プラグインを使って簡単に実現できました。

AMP

またGoogle Analyticsの設定は、「AMP → 設定 → アナリティクス」の「種類:」に「googleanalytics」と入力します。すると「JSON構成:」が自動入力されるので、「UA-」で始まるトラッキングIDを設定すればOKです。

しかし、AMP化によって一つ問題が発生しました。AMP化したことにより、Gistの埋め込みコードが表示されなくなってしまったのです。

GistのAMP対応

Gistの埋め込みコードを、AMP化したWordPressに表示する方法として、ショートコードを使う方法を紹介します。そのために、JetpackというこれまたWordPress公式プラグインを使います。

Jetpackの「設定 → 執筆」にある「ショートコードを使って作成し、人気サイトからメディアを埋め込む」にチェックを入れます。これにより、ショートコードの機能が使えるようになります。

AMP化前は、カスタムHTMLで以下のコードを記載すればGistを埋め込めました。

<script src="https://gist.github.com/shoarai/a98cf027914d43139f4dbe579f726b8b.js"></script>

AMP化後は、ショートコードで以下のテキストを記載すればGistを埋め込めます。

[gist]a98cf027914d43139f4dbe579f726b8b[/gist]

ちなみに、ショートコードはGist以外にも、Facebookの投稿やTwitterのツイートなども埋め込めます。利用可能なショートコードは以下で確認できます。
https://jetpack.com/support/shortcode-embeds/

M5StickC PlusとAmbientでCO2の推移を可視化した

前回の記事では、M5StickC PlusとMH-Z19CでCO2濃度を測定し、画面に表示しました。今回は、CO濃度の推移をチャートで見れるようにするため、測定値をクラウドに蓄積して可視化してみました。

クラウドサービス

データを蓄積するクラウドサービスはAmbientを使いました。無料枠でも、8チャネル×8種類のデータ、データの保存期間1年間と、個人で使うには十分すぎるサービスです。有料版は、データの受信監視や通知が利用できるようです。

クラウドサービスなので、M5StickC Plusからデータを送信するには、インターネットに繋がるWiFiのアクセスポイントが必要です。

セットアップ

Ambient公式ドキュメントの以下の手順で、チャネル生成まで行います。

  1. ユーザー登録(無料)
  2. チャネル生成

生成したチャネルの「チャネル設定」で、以下の通りデータ名を変更しておきます。

  • データー1:CO2
  • データー2:温度

Ambientのライブラリは、Arduino IDEのメニューバーの「ツール → ライブラリを管理…」で、「ambient」と検索すると見つかります。ライブラリ名は「Ambient ESP32 ESP8266 lib」です。バージョンは1.0.1でした。

ソースコードの更新

前回の記事のソースコードに、以下のコメント部分を追記します。「…」の部分は各自の環境に合わせて、WiFiのアクセスポイントの情報と、生成したチャネルのチャネルIDとライトキーを記載します。

#include <M5StickCPlus.h>
#include <MHZ19_uart.h>
// Ambientライブラリをインクルードする。
#include "Ambient.h"
const int rx_pin = 36;
const int tx_pin = 26;
// WiFiアクセスポイントのSSIDとパスワードを設定する。
const char* ssid = "...";
const char* password = "...";
// Ambientで作ったチャネルのチャネルIDとライトキーを設定する。
unsigned int channelId = ...;
const char* writeKey = "...";
MHZ19_uart mhz19;
// WiFiとAmbientの変数を宣言する。
WiFiClient client;
Ambient ambient;
void setup()
{
M5.begin();
pinMode(36, INPUT);
gpio_pulldown_dis(GPIO_NUM_25);
gpio_pullup_dis(GPIO_NUM_25);
Serial.begin(9600);
mhz19.begin(rx_pin, tx_pin);
mhz19.setAutoCalibration(false);
M5.Lcd.setRotation(3);
M5.Lcd.setTextSize(4);
// Wi-Fiアクセスポイントに接続する。
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
M5.Lcd.println("WiFi connected.");
// Ambientを初期化する。
ambient.begin(channelId, writeKey, &client);
M5.Lcd.println("MH-Z19 is warming up now.");
delay(10 * 1000);
}
void loop()
{
int co2ppm = mhz19.getCO2PPM();
int temp = mhz19.getTemperature();
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
M5.Lcd.print("co2: ");
M5.Lcd.println(co2ppm);
M5.Lcd.print("temp: ");
M5.Lcd.println(temp);
// 測定値をAmbientに送信する。
ambient.set(1, co2ppm);
ambient.set(2, temp);
ambient.send();
delay(5000);
}

チャートの確認

Ambientでデータを送信したチャネルを開くと、CO2濃度の推移を可視化できました!
左のCO2のチャートを見ると、15:30:00過ぎに600ppmぐらいまで下がっています。これはエアコンをつけて窓を締め切った部屋から、ベランダに出たためです。

回路図をdraw.ioで描いてWordPressで表示する方法

以下の記事でギターアンプの回路を設計しました。回路図はdraw.ioを使って描き、描いた図をWordPressで表示しました。その時の手順を紹介します。

回路図をdraw.ioで描く

draw.ioを開いたら「Create New Diagram」を選び、図のテンプレートを選びます。ここで「Engineering → Electrical 1」を選ぶと、抵抗やコンデンサ、オペアンプやトランジスタの図が左サイドバーに表示されるので、すぐに回路図を描き始められます。

図の描き方はここでは説明しません。わりと直感的に描けるので、そんなに困らないと思います。

回路図をWordPressで表示する

以下の手順で、draw.ioで作成した図をWordPressで表示できます。手順はdraw.io公式の記事にある通りです。

  1. 右クリックして「Select All」を選び、右サイドバーの「Text → Formatted Text」のチェックを外す。
  2. 右クリックして「Select Vertices」を選び、右サイドバーの「Text → Word Wrap」のチェックを外す。
  3. 「File → Embed → SVG…」を選ぶ。
  4. 「Lightbox」のチェックを外して、「Embed」を押し、「Copy」を押してSVGのコードをコピーする。
  5. コピーしたSVGをWordPressにカスタムHTMLとして貼る。

以下のように回路図が表示できます。

4.7kΩ220μF100Ω10μF10μF9V0.047μF220μF1kΩB100ΩB8Ω0.5WLM386N-1Blue LED154236876.3mmStereo Jack

はじめてのM5StickC PlusでCO2を測った

先日はじめてギターアンプを自作しましたが、今回はM5StickC Plusを使った電子工作です。在宅勤務が今後も続きそうなので、自宅の快適さを測りたいと思い、集中力に影響があると言われているCO2の濃度を測ることにしました。

デバイスと部品

DETEKER 260本多色デュポンワイヤー

MH-Z19Bという下位バージョンのものもありますが、フェイク品が出回っているそうで、秋月で確実に買えるMH-Z19Cにしました。その他にPC、PCとM5StickC Plusを繋ぐためのUSB Type−Cケーブルが必要です。

環境構築

  • Arduino IDEをインストールしてセットアップ

Arduino IDEのインストールやセットアップは、Interfaceの以下の記事を参考にしました。実施するのはステップ1、2だけです。
M5StickC Plusの開発環境(Arduino IDE)構築の手順 – Interface

記事ではWindows10で、僕はMacで実施しましたが問題ありませんでした。Macの場合は、zipファイルがダウンロードされ、解凍するとappファイルができます。また、記事中にある「ESP32パッケージのJSONファイルURL」は以下になります。コピペ用にどうぞ。
https://dl.espressif.com/dl/package_esp32_index.json

バージョンは以下の通り。

  • Arduino IDE:1.8.15
  • ESP32パッケージ:1.0.6

PlatformIOという開発環境もあるようですが、初心者なのでまずは基本的な環境であるArduino IDEを使ってみます。

サンプルプログラムの実行

試しにサンプルプログラムを動かしてみます。メニューバーの「ファイル → スケッチ例 → M5StickCPlus → Basics → IMU」を選ぶと、サンプルプログラムのソースコードが表示されます。画面左上の「マイコンボードに書き込む」ボタンを押して、プログラムをマイコンに書き込みます。IMUというのは加速度センサーのサンプルです。

初めて書き込みを実行したときは、「シリアルポートが選択されていません。」というエラーが表示されました。「cu.usbserial-…」というポートを選んで再度実行したところ、正常に書き込め、プログラム実行できました。

CO2濃度の計測

M5StickC PlusとMH-Z19Cを接続します。以下のピン同士をジャンプワイヤー オス-メスで繋げます。

M5StickC PlusのピンMH-Z19Cのピン
GNDGND
5V→VIN
G26Rx
G36(G36/G25と記載されているピン)Tx

プログラムにはmhz19_uartというライブラリを使わせてもらいます。zipファイルをダウンロードし、メニューバーの「スケッチ → ライブラリのインクルード → .ZIP形式のライブラリをインストール…」からインストールします。

このライブラリには実行サンプルコードも付属しているので、使わせてもらいましょう。メニューバーの「ファイル → スケッチ例 → MHZ19_uart → MHZ19_getco2」を選ぶと、サンプルコードが表示されます。ただし、まだマイコンに書き込みません。下記のコメント記載部分を追記、変更してからマイコンに書き込みます。

// 追記:M5StickC Plusで必要なヘッダをインクルードする。
#include <M5StickCPlus.h>
#include <MHZ19_uart.h>
// 変更:接続するピンの番号を変更する。
const int rx_pin = 36;
const int tx_pin = 26;
MHZ19_uart mhz19;
void setup()
{
// 追記:M5StickC Plusの初期化と、G36ピンを使うためにG25ピンをフローティングにする。
M5.begin();
pinMode(36, INPUT);
gpio_pulldown_dis(GPIO_NUM_25);
gpio_pullup_dis(GPIO_NUM_25);
Serial.begin(9600);
mhz19.begin(rx_pin, tx_pin);
mhz19.setAutoCalibration(false);
// 追記:デフォルトだと画面が見づらいので、横向き表示でフォントを大きくする。
M5.Lcd.setRotation(3);
M5.Lcd.setTextSize(4);
// 変更:文字を画面に表示する。
M5.Lcd.println("MH-Z19 is warming up now.");
delay(10 * 1000);
}
void loop()
{
int co2ppm = mhz19.getCO2PPM();
int temp = mhz19.getTemperature();
// 追記:画面の表示とカーソルを初期化することで、前回の文字の表示を消す。
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
// 変更:文字を画面に表示する。
M5.Lcd.print("co2: ");
M5.Lcd.println(co2ppm);
M5.Lcd.print("temp: ");
M5.Lcd.println(temp);
delay(5000);
}

CO2濃度を測定できました!!ついでに温度も!

外気のCO2濃度は400ppm前後だそうなので、870ppmは少し高めでしょうか。エアコンをつけて窓を締め切っている状態なので、感覚的には正しいように思います。
息を吹きかけてみると、10秒後ぐらいに3,000ppmぐらいになりました。息に反応する程度には計測できているようです。

とりあえず測定はできたので今回はここまで。この後はMH-Z19Cのキャリブレーションや画面表示のデザイン、クラウドへのアップロードなどを試してみたいと思います。

電子工作をなるべくお金をかけずに始める方法

先日、初めて電子工作をしました。電子工作を始めるにはいろいろな部品や道具を準備する必要があり、お金がかかります。ただ、いきなりすべての道具を揃えるのは金銭的にもキビしいし、すぐ飽きてしまうかも。。そこで、必要になったら買い足していくことにしました。その進め方のステップについて紹介します。

今回、僕はギターアンプを作ったので、他の電子工作には当てはまらかもしれませんが、進め方は多少参考になるかもしれません。

注意事項

電子工作は工具の扱いや配線作業において危険がともなうため、怪我などに十分ご注意ください。本記事の内容を参考にして発生した事故などは、shoaraiは一切責任を負いません。自己責任でお願いいたします。

作ったもの

こちらが今回作ったギターアンプです。機能や回路図は以下の記事で紹介しています。

始め方〜完成までのステップ

  1. 作りたい回路を調べる。
  2. ブレッドボードで回路を組むための部品を買う。
  3. 回路を入れる箱を買う。
  4. 箱の穴を開けるための道具を買う。
  5. 箱に回路を組むための部品を買う。

作りたい回路を調べる。

作りたい回路は人によるので、ここでは詳しく説明しません。今回はギターアンプを作りたかったので、とりあえず「ギターアンプ 自作」でGoogle検索。個人ブログで作り方が紹介されていますが、紹介されている回路が正しいのかどうかわからなかったので、ある程度信頼できる本を購入しました。

ブレッドボードで回路を組むための部品を買う。

なぜ今回ギターアンプを作りたいかというと、結局のところ、ギターの音を出したいわけです。最悪、回路が箱に入っておらず剥き出しの状態でも問題ありません。そこで、まずはブレッドボード上で回路を組んで音を出すことを目標とします。

ブレッドボード上で回路を組むために、僕が買った部品は以下の通り。

  • 回路部品(入力ジャック、スピーカー、抵抗やコンデンサなど、回路によって異なる)
  • ブレッドボード
  • 9V電池
  • 電池スナップ
  • ジャンパーワイヤー
  • クリップ付コード

実はこれだけあれば、回路を組んで音を出すことができます。はんだごてやニッパーがなくても回路は組めるんです。

上の画像がブレッドボード上に回路を組んで音が出る状態です。(画像からはわかりにくいですが;)入力ジャックとスピーカーは、ジャンプワイヤーとクリップ付コードでブレッドボードに繋いでいます。クリップ付コードで部品を挟むときは、なるべくコード同士が触れないようにカバー部分を深くかぶせるといいです。

ボリュームもクリップ付コードで繋げましたが、問題なく動きました。クリップが隣同士触れないように注意!

最低限、音が出るところまでできたら、抵抗やコンデンサの値を変えたり、部品の構成を変えたりして、音がどう変わるか試してみました。抵抗やコンデンサは複数セットになっているものを買っておきました。

この状態でも問題ないかもしれませんが、ブレッドボードだとスペースを食うので多少邪魔だったり、箱に入れないとボリュームが回しにくいです。やっぱり箱に入れたい!となったタイミングで箱を探しました。

回路を入れる箱を買う。

箱探しがなかなか難しい。今回作るLM386を使ったギターアンプは、スモーキーアンプという名前で知られていて、名前の通りタバコの箱に入るぐらい小さくできます。つまり紙の箱でも問題ないようです。ただ紙だと耐久性に問題あるし、今回は音量やゲイン調整用のボリュームを付けたかったので、ポリケースにしました。

100均でポリケースを探しまくりました。結果、見つけたのはこちら。

本体がポリプロピレン、蓋がポリエステルのケースです。3つ入りでしたが、1つ使ったので画像は2つだけ写ってます。なかなかちょうどいいサイズの箱が見つからないかもしれませんが、とりあえず買ってみて部品をあててみるのがいいかもしれません。100円だし、ケースなので他の用途にも使えそうなので。

箱の穴を開けるための道具を買う。

箱を買ったら、その箱に穴を開けるための道具を調べて買います。エフェクター製作だとよく使われるのはアルミダイキャストケースですが、今回はポリケースなので必要な道具は少ないです。

僕が買った道具は以下の通り。

  • ピンバイス本体
  • ピンバイスに取り付けるドリル
  • リーマー

ピンバイスで穴を開け、リーマーで穴を広げます。

箱に回路を組むための道具や部品を買う。

箱に穴を開けられたら、ついにはんだごてを買って基板上で回路を組みます。

僕が買った道具は以下の通り。

  • ユニバーサル基板
  • 配線材
  • ニッパー
  • はんだごて
  • こて台
  • はんだ
  • はんだ吸取線

ユニバーサル基盤の上に回路を組み、配線材で配線していきます。

↑初めてのはんだ付け。

この記事の冒頭でも説明しましたが、完成品は以下の記事で紹介してます。

LM386でギターアンプを作った

日頃、仕事やプライベートでプログラミングをしていますが、今回始めて電子工作でギターアンプを作りました。

注意事項

電子工作は工具の扱いや配線作業において危険がともなうため、怪我などに十分ご注意ください。本記事の内容を参考にして発生した事故などは、shoaraiは一切責任を負いません。自己責任でお願いいたします。

作りたいもの

ギターは持っているのですが、アンプは随分前に売ってしまい、PCに繋いで音を出していました。ただ毎回PCに繋ぐのは面倒なので、簡単に音出ししたいときのために、ギターに直差しできるような小型のアンプがほしいと思っていました。でもギターに直差しできて、かつスピーカーがついているアンプが売ってない。。ヘッドフォンを繋いで使うようなミニアンプはあるんですが。そこで、自分で作れないか調べたところ、わりと簡単にしかも安く作れるようなので試してみました。

作りたいもののイメージは以下の通り。

  • ちょっと弾きたいときに、ギターに直差しして使える。
  • 自分が聞こえればいいので、音量は小さくてもいい。
  • 音色は幅広く、クリーンも歪みも出したい。歪み具合は調整したい。

作ったもの

こちらが作成したギターアンプです。左上のトグルスイッチは電源、左下はゲインのON/OFF切り替えです。右上のつまみは音量、右下はゲインの調整になっています。ギターに直差ししたときに、右手でスピーカーを隠さずにつまみを調整できるように、右側につまみがくるように配置しました。電源を入れると青色LEDが光ります。ステレオジャックがあり、短いパッチケーブルを使ってギターと接続することができます。

ステレオジャックではなくステレオプラグを取り付けてギターに直差しできるようにすることも考えましたが、卓上に置いても使えるようにステレオジャックを付けました。

後で部品を交換したり修理したりできるように、グルーガンなど使わずにナットで部品を締めて取り付けました。

基盤上に部品をキツキツに詰めてますが、今後拡張したくなったときのためにまだカットしていません。

回路図

4.7kΩ220μF100Ω10μF10μF9V0.047μF220μF1kΩB100ΩB8Ω0.5WLM386N-1Blue LED154236876.3mmStereo Jack

回路にはLM386という小型パワーアンプICを使っています。抵抗やコンデンサなどの構成はほとんど公式のデータシートに記載されているものと同じです。違いとしては、音量とゲイン調整用のスイッチとボリューム、電源の状態確認用のLEDと抵抗をつけたぐらいです。また、5番ピンにある抵抗をデータシート記載の10Ωで試したところ、なぜか手前のコンデンサが異常に熱くなったので、100Ωに変えました。セラミックコンデンサを使っているからなのか、原因はわからず。LEDに繋ぐ抵抗は1kΩ、2.2kΩあたりも試したのですが、LEDの光が眩しすぎたので4.7kΩにしました。

振り返り

スピーカーをケースに取り付ける前と後で音を比べると、取り付けた後は少しこもった音になってしまいました。ケース本体の素材はポリプロピレン、蓋はポリエチレンなので、素材が原因なのか、ケースの穴が空いていない部分が影響しているのかわかりませんが、改善したいところです。スピーカーを覆っている部分をすべて穴開けしてもいいかもしれません。

配線が少し複雑になってしまった気がします。基盤のレイアウトを考えるときに、ケースに取り付けた部品の位置を考慮して配線しやすいようにすればよかったと思いました。

ボリュームのシャフトが少し長すぎるため、つまみからはみ出てしまっています。短く切るのは面倒ですし道具もないので、ボリュームとケースの間に何か挟んで高さを調整すれば解消するかも。

最後に、お気づきでしょうか?実はスピーカーを固定しているネジが1本足りません笑。これは買ってあったスピーカー抑え金具を急遽使ったのですが、そのネジが3本しかなかったためです。できれば4箇所とも別のネジを使いたいところです。

KotlinでToastをカスタマイズする

先日、ポップアップアラームという設定した時刻にポップアップを表示するアプリを作りました。このページではその中でもポップアップであるToastをカスタマイズして表示する処理について紹介します。

標準のToastを表示する

標準のToastは以下のコードで表示できます。

object ToastView {
    fun showToast(context: Context, message: String) {
        Toast.makeText(context, message, Toast.LENGTH_LONG).show()
    }
}

Toastをカスタマイズする

前述のような標準のToastだと目立たず、通知を見逃しやすいので、上の画像のようにToastのサイズやフォントサイズが大きい独自のレイアウトを作成します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">

    <TextView
        android:id="@+id/message"
        android:layout_width="320dp"
        android:layout_height="80dp"
        android:background="@drawable/toast_shape"
        android:gravity="center"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="@color/colorBase"
        android:textSize="40sp" />

</LinearLayout>

上記の独自レイアウトを表示します。

object ToastView {
    fun showToast(context: Context, message: String) {
        val inflate = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view = inflate.inflate(R.layout.toast, null)
        val textView = view.findViewById(R.id.message) as TextView
        textView.text = text

        Toast(context).run {
            this.view = view
            duration = Toast.LENGTH_LONG
            setGravity(Gravity.BOTTOM, 0, 250)
            show()
        }
    }
}

KotlinでAndroidの時刻を検知する

先日、ポップアップアラームという設定した時刻にポップアップを表示するアプリを作りました。このページではその中でも時刻の検知の処理について紹介します。

アラームを開始、停止する

Androidアプリで、ある時刻になったら処理を実行したい場合、AlarmManagerを使用します。厳密には、ある時刻になったことを通知するのではなく、ある時間を経過したことを通知できます。
今回はアラームアプリなので、ある程度正確な時間を通知できるsetExact()を呼びます。通知はBroadcastReceiverで受け取ります。
以下のクラスでは、アラームを開始して1度だけ通知します。別のアラームがすでに実行中なら、実行中のアラームは停止し、新しいアラームが開始されます。

object OnceAlarmManager {
    private const val REQUEST_CODE = 0
    private var alarmManager: AlarmManager? = null
    private var pendingIntent: PendingIntent? = null

    fun startAlarm(context: Context, calendar: Calendar) {
        alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, AlarmBroadcastReceiver::class.java)
        pendingIntent = PendingIntent.getBroadcast(
                context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager?.setExact(AlarmManager.RTC, calendar.timeInMillis, pendingIntent)
    }

    fun stopAlarm() {
        alarmManager?.cancel(pendingIntent)
    }
}

アラームアプリでは、1つのアラームで時刻通知したら次のアラームを開始する必要があるので、以下の通り、設定がONになっているアラームを開始します。

object WeeklyAlarmManager {
    fun startNextAlarm(context: Context) {
        var weeklyAlarms = WeeklyAlarmDataManager.weeklyAlarms
        if (WeeklyAlarmUtil.hasPowerOn(weeklyAlarms)) {
            val calendar = WeeklyAlarmUtil.getNextAlarmAsCalendar(weeklyAlarms)
            OnceAlarmManager.startAlarm(context, calendar)
        } else {
            OnceAlarmManager.stopAlarm()
        }
    }
}

アラーム通知を受け取る

前述の通り、BroadcastReceiverでアラーム通知を受け取ります。通知を受け取ったら、ポップアップを表示し、次のアラームを開始します。

class AlarmBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // Show popup.
        WeeklyAlarmManager.startNextAlarm(context)
    }
}

BroadcastReceiverをアプリに登録します。

<application
    ...
    <receiver android:name=".AlarmBroadcastReceiver">
    </receiver>
</application>

端末の再起動時やタイムゾーンの変更時に、アラームを再設定する

端末が再起動されたことやタイムゾーンが変更されたことを、BroadcastReceiverで受け取れるよう、actionを設定します。

<application
    ...
    <receiver android:name=".AlarmBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.TIMEZONE_CHANGED" />
            <action android:name="android.intent.action.TIME_SET" />
            <action android:name="android.intent.action.DATE_CHANGED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data
                android:path="com.isolity.toastalarm"
                android:scheme="package" />
        </intent-filter>
    </receiver>
</application>

上記で設定したactionの通知時にも、BroadcastReceiverのonReceive()が実行されます。アラーム通知の場合のみ(ここではactionがnullのとき)、ポップアップメッセージを表示します。

class AlarmBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == null) {
            // Show popup.
        }
        WeeklyAlarmManager.startNextAlarm(context)
    }
}

改善点

上記コードの改善点として、例えば、アラーム通知の判定がaction==nullだとわかりにくいので、アクション名つけた方がいいですね。あとはDIとかテストの方法はこれから調べます。

※Huaweiのスマホでの注意事項

Huaweiのスマホでは、以下の設定をしないと、アプリをKillしたあとにAlarmManagerの処理が止まってしまい、通知を受け取れなくなってしまいます。
設定 > 詳細設定 > バッテリーマネージャー > 保護されたアプリ > 対象のアプリをONにする
アプリごとに設定が必要なので、アプリを初めてインストールしたときに設定しておきます。僕はHuaweiのP8liteというスマホを使っていて、Emulatorでは動くのに実機で動かず非常に苦労しました。。Android開発者は各端末の知識も必要で大変ですね;