75才からのモバイルアプリ作成

MIT App Inventor 2 を使ったアプリ作成

MIT App Inventor 2で遊ぶ (PinpointWeather 2)

2025-04-03 11:33:52 | 日記

各種お天気情報の表示および対象都市の変更ボタンを実装。ちょっとは、お天気アプリらしくなった。

現在、日付の変更、選択にListPickerを利用しているが、前回のブログでも触れた通り、次回以降に「<」「>」のようなボタンで変更可能にしたい。それとも良い別の方法が見つかればその方法を採用したい。まだ、検討中の段階。

アプリ実行のビデオ:

スクリーン・デザイン:

test labelを非表示に。その他のお天気情報表示labelも初期段階でTextは全て空白に変更。お天気アイコンのみ初期画像を表示。

                                     

ブロック・コード:

変更および追加のブロック・コードのみ。

前回、対象都市名の頭文字を大文字に変更する関数を作成したが、対象都市名に限らず一般的に頭文字を大文字にできるような関数に変更した。考え方はいたってシンプルで、「tokyo」=> 「t」抽出 => 「T」に変更 => 「T」+「okyo」を結合 => 「Tokyo」とするもの。2つ以上の単語の場合は別途検討したい。(例えば、new york)

所定のURLに対しGET requestを行い、データ取得に成功した場合、使用するデータのリストを生成するための関数を追加した。

関数makeWeatherDescriptionList以降。

データ取得に失敗した時は、circularProgress アイコンを非表示にした方がベター。追加予定。

関数showWeatherData:

各データを所定のLabelに表示する関数。すでに各データの7日分のデータはそれぞれリスト形式で変数に格納済みなので、選択された日付のindexを利用して該当のデータを取り出す。

changeTargetCityButton 「+」をタップした時の動作:

関数initVarsを実行して、すべての変数を初期化の後、関数showCityInputDialogueを実行して都市名の入力を促す。

新たにデータリストを生成する関数:

関数自体の内容は、すでに前回のブログで紹介しているものと大差ないので関数makeFeelsLiketempList以外は省略。

要するに、以下JSONファイル(MIT App Inventor2でデコード前の生データ)の赤黄点線内のデータを取得して、7日分をリストにするもの。

例として関数makeFeelsLiketempListを折り畳まずに以下に表示。listの値=>index 1 (最初のデータ)のデータ=>feels_likeの値=>dayの値と言う具合にたどっていけば目的のデータを取得できる。この作業をデータの個数(1週間なので7つ)の回数だけ反復しリストを生成している。

                                     

 

                                            ***********************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (PinpointWeather 1)

 


MIT App Inventor 2で遊ぶ (PinpointWeather 1)

2025-03-28 21:25:21 | 日記

またまた、お天気アプリ。ブロック・コーディングの練習にもってこいの素材なので。

今回は、都市名をインプットしてお天気情報をゲットして、当日のデータを表示。その後は日付を選択してそれぞれの日付のデータを表示するというもの。「+」ボタンをタップすれば、他の都市名をインプットし当該都市のお天気情報をゲットできるもの。ほとんど目新しいものはなし。

今回はとりあえず、日付をゲット。これが問題なければ、次から日付をキーにお天気情報を抽出し、画面にレイアウトする予定。

日付を変更する場合は、ListView(リスト形式で日付を表示し、その中から該当の日付をタップして選択)で日付を選択しているが、これを「<」「>」のようなボタンで日付を変更するようにしたい。

アプリ実行のビデオ:

スクリーン・デザイン:

                                 

ブロッック・コード:

変数targetCity:お天気情報を取得する対象の都市名を格納

お天気情報を取得したい都市名をインプットするポップアップ

Screen1を初期化する際に上記関数showCityInput Dialogueを実行

変数cityNameInCapital:都市名の頭文字を大文字に変更した都市名を格納。「New York」のような2文字以上で構成されている都市名にはまだ対応していない。今回は、1文字の都市名にのみ対応。(これは不要な変換であるが、テスト的にブロック・コードで可能か試してみたもの。取得データの都市名を使えば、頭文字が大文字となっている。)

関数makeFirstLettercapital:

当該都市名の最初のアルファベットを大文字に変換し、2文字目以降と結合。

ポップアップにて「Cancel」をタップせず、都市名をインプットした場合、

1. 同都市名を変数targetCityに格納。

2. 処理の状況を示すCircularProgressを表示

3. 上記関数makeFirstLettercapitalと関数fetchDataを実行。

関数fetchData:

所定のURLに都市名をパラメーターにセットして、GET requestを行う。

変数dataIndex:1で初期化(一週間のデータの中で何番目のデータを表示するか、そのキーとなるindex)

変数lengthOfList:データの個数(一週間分なので7としても良いが)

変数JSONData:取得したデータをDictionary型でデコードした結果を格納

データの取得に成功した場合(responce codeが200の場合)の動作を設定。

1. 取得したデータをデコードの上、変数JSONDataに格納

2. 対象都市名の頭文字を大文字にしたものをtargetCityNameLabelに表示

3. データの個数を取得して変数lengthOfListに格納。

4. CircularProgressを無効して非表示とする

5. 関数makeDateListを事項してデータの日付のみを取り出したリストdateを作成

6. dateLabelにdateの一番最初の日付を表示

7. dateListPickerに日付のリストdateをセット。

8. 関数getLonLatを実行して、対象都市の緯度経度を取得

9. 関数prepareMapを実行して、上記対象都市の緯度経度を地図の中心点として地図を表示

10. 関数makeWeatherIconListを実行して、最初の日付の天気情報(アイコン)を取得

11. テスト用に設定しているtestLabel1にお天気アイコンのリストを表示

12. weatherIconImageにお天気アイコンの一番最初のアイコンを表示

      dataIndexの値をindexとしてweatherIconListよりiconのURLを取得し表示。

      dataIndexは初期値として1が設定してあるので、まずは最初のお天気情報(アイコン)が表示されることになる、

dateListPickerより日付を選択した際の動作設定

選択された日付がお天気情報の日付のリスト(date)の何番目なのかをチェックしてその番数を「dataIndex」に格納。

そして、あらためて新規に選択されたdateをdateLabelに表示。

以下は、日付、当該都市の緯度経度、お天気アイコンのリストを作成する関数。

日付のリストを作成:

注意すべきポイントは、MIT App Inventor 2では日付の単位はミリ秒なので、取得したUNIX Time(秒単位)を1000倍する必要があること。あとは、JSONファイルをたどっていけば日付のデータ (dt) を取得できる。

該当都市の緯度経度の取得:

JSONファイルをたどっていけばデータ (lon, lat) は取得できる。

お天気アイコンの取得:

JSONファイルを「icon」までたどっていけばファイル名(拡張子を除く)を取得できる。

あとは、 https://openweathermap.org/img/wn/ + ファイル名(例えば、晴れの場合は、01n)+ @2x.pngのように結合すれば画像のURLが生成される。このURLをweatherIconImage.Pictureにセットすれば画像を取得できる。

参考までにデコード前のJSONファイル(一部)は下記の通り。(このファイルは、昨年取得したもので今回使用したものとは異なるが構成は同じ。)

             

ここまで書いてきたが、ちょっとブロック・コードがおかしいような感じがする。日付のリストの変数が「date」と「dateList」の2つが存在する。でもアプリ自体は期待した通りに動く。いずれかが不要だと思うが。次回要チェック。

 


MIT App Inventor 2で遊ぶ (銀行屋さんごっこ 1 -おまけ-)

2025-03-19 20:44:05 | 日記

Firebaseのデータベースを利用したり、Public APIを使う、いわゆるネットを介したアプリはMIT App Inventor 2にとって難しい。

うまくいく時は非常にうまくいく。当たり前だけど!

前回は、口座を持っているKanooKanaのみのアプリ操作を録画したが、kanooKanaに加えKanooKeiのアプリ操作も録画し2人で使っているところをビデオに録画してみた。

スクリーン・デザインとブロック・コードは同じなので省略。

どうしても、(1回だけだけど)Warningが表示されてしまう。まあ、「Reload」ボタンをタップすれば正常に表示してくれるので、OKというところか。

アプリ実行のビデオ:

(ビデオの中で「KanooKen」と表示あるのは「KanooKei」の間違い)

KanooKanaとKanooKeiのスクリーンショットは以下の通り。(ビデオの画面と同じ)

              

なお、JSON File データは以下の通り。

ちょっと見にくいが、上記スクリーンに表示されているデータのもととなったJSONデータ。(KanooKanaの上記表示データはすべてが表示されておらず、下に隠れている部分もあり。)

             

 

                                           ********************************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (銀行屋さんごっこ 1)

 


MIT App Inventor 2で遊ぶ (銀行屋さんごっこ 1)

2025-03-16 15:47:37 | 日記

Firebaseを利用して金融機関のスマホ・アプリのシンプルなものを作ってみることにした。ヒントを与えてくれたのは、このYouTube ビデオ。

          Let's code a beginner Python BANKING PROGRAM

今回の設定は、

1. Kanoo Bankという架空の銀行

2. 同銀行に2人が口座を保有

3. それぞれの入金、出金およびその2人の間での送金をトレースする

このアプリでは、データベースを扱うときの基本CRUD(Create/Read/Update/Delete)の内、CRを実装。

アプリ実行のビデオの通り、「取引実行」ボタンをタップするとWarningが表示されたり、残高がリアルタイムに変更されないなどまだまだ、問題多いが、このアプリを作り始めて随分時間も経過したので、この段階で一旦アップするもの。引き続き改善していく予定。Warning後、Reloadボタンをタップしたら表示できた。

今回はミラリング・ソフトがうまく作動したので、Firebase側のページとアプリの画面を同時録画。

アプリ実行のビデオ:

ビデオが長いためか、gooへのリンクを取得できなかったが、リンクが取得できた。

スクリーン・デザイン:

右側画面下部にあるテスト用のLabelは「Test Label3」までしか見えないが、計4つあり。

Test Label1=>データのIDリスト(tag list)

Test Label2=>全データのJSON File

Test Label3=>ログインした預金者のデータの日付リスト+取引内容(入金or出金)+入金or出金の金額(数字)のリスト

Test Label4=>出金可能金額合計額

                                              

以下はアプリ実行時の画面について、私の備忘録的にまとめたもの。全てのデータからログインしているKanooKanaの口座内容のみがListView(左端の画面の緑の四角内)に表示されている。(ちょっと日付は古いが、このアプリを作ってすぐにスクリーンショットしたもので、アプリ実行のビデオはこれに新たにデータを加えたもの)

ブロック・コーディング:

<Screen1>(スクリーン・デザインの左のランディング・ページ)

お客のお客様番号をキーに、ログインパスワードをその値としてDictionary型の変数customerDetailsを設定

画面が初期化される際に、openingClock1を有効にする。

ランディング・ページが表示されたら、若干間(ま)を置いてから、お客様番号の入力を促すポップアップを表示する。その間(ま)を格納する変数countIndexForOpeningを初期化。

countIndexForOpeningの interval は、1000ミリ秒にセットしてある。2回ループするので2秒の間をおくことになる。2秒経過するとelse以下が実行され、お客様番号の入力を促すポップアップが表示される。

変数customerNumberInput:上記ポップアップで入力される数字を格納

入力された数字を変数customerNumberInputにセットする。(この変数に格納されたデータは後で利用)=>入力されたお客様番号がcustomerDetailsのキー(お客様番号)に存在する場合は、「ログイン・パスワード」入力を促すポップアップが表示。ない場合は、再度お客様番号の入力を促すポップアップが表示。ただし、cancelボタンをタップした時の動作がまだ実装されていない。

変数customerPasswordを設定

変数customerDetailsよりcustomerNumInputをキーにしてパスワードを取り出し、customerPasswordに格納。

customerPasswordの値が入力の値とマッチすればtransitionClock1を有効にする。

変数countIndexToTransition:この値が2超となったら、すなわち2秒経過したら「mainScreen」へ遷移させる。その際、お客様番号を渡す。

 

<mainScreen>(スクリーン・デザインの右側の画面)

変数customerNameList:Screen1と同様の顧客情報をDictionary形式で格納。お客様番号をキーとして、値はお客様の名前と口座番号。Screen1にも似たような変数customerDetailsがあるので、一つにしてFirebase内で管理すべきかもしれないが、複雑になるので現段階ではそれぞれの画面で変数で対応。

変数transactionList:取引内容をlist形式で格納

関数init:リストの初期化

変数customerNameとcustomerAccountNumberをブランクで初期化。内容は変数の名前の通り。

mainScreenの初期化:

関数initを実行し、変数を初期化 => Layout用ブロック(HorizontalArrangement)であり、TextBoxの「入金額」と「引出し額」を格納しているdepositHAとwithdrawalHAを非表示とする。選択された取引内容が「入金」または「出金」であればいずれかを表示=>Screen1より渡された値を基に、dictionary型のcustomerNameListより値を取り出し、変数customerNameとcustomeracountNumberに格納。=>それぞれ、customerNameLabelとcustomerAccountNumberLabelに表示。=>transactionListPickerに取引種類(transationList)をセット。=>fetchingDataClockを有効にして動かす。

fetchingDataClockでは、データをFirebaseより取得するための関数(関数init、関数getTagList、関数getData)を2回実行させる。もちろん、1回実行させたら、うまくデータを取得できることもあるが、不安定であり、2回実行するとデータ取得を失敗することが少なくなったので、この方法を採用。(この方法は、以前マリオの時にも、背景をセットする際に利用)でも、成功率は低い。

なお、以下は、1回のみこれら3つの関数を実行する最初に試したブロック。(今回はこのブロックではなく、上記ブロックを使用)

           

関数initTextBox:depositTextboxとwithdrawlTextBoxをブランクで初期化する。

今回は、取引内容を「入金」と「出金」に限って作成。「送金」と「残高」は今後実装を検討予定。なお、「残高」は今回ほぼ実現しているので不要かもしれないが。

変数transactionType:「入金」か「出金」のいずれが選択されたかを格納するもの。「入金」=1、「出金」=2。

取引内容の選択後、

1. 「入金」の場合は、depositHA(入金額入力用TextBoxを内包)とexecutionButton「取引実行」を有効にする

2. 「出金」の場合は、withdrawlHA(出金額入力用TextBoxを内包)とexecutionButton「取引実行」を有効にする。

「取引実行」ボタンをタップした際の動作を設定。

取引内容リストより「1 入金」あるいは「2 出金」を選択した場合、関数makeCurrentDateおよび関数makeDepositWithdrawlTransactionを実行。

関数makeCurrentDate:

現在の日付を設定したフォーマットに変換の上変数currentDateに格納。フォーマットは こちらのサイト を参照にした。

関数makeDepositWithdrawlTransaction:

Firebaseに対しアップロードするデータを格納する変数postDataを初期化。

Firebaseには、このアプリ用にあらかじめサブフォルダー「PlayBank」を設定済み。

depositTextBoxまたはwithdrawTextBoxに何らかの入力がある場合は、POST先のURLをセットし、それぞれのデータをpostDataに格納。=>セットされたURLに対しPOST requestを行う。=>この際、金額については、「Amount」と「AmountForCalculation」の二つのデータをアップロードしている。「出金」の場合は残高より差し引く必要があるため、「AmountForCalculation」は Amount X -1 として負の数字としている。後で残高などを計算する時は、この「AmountForCalculation」の数字のみを対象に行なっている。

なお、depositTextBoxおよびwithdrawTextBoxが空白の場合は、金額の入力を促すポップアップを表示。

関数getTagList:

これは、Firebaseを利用するときにいつも行なっている各データのIDを取り出すもの。パラメーター「?shallow=true」を追加すれば取得できる。

所定のURLをセットして、GET requestを行う。

データが取得できれば、変数tagListにIDのリストを格納。なお、取得したそれぞれのデータのindexが1のデータを取り出しているが、[["-ojds983rlrlkas_xVFW", "TRUE"], ......]のようなリスト形式で、最初のIDのみを取り出すため。(Mit App Inventor の場合、index は 0 ではなく1 )

関数getData:

データの詳細を取得するため、所定のURLをセットし、GET requestを行う。

データ取得に成功すれば、取得データをデコードの上変数responseJSONに格納。

その後、各データアイテムごとにリストを作成するため、関数makeDateList、makeAmountList、makeTransactionTypeListを実行し、最後にListViewに表示するデータを作成するmakeDataForListViewを実行する。

なお、それぞれの結果は、testLabel2 ~ 4 に表示させている。

accountBalanceLabelは残高を表示するもので、3桁ごとに区切り、末尾に「円」を追加。

以下は、データリストを作成する関数のブロックで、関数getTagListで取得したIDをキーにして各アイテムごとに順番にデータを取り出してリスト形式で変数に保存している。

想定では、このFirebaseのデータベースは銀行のデータベースであり、すべての客のデータを保存している。したがって、現在このアプリにログインしているお客様のデータを取り出す必要がある。そのため、ログインしたお客様の名前と各データのお客様の名前をチェックし、合致すればリストに追加していく。(最初のif statementの部分)

関数makeAmountList:ほぼ上記と同様。

関数makeTransactionTypeList:ほぼ、上記と同様。

関数makeDataForListView:

上記関数実行により取得した当該お客様のアイテムごとのデータ(リスト形式)を表示形式を整え統合してListView用のリストを作成。

Reloadボタンをタップした時の動作を設定。基本的に変数の初期化と再度Firebaseよりデータを取得し表示する関数を実行している。

FirebaseやPublic APIを利用した場合、どうしても長くなってしまう。

まだまだ、問題が多いが、色々試行錯誤を行なっていきたい。

 

 


MIT App Inventor 2で遊ぶ (Calculator 2 JavaScript)

2025-03-10 07:33:21 | 日記

前回の問題点の解決と「べき乗」および「平方根」の追加も行った。

ほぼ期待した通りの計算結果を表示してくれるようになった。

残る改善点としては、式の途中でも「べき乗」および「平方根」を使用できるようにすることだが、これはちょっと難しそう。また、「べき乗」の式の表示も一工夫が必要なようだ。

アプリ実行のビデオ:

スクリーン・デザイン:

式を表示、計算結果を表示の部分は前回、今回とも同じ。

               今回の画面                   前回の画面

                                                                            

ブロック・コード:

主な追加点は、Xʸ と √  のボタンがタップされた時の処理。ボタン操作のブロックは以下の通り。

<最初の赤黄点線で囲んだ部分>

1. Xʸ ボタンをタップした時は、他の数字、演算子と同様、変数calculationListにJavaScriptのべき乗の演算子である「**」を追加する。

2. √  ボタンをタップした時は、まず、変数rootSymbolに「√ 」と入力済みの数字を結合させ(例えば √ 2)、equationLabelにセットして画面に表示する。

3. 同時に、入力した数字をJavaScriptのメソッドMath.sqrt()のパラメーターとして挿入し、変数formulaにセットの上、メソッド自体をJavaScriptのファイルに送り計算させている。(上記の例だと、画面の表示は √ 2 だが、実際に送られるのは Math.sqrt(2)。)

<2番目の赤黄点線で囲んだ部分>

1.  数字のボタンをタップした時に、statusがtrueの場合は 「=」 ボタンをタップして計算結果を取得しているので、その計算結果をもって改めて計算を始める。

すなわち、10+10= のようにボタンをタップすると、20という計算結果が返される。次はその計算結果である 20 から引き続き計算を行うことができるようにしている。

 

「=」 ボタンをタップして計算結果を取得済みかどうかを監視するために変数statusを設定。

JavaScriptのオブジェクトが値を返した時に変数statusにtrueをセット。

 

                                                      *********************************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (Calculator 1 JavaScript)