郵便番号検索
郵便番号を検索するアプリを作ります
このチュートリアルは初心者用ではありません。わかりにくい点などありましたらTwitter(@AppInventorJPN)またはFacebookページ、Facebookグループでお知らせください。随時更新します。標準のApp Inventor 2日本語版にSQLiteエクステンション、Zipエクステンション、Fileエクステンションを追加して使用しています。また、簡単なSQL言語を使用しています。App Inventor 2日本語版でどこまでのアプリを作れるかの実験だと考えてください。
更新履歴
- 初版 6/11/2019
- 二版 6/23/2019: Android 8.0.0以降のファイル書き込み許可をサポートするために更新。更新部分は都度その旨表示
- 三版 6/28/2019: フィードバックに基づき修正。更新部分は都度その旨表示
-
- いつもAfterUnzip内ImportDatabaseブロックのコメントを削除(aiaファイル内)
-
ソースコードのダウンロード
ソースコードを見ながらこのチュートリアルを読んだ方がわかりやすいと思います。ここをクリックして、コンピュータにソースコードをダウンロードしてからApp Inventorを開き、[ プロジェクト ]をクリックして[ローカルコンピュータからプロジェクト(.aia)をインポート]を選択し、ソースコードを選択してインポートしてください。
プログラムの構造(流れ)
SQLite自体はAndroidに標準装備です。
- あらかじめSQLiteの全国郵便番号データベースファイル(約12万件)を作成しておき、このファイルのzip圧縮ファイルをアセットとしてアプリに同封します。App Inventorではアセットとしてアップロードできるファイルのサイズは5MB程度が上限なので、圧縮しています。全国郵便番号データベースファイルの圧縮前ファイルサイズは8.5MB、圧縮後ファイルサイズは2.3MBです(三版修正:圧縮前->圧縮後)。万が一、アセットにファイルが無い時あるいは圧縮ファイルサイズが5MBを超えた時に備え、指定サーバーからzip圧縮ファイルをダウンロードして使用する機能も持っています。
- zip圧縮データベースファイルを解凍後、SQLiteにインポートし、データベースから都道府県のリストを作成してスピナーで表示します。
- 都道府県が選択されたら指定都道府県内の市町村リストを作成してスピナーで表示します。
- 市町村が選択されたら指定市町村内の町域リストを作成してスピナーで表示します。
- 町域が選択されたら定都道府県内指定市町村内指定町域の郵便番号を表示します。
郵便番号データベースファイルの作成(App Inventorは使いません)
https://www.post.japanpost.jp/zipcode/dl/roman-zip.html より全国一括のzip圧縮データファイルをダウンロードします。解凍後、表計算ソフトでローマ字列を削除し、代わりに通し番号の列を追加します。また文字コードがShift JISなので、UTF-8に変換してからcsvで保存します。
SQLiteデータベースのテーブル構造を定義し、以下のようにテーブルを作成するSQL文を作ります。
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS “japanzip" (
“id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
“zip" TEXT,
“prefs" TEXT,
“city" TEXT,
“street" TEXT
);
COMMIT;
SQLite GUI管理ツール(たとえばDB Browser for SQLite)を使って、テーブルを作成後csvファイルをインポートしてデータベースを作成します。ここではjapanzip.sqliteという名前でデータベースを作成し、japanzip.zipというファイルに圧縮しました。japanzip.zipはここからダウンロードしてください。
プロジェクトを作成
[プロジェクト]メニューから[プロジェクトを新規作成]を選択し、”ZipJapan”と名前を付けます。
エクテンションの追加
デザイン編集
レイアウトとコンポーネントの配置
下図のように縦並びレイアウトを配置した後、その中に横並びレイアウト、ラベル(タイトル、初期化ラベル、住所ラベル、郵便番号ラベル)、スピナー(選択ドロップダウン)、テキストボックス(郵便番号)、ボタン(初期化ボタン、リセット)を配置します。選択ドロップダウン、初期化ラベル、初期化ボタン、住所ラベル、郵便番号ラベル、郵便番号はプロパティの見えるからチェックを外してください。さらに、見えないコンポーネント類としてエクテンションに追加したSQLite、 TaifunZip,、TaifunFileと接続パレットにあるWeb、ストレージパレットにあるファイルをドラッグアンドドロップします。最後にファイルをアップロードをクリックしてjapanzip.zipをアップロードします。
初期化ラベル、初期化ボタン、ファイルコンポーネントは二版にて追加。
ブロック編集機能を使用したプログラミング
グローバル変数定義
三版でsreetを削除
- asset_fn: アセットにアップロードしたデータベースファイルのパス
- unzipped_fn: 解凍したデータベースファイルのパス
- unzip_fn: 解凍するためにはストレージ領域にファイルをコピーする必要があります。コピー先のデータベースファイルのパス。
- downloaded_fn: ダウンロードしたデータベースファイルのパス
- download_url: データベースファイルをダウンロードするURL
- 郵便番号:
- 町域選択: 町域選択メッセージ
- 市町村選択: 市町村選択メッセージ
- 都道府県選択: 都道府県選択メッセージ
- app_dbfile: SQLiteデータベースファイル名
- prefs: 選択済み都道府県格納用
- city: 選択済み市町村格納用
- column: 現在表示中のコラム名
都道府県リスト手続き
郵便番号検索の入り口である都道府県リストの表示は繰り返し行われるので手続きを作っています。やっていることはSQLiteデータベースをopenして"select distinct(prefs) from japanzip"と言うSQL文を実行して重複しない都道府県名を取得し、その結果からスピナーを作っています。後はグローバル変数とラベルの初期化作業をしています。二版で住所ラベル.見えるを追加しています。
スクリーン初期化に伴う作業など
Screen1.アクセス許可と初期化ボタン.クリックされたらの処理が二版にて大幅に変更されています。
- スクリーンが初期化したらファイルの読み書き許可を求めます。2回目以降の起動時はデータベースファイルが存在するので、直接都道府県リスト手続きを呼び出し、郵便番号検索を始めます。
- ファイルの読み書き許可が得られてなおかつデータベースファイルが存在しない場合は、以下のブロックで実際にzipjapan.txtと言う名前のダミーファイルの書き込みを行ってから初期化ラベルと初期化ボタンを表示します。Android 8.0.0以降ではファイルが実際に書き込まれるまでファイルの読み書き許可が実際には与えられないので、このような作業が必要になっています。
- 初期化ボタンがクリックされたらアセットにデータベースファイルが存在するか調べて、存在する場合はストレージ領域にファイルをコピーした後に解凍します。アセットにデータベースファイルが存在しない場合はWebコンポーネントを使ってデータベースファイルをダウンロードします。
- ダウンロードが成功したら、ストレージ領域にファイルをコピーした後に解凍します。
- 解凍が成功したらSQLiteにインポートします。
- リセットボタンがクリックされたら直接都道府県リスト手続きを呼び出し、最初から郵便番号検索をやり直します。
郵便番号検索
- 検索はスピナーで"項目が選択されたら"イベントで処理します。グローバル変数columnに入っているのがprefsならばSQLiteデータベースをopenして"select distinct(city) from japanzip where prefs=都道府県名"と言うSQL文を実行して選択された都道府県内の重複しない市町村名を取得し、その結果からスピナーを作っています。
- グローバル変数columnに入っているのがcityならばSQLiteデータベースをopenして"select distinct(street) from japanzip where city=市町村名 and prefs=都道府県名"と言うSQL文を実行して選択された都道府県内の選択された市町村内の重複しない町域名を取得し、その結果からスピナーを作っています。
- それ以外ならば選択された都道府県内の選択された市町村内の選択された町域の郵便番号を"select zip from japanzip where street=町域名 and city=市町村名 and prefs=都道府県名"と言うSQL文を実行して取得し、郵便番号のフォーマットを調整後に表示します。
スマホでテストしてください!