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

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

MIT App Inventor 2で遊ぶ (色と描画2-お絵描き帳2-)

2024-06-18 07:59:56 | 日記

今回は、少しお絵描き帳のアプリらしく。。。基本的な機能を整えた。データの保存については、お手軽にTinyDBというMIT App Inventorが用意してるものを使用。データはスマホ内部に保存される。

Tiny DBは小さな容量のファイル保存には適しているが、画像ファイルのような大きな容量の場合は適当なDBとは言えないようだ。

アプリ実行のビデオ:

やっぱり絵はどうしようもないくらいヘタ。

スクリーンのデザイン:

Tablet sizeでキャプチャー。

                               

ブロック・コード:

1. 描画の部分:前回と同じ。

2. 「全消去」ボタン:キャンバス(描画)を消去すると共に、背景画像(写真ライブラリーより取り込んだ画像)も消去。

3. 「画像消去」ボタン:キャンバス(描画)を消去。

3. 写真ライブラリーより画像を取得するImagePickerの動作設定:

extensionを使用して「CROP」(トリミング?)を選択している。「CROP」「FIT」そしてextensionを使用しない場合のスクリーンへの画像の表示は以下の通り。

左から、extensionの「CROP」、extensionの「FIT」、extensionなしとなる。

       

4. 画像の保存先をTinyDBとした。(簡単だから)

「保存」のボタンをタップすると、保存する画像につけるタグの入力を促すダイアログボックスが表示される。

5. ダイアログボックスにタグ名を入力して、保存されているタグ名とダブらなければ、保存される。ダブった場合は、ダイアログボックスが表示される。

キャンバス上にある画像にファイル名(ユニークな名前)をつけて、タグと一緒に(ペアーで)保存する。とりあえず1〜1000のランダムな数字をファイル名に付加した。テストの結果これで特段の問題は発生しなかった。

同じファイル名にした場合は、上書き保存された。

コミュニティーで色々検索するとID Generatorということで多くのサンプルがあった。その中でも一番簡単そうなものをさらに簡素化した以下のgeneratorでファイル名を生成することとした。

「abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJLKMNOPQRSTUVWXYZ_」を一文字ずつ分解してリストを生成し、そのリストから指定の長さの文字をランダムに抽出するといういたって簡単なもの。

関数generateFileNameを実行し、6桁の文字列をファイル名の頭に追加した。

 

6. TinyDBより画像をダウンロードする場合、もし、TineyDBのタグリストが空(から)の場合は、「保存されている画像はありません」のダイアログボックスを表示。空でなければ、ListViewにタグリストを設定し、ListViewのcontainerであるVerticalArrangement2を表示する。

7. タグが選択されたら、そのタグが付けられている画像をキャンバスに表示する。

8. 「DB消去」ボタンをクリックすれば、TinyDBに保存されているすべてのデータ(画像)が消去される。

9. 描画の線幅を調整するスライダー。

10. 描画色選択のボタン。赤色、白色。黒色、青色、ピンク色、黄色、緑色の各ボタンにRGBで色を設定。(赤色以外は省略)

 

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

前回までのブログ:

MIT App Inventorで遊ぶ (色と描画1-お絵描き帳-)

 


MIT App Inventorであのアプリを作ってみる (KanooPizza 3)

2024-06-16 12:50:21 | 日記

メニューの選択画面を追加。と言っても、メニュー選択機能を付加するのではなく、担当店舗の詳細を表示できるようにした。(半熟アプリだが、前に進むためにアップ)

アプリ実行のビデオ:

スクリーンのデザイン:

メニュー選択画面のみ。左図の赤点線内のボタンをタップすれば右図のように非表示としていたcomponentが開く。

今回、地図を使っているが、MIT App InventorのMap componentを利用。Google Mapより古臭い感じはするが、マーカーなどが簡単に追加することができるので。このMap componentの反応は悪く、うまく指定した緯度経度の場所を表示しないことがある。やり直すとうまく表示するのでOK。

                                      

ブロック・コード:

1. 「戻る」ボタン:二つ前のスクリーン(郵便番号を入力して住所を取得するスクリーン)へ戻る。

入力済みデータの保存がうまく行けば前のスクリーンに戻ることも可能となる。(後記)

2. スクリーンの初期化の際に、前のスクリーンより受け取るお客の郵便番号を変数customerZipCodeに格納する。

アプリに同梱されているzipCodeList2.jsonおよびmenuList2.jsonを読み込む。これらのファイルの内容(最初の部分のみ)は以下の通り。

<zipCodeList2.json(各郵便番号をカバーしているピザ店の店舗情報)>

[
 {
   "zipcode": 1540001,
   "areaName": "池尻",
   "shopName": "世田谷公園店",
   "shopAddress": "東京都世田谷区池尻",
   "businessHours": "9:00-22:00",
   "payment": "credit card/digital pay/cash"
 },
 {
   "zipcode": 1540002,
   "areaName": "下馬",
   "shopName": "三軒茶屋店",
   "shopAddress": "東京都世田谷区三軒茶屋",
   "businessHours": "9:00-22:00",
   "payment": "credit card/digital pay/cash"
 },

.....

]

<menuList2.json(今月のサービスピザの内容)>

[
 {
   "id": 1,
   "photo": "1.png",
   "name": "モッツアレラ",
   "feature": "特別調合ソースがたっぷり",
   "price": 900
 },
 {
   "id": 2,
   "photo": "2.png",
   "name": "デラックス",
   "feature": "ピザ好きならこれがお勧めNo1",
   "price": 800
 },

.....

]

3. zipCodeList2.jsonをデコードの上、お客の郵便番号をカバーしている店舗を抽出し、その店舗名をshopInChargeLabelに表示する。

4. 「>>」ボタンをタップすると、地図および店舗情報が表示される。

アプリに同梱のtenpoListCoords.jsonを読み込む。地図、店舗情報などを表示するコンテナーVerticalArrangement2を表示し、extensionを利用してVerticalArrangement2に角丸を設置する。

<tenpoListCoords.json(各店舗の緯度経度一覧)>

(こんな言い方が正しいのかどうかわからぬが、緯度経度が小数点以下6桁までデータとして入れたが、MIT App InventorのMap componentは小数点以下5桁までしか読み取らないようだ。)

[
 {
   "shopName": "三軒茶屋店",
   "address": "東京都世田谷区三軒茶屋",
   "latitude": 35.640081,
   "longitude": 139.665693
 },
 {
   "shopName": "世田谷公園店",
   "address": "東京都世田谷区池尻",
   "latitude": 35.642619,
   "longitude": 139.680646
 },
.....
]

読み込んだJSONファイルをデコードし、担当店舗の名前、店舗の緯度経度を抽出する。地図の中心を取得した緯度経度にセットすると共に地図上のマーカーも同じ緯度経度にセットする。最後に店舗情報を取得する関数makeShopDetailを実行する。

関数makeShopDetail:店舗情報が格納されているzipCodeListJSONより店舗名に該当する住所、営業時間などのデータを抽出し、所定のLabelに表示していく。

地図、店舗情報を非表示にするボタンの動作。

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

ここからは<今月のサービス・ピザ>の部分。

menuList2.jsonをデコードしたmenuJSONよりそれぞれのデータを抽出し、最終的にそれらを統合し「今月のサービスピザ」の下にあるListViewに表示。データ抽出の関数はすべて同じ構造を持っているので、関数makeMenuPhotoListをサンプルとして表示。

                                        **************** 他関数は省略 ***************

なお、最後にデータを統合する関数は以下の通り。価格には「円」を付加したりして見やすくしている。

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

色々と課題は残っているが、最大の課題は、一度入力した情報をTinyDBなどに保存し、再利用できるようにすることがUX(User Experience)の向上にもつながると思われる。これができると、例えば最後のメニュー選択スクリーンより一つ前のスクリーンに戻ることが可能となり、一度入力したデータを見ながら修正などもできるようになる。

また、メニュー選択スクリーンにある「今月のサービス・ピザ」は、とりあえずListViewで表示したが、これだとタップした時に反応してしまうので、HorizontalScrollArrangementにLabelを並べて表示する形式に変更を検討(Weather Appのように)。

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

前回までのブログ:

MIT App Inventorであのアプリを作ってみる (KanooPizza 2)

MIT App Inventorであのアプリを作ってみる (KanooPizza 1)

 

 


MIT App Inventorと失敗、勘違い等諸々 1(JSONファイルのデコード)

2024-06-15 07:26:05 | 日記

MIT App Inventorなら、比較的簡単にPublic APIからデータを取得して、様々なアプリを作ることができる。

でも、このブログを始めた頃は、JSONファイルをデコードするメソッドを間違えてたというか、適当にメソッドを使ったため随分苦労した。以前のブログでも触れたことがあるが。。。

MIT App Inventorでは、通常以下のようなブロック・コードでJSONファイルを取得。

スクリーンの初期化時に所定のURLに対し、GETリクエストを行う。

取得したオリジナルのJSONファイル:

今回は、フェイク・データを提供してくれているhttps://dummyjson.com/よりデータ個数を1つに限定してデータを取得。赤字、下線は当方にて加えたもので、例として後でこのデータを抽出する。

{
   "users":[
      {
         "id":1,
         "firstName":"Emily",
         "lastName":"Johnson",
         "maidenName":"Smith",
         "age":28,
         "gender":"female",
         "email":"emily.johnson@x.dummyjson.com",
         "phone":"+81 965-431-3024",
         "username":"emilys",
         "password":"emilyspass",
         "birthDate":"1996-5-30",
         "image":"https://dummyjson.com/icon/emilys/128",
         "bloodGroup":"O-",
         "height":193.24,
         "weight":63.16,
         "eyeColor":"Green",
         "hair":{
            "color":"Brown",
            "type":"Curly"
         },
         "ip":"42.48.100.32",
         "address":{
            "address":"626 Main Street",
            "city":"Phoenix",
            "state":"Mississippi",
            "stateCode":"MS",
            "postalCode":"29112",
            "coordinates":{
               "lat":-77.16213,
               "lng":-92.084824
            },
            "country":"United States"
         },
         "macAddress":"47:fa:41:18:ec:eb",
         "university":"University of Wisconsin--Madison",
         "bank":{
            "cardExpire":"03/26",
            "cardNumber":"9289760655481815",
            "cardType":"Elo",
            "currency":"CNY",
            "iban":"YPUXISOBI7TTHPK2BR3HAIXL"
         },
         "company":{
            "department":"Engineering",
            "name":"Dooley, Kozey and Cronin",
            "title":"Sales Manager",
            "address":{
               "address":"263 Tenth Street",
               "city":"San Francisco",
               "state":"Wisconsin",
               "stateCode":"WI",
               "postalCode":"37657",
               "coordinates":{
                  "lat":71.814525,
                  "lng":-161.150263
               },
               "country":"United States"
            }
         },
         "ein":"977-175",
         "ssn":"900-590-289",
         "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
         "crypto":{
            "coin":"Bitcoin",
            "wallet":"0xb9fc2fe63b2a6c003f1c324c3bfa53259162181a",
            "network":"Ethereum (ERC20)"
         },
         "role":"admin"
      }
   ],
   "total":209,
   "skip":0,
   "limit":1
}

データ取得に成功したらJSONファイルのデコードを行う。

上記の通り、通常以下いずれかのメソッドを使っている。

当初、このJsonTextDecodeでデコードを行っていたため、デコードの結果で得たのは以下のファイルだった。リスト形式。 キーと値が ["limit", 1]のような形式となっている。ネストが深くなってくると、[[["address",[["address","626 Main Street"],[........と続き、必ずしも可読性が良いとは言えない。目的のデータまでたどるのが一苦労!

上記データで、赤字、下線のEmilyの会社の緯度(lat)を抽出するためには、以下のようにリストのindexを順番に追いながら目的のデータに辿り着かないといけない。長いので二つに切った。「あ〜しんどいな〜」と言うこと。

まず、上記JSONListのindex 4 ということは、下のデコードデータで言えば、["limit", 1]がindex 1、["skip",0]がindex 2、["total", 209]がindex 3、そして["users",..........]がindex 4でこの中に目的のデータがあるということになる。オリジナルのJSONデータを見てもその通りだが、まあ、気が遠くなるような作業となっていく。

testLabel1の表示は以下の通り。

もう一つは、Dictionary形式でデコードしてくれるJsonTextWithDictionariesというmethod。

デコード結果は、以下の通りで、はるかに見やすい。オリジナルのJSONファイルとも相違はなく、唯一異なる点は、キーがアルファベット順に変更されていることだが、キーだけを見れば良いので、あまり問題ではない。(もちろん、リスト形式でデコードした場合もアルファベット順となっている)

したがって、元のオリジナルのJSONファイルを見て、目的のデータまでのキーを順番にたどって行けばOK。

testLabel2の表示は以下の通り。

いずれにしても、最初のリスト形式の場合、ネストが深くなっていくと目的のデータまでの経路を辿るのがとても大変。

なぜリスト形式のデコードを選んだかと言うと、当時、参考にしたYouTubeのチュートリアルがこのデコード方法を採用していたから、という単純な理由。

<付け加え>

さて、ここまで書いてきたのだが、偶然MIT App InventorでデコードしたJSONデータをprettify(読みやすく)するextension が存在することがわかった。それを使って早速スマホに表示させたのが下の右図。(スクリーン・キャプチャーがうまくないが)

オリジナルのJSONファイルと比べて、キーのアルファベット順に並び替えられているが、可読性は非常に良い。データのチェックには最初からこれを使っていれば良かった!

                          整形前                       整形後

            

 


MIT App Inventorで遊ぶ (色と描画1-お絵描き帳1-)

2024-06-14 05:06:17 | 日記

モバイルアプリ作成の初心者なら一度は作る、、、、、、お絵描きアプリ。一度はやってみないと。

指でスクリーンをなぞると線が描けるんですから!私のような素人にとってはちょっとした感動の瞬間。(イーロン・マスク氏が、初めてのStarship打ち上げの際に、"Success is not guaranteed, but excitement is guaranteed."と言ったのを思い出した。関係ないけど。)

今まで見たこともないようなアプリではなく、今までに何度も何度も出くわした、平凡なアプリだが。

YouTubeにもMIT App Inventorのみならず、色々なプログラミング言語で作られたお絵描きアプリの紹介がたくさんある。

まずは、線を描く。

アプリ実行のビデオ:

絵は下手だが、ここは恥を忍んで。。。New Drawing App 1とNewがついているのは、以前MIT App Inventorを学び始めた頃に同様のお絵描きアプリを作成したので。

スクリーンのデザイン:

いたってシンプル。

                                             

ブロック・コード:

できる限り滑らかな描画をしたいものだ。なんら工夫せずに描画のcomponentを使った場合は、以下のようにぶつ切れの線になってしまう。

そうじゃないよと、教えてくれたのは、以下のウエッブサイト。

Draw A Smooth Line on Canvas

ぶつ切れの描画ブロック:

ビデオのように比較的滑らかな線を描画するブロック(DrawCircleを追加):

DrawCircleの半径を「線幅の半分」に設定するがミソらしい。

最初からブロックを見ると。

1. 描画の色と線幅を割り当てる変数を設定。色は空(から)のリストで、screenの初期化の際に、RGBの値にそれぞれ0, 0, 0を割り当て、黒を作成。MIT App Inventor的に考えれば、もひとつAの値(不透明度)がある。それを加えると0, 0, 0, 255となるらしい。(不透明度は0から1の数字、例えば0.6とか、で表す場合が多いらしい、MIT App Inventorでは、0〜255)

2. 描画のブロック:キャンバスの描画色に変数drawingColorを設定。

3. 消去ボタンをタップした時の実行内容。スライダーのthumbの位置を線幅として設定。

次回は、もう少しお絵描き帳として標準的な機能を追加したい。

 


MIT App Inventorであのアプリを作ってみる (KanooPizza 2)

2024-06-13 08:19:01 | 日記

前回、郵便番号を入力すると、その地域に対する丁目の候補が表示され、選択できるようにしたいと書いたが、解決方法は意外と簡単に見つかった。

全国の市区町村に存在する丁目を提供してくれるAPIがあった。

Geolonia blogというサイト

以下は東京都世田谷区の丁目を検索した結果の冒頭部分。他の都道府県の市区町村も検索してみたら、データが取得できた。

今回は、とりあえず、東京都世田谷区に絞ってアプリを作成している。もし、全国のピザ販売店の位置情報などが取得できるのであれば、世田谷区に限ることはないが。。。無理な相談!また、そんな膨大なデータを作ることは不可能。

[
   {
      "town":"赤堤一丁目",
      "koaza":"",
      "lat":35.655245,
      "lng":139.641523
   },
   {
      "town":"赤堤二丁目",
      "koaza":"",
      "lat":35.658003,
      "lng":139.645777
   },
   ......

]

アプリ実行のビデオ:

(まだテスト段階なので、Test用Labelはそのままにしてある)

スクリーンのデザイン:

特にデザインに変更はなし。

ブロックのコード:

丁目候補表示部分のみ。

関数callChomeを実行し、所定のURLに対しGETリクエストを行う。

そして、データが取得できたら(responseCodeでのチェックが抜けているが)、必要なデータの抽出に移る。

市区町村の丁目データから、街の名前、例えば、「桜」が「town」の値として含まれていれば、「桜一丁目」「桜二丁目」・・・を取り出しリストにして表示すればよいと考えた。

しかし、世田谷区に限定して作成しているものの、世田谷区には、「桜」が付く地域が「桜」以外に「桜丘」「桜上水」「桜新町」3つあったのでこのような考え方が通じなかった。そこで、「桜一丁目」と「桜丘一丁目」「桜上水一丁目」「桜新町一丁目」のグループを区別し、目的のデータのみを抽出する方法として、

      => 街の文字数が1つであり、(「桜」は一文字。一文字の街は、世田谷区でも他に「砧」などがある)

      => 丁目を含んだ文字数が4文字であり、(「桜一丁目」これはちょっと強引かもしれない。十一丁目があったらどうする?対応不可。いずれにしても「桜一丁目」「砧一丁目」などが抽出される)

      => 丁目を含んだ街の中に「桜」が含まれているならOK(「桜一丁目」〜「桜三丁目」までを抽出成功)

という条件とした。世田谷区の場合はうまくいったが、他の地域ではダメだろう。もう少しユニバーサルに適用できるロジックを考える必要があるだろう。今回は、これで次に進む。

リストができれば、chomeListPickerに表示。

選択された丁目をchomeLableに表示し、次へのボタン( >> )も表示。

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

因みに、全国の市区町村に存在する丁目のAPIから世田谷区に限定して取得したデータ(JSON)の桜が含まれている部分は以下。(抜粋)

[

......

   {

      "town":"桜一丁目",
      "koaza":"",
      "lat":35.645526,
      "lng":139.641136
   },
   {
      "town":"桜二丁目",
      "koaza":"",
      "lat":35.643813,
      "lng":139.637878
   },
   {
      "town":"桜三丁目",
      "koaza":"",
      "lat":35.640435,
      "lng":139.637264
   },
   .......
   {
      "town":"桜丘一丁目",
      "koaza":"",
      "lat":35.642736,
      "lng":139.632385
   },
   ......
   {
      "town":"桜新町一丁目",
      "koaza":"",
      "lat":35.628891,
      "lng":139.642972
   },

   .....
   {
      "town":"桜上水一丁目",
      "koaza":"",
      "lat":35.658089,
      "lng":139.631515
   },
   ......

.......

]

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

前回までのブログ:

MIT App Inventorであのアプリを作ってみる (KanooPizza 1)