網頁

2022年7月24日 星期日

手機 App 程式設計- AppInventor2-尋找物件和追踨,LocationSensor +ActivityStarter+CloudDB 的應用

註:本主題為阿旺師寫的專題實作啟蒙範例,不適合初學者觀看。

研究動機

  • 出去旅行,把車停在停車場,當要回來取車,有時發現不知停在那裏,或者忘了停車場的位置。
  • 把行李箱,寄放在某地的櫃子內,當要取回行李箱,忘記放在那裏。
  • 小孩子跟朋友出去玩,不知現在在那裏,家長很擔心。
     是否可以設計一個App,解決上述的問題呢?  

研究目的

此App 的功能是可以儲存物件名稱和位置到資料庫。從資料庫把已儲存的物件名稱,顯示在清單選擇器中,使用者從裏面挑選 一個物件,可以使用 Google Map ,從目前位置指引到此物件的位置。也可以記錄使用者的位置到雲端,讓另一個人透過 Google Map 看到其位置。

學習目標

學習如何使用  Google Map 參數的用法、LocationSensor (位置感測器 )、TinyDB(微型資料庫)、ActivityStarter(啟動器)、CloudDB(雲端資料庫) 等元件的應用。

功能

  • 使用手機定位的功能,查出目前的位置((地址、緯度、經度),將物件名稱和位置儲存到資料庫。
  • 從資料庫讀出物件名稱,將之顯示在 ListPicker( 清單選擇器)內。使用者選一個物件,得出此物件的位置,透過 Google Map 的輔助,從目前位置導引到此物件的位置。
  • 使用者可以刪除資料庫某個物件的資料,也可以刪除整個資料庫,刪除前要出現確認框,以免誤刪。
  • 使用者將自己的位置,存入雲端資料庫。另一個人可從雲端找到其位置,並顯示在Google Map 。

執行畫面

按「目前位置」鈕,顯示目前地址和位置。在名稱後的文字方塊,輸入物件名稱,按「儲存」鈕,將此物件的地址和位置存入資料庫。

在「選擇物件」清單選擇器,選一個物件,如「機車」,名稱右邊的文字方塊就顯示此物件的名稱。下面會顯示此物件的位置,即「機車」的位置。

按「存到雲端」鈕,可將目前的位置存到雲端。按「雲端追踨」鈕,從Google Map 看出某人在那裏。

按「使用網路瀏覽器元件」鈕,出現從目前位置到「機車」的路線。

按「使用Google Map」鈕,出現從目前位置到「機車」的路線。
在「附近有什麼」清單選擇器選一個項目,如「Restaurants」此關鍵字,
就顯示附近有什麼「餐廳」:
在名稱文字方塊,輸入一個物件的名稱,如「行李箱」,再按「儲存」鈕,把「行李箱」的位置加入到資料庫內。若勾選「加入日期」,會加入現在的日期。
下次祇要從「選擇物件」選擇「行李箱」,就知其位置了。

選單內出現剛才加入的「行李箱」,前面加上日期。

「雲端追端」的起始畫面:

按「選一個人」鈕,從選單選一個人,如「爸爸」。

按「WebView」鈕,顯示「爸爸」的位置,不過沒有出現標記,所以此功能可以不用設計。

按「Google Map」鈕,會出現紅色標記,表示「爸爸」的位置。

藍色的小圓點是手機目前的位置,紅色的標記是「爸爸」的位罝。


素材

適用於 AppInventor 的 icon(圖示),大小是 50x50 pixels。 本 App的 icon (圖示),可自己繪製或網路搜尋。以下是阿旺師使用 Illustrator 繪製的圖片:

track_where.jpg

檔案/轉存,存檔類型,選  jpg。
色彩模式,請記得改選 RGB。如果是 CMYK,AppInventor 在編譯時會出現 Application icon的錯誤訊息,無法編譯。

如果使用網路的作品,請注意著作權。如果是 CC0 ,就比較沒有限制。

進入 AppInventor 

Google 輸入 AppInventor,選 「MIT App Inventor」,選 「Create Apps」,進入建置 App 的畫面。網址為 :http://ai2.appinventor.mit.edu/

Projects/Start new project,輸入新專案的名稱,如 TrackWhere,按 「OK」鈕 。專案的名稱只能使用大小寫字母、數字及「 _」符號,名稱的第一個字元必須是英文字母,不能使用中文字。

Designer  (畫面編排)

有三個 Screen,如下圖:

要新增 Screen, 選 Add Screen,選入 新 Screen的名字,命名規則和專案名稱一樣。

Screen1:




Screen1 元件相關屬性表

元件

類別

屬性

功能

Screen1

 

AppName:TrackWhere,可以改成「尋找物件和追蹤」(出現在手機上面的App名稱)
Icon :track_where.jpg
ScreenOrientation(
螢幕方向):Portrait(鎖定直式畫面)
Title:
尋找物件和追蹤

1Screen元件就是1個螢幕 (畫面)ScreenOrientation設定為Portrait,避免使用者晃動手機造成螢幕方向轉換。

HorizontalArrangement_Function

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Button_DisplayCurrentLocation

User Interface

FontSize(字體大小):12
Text(文字):目前位置

按鈕

ListPicker__Neighborhood

User Interface

FontSize:12
Text:附近有什麼

清單選擇器,

尋找附近的美食餐廳、景點、加油站等。

Button_OpenCloudScreen

User Interface

FontSize:12
Text:雲端追踨

按鈕

Button_End

User Interface

FontSize:12
Text:結束

按鈕

HorizontalArrangement_CurrentAddress

Layout(介面配置)

Width:Fill Parent (填滿)

水平配置元件

Label_CurrentAddress

User Interface

FontSize:12
Text:
目前地址:

 

標籤

Label_CurrentAddressData

User Interface

FontSize:12
Text:
未知

標籤

HorizontalArrangement_CurrentLocation

Layout

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件

Label_CurrentLocation

User Interface

FontSize:12
Text:
目前位置(緯度,經度):

標籤

Label_CurrentLocationData

User Interface

FontSize:12
Text:
清空)

標籤

HorizontalArrangement_Object

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件

Button_ObjectName

User Interface

Text:名稱

按鈕

TextBox_ObjectName

User Interface

FontSize:12
Hint:請輸入物件名稱
Text:
車子

文字方塊,輸入物件名稱。

CheckBox_AddDate

User Interface

FontSize:12
Text:加入日期

複盒選,即核取方塊,物件名稱是否要加入日期。

HorizontalArrangement_Database

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件,讓裏面的元件可以水平對齊。

ListPicker_SelectObject

User Interface

FontSize:12
Text:選擇物件

清單選擇器,選擇物件。

Button_Save

User Interface

Enabled:(不勾選)

FontSize:12
Text:儲存

按鈕

Button_Delete

User Interface

Enabled:(不勾選)
FontSize:12
Text:刪除

按鈕

Button_ClearDatabase

User Interface

FontSize:12
Text:清除資料庫

按鈕

Label_ObjectPlace

User Interface

Text:此物件的位置:

標籤

HorizontalArrangement_ObjectAddresss

Layout(介面配置)

Width:Fill Parent (填滿)

水平配置元件

Label_ObjectAddress

User Interface

FontSize:12
Text:
地址:

 

標籤

Label_ObjectAddressData

User Interface

FontSize:12
Text:
未知

標籤

HorizontalArrangement_ObjectLocation

Layout(介面配置)

Width:Fill Parent (填滿)

水平配置元件

Label_ObjectLocation

User Interface

FontSize:12
Text:
位置(緯度,經度):

 

標籤

Label_ObjectLocationData

User Interface

FontSize:12
Text:
0,0

標籤

Label_GuideTitle

User Interface

Text:從目前位置導引到此物件:

標籤

HorizontalArrangement_Guide

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Button_WebView

User Interface

Enabled:(不勾選)
FontSize:12
Text:使用網路瀏覽器元件

按鈕

Button_GoogleMap

User Interface

Enabled:(不勾選)
FontSize:12
Text:使用GoogleMap

按鈕

HorizontalArrangement_Cloud

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Button_MyName

User Interface

Text:名稱

按鈕

TextBox_MyName

User Interface

Hint:輸入自己的名字或稱謂
Text:
姐姐

文字方塊,輸入自己的名稱。

Button_SaveToCloud

User Interface

Text:存到雲端

按鈕

TinyDB1

Storage(資料儲存)

 

微型資料庫,儲存物件名稱和位置

LocationSensor1

Sensors(感測器)

TimeInterval:(計時間隔):60000

位置感測器,每601次。

ActivityStarter1

Connectivity(通訊

 

ActivityStarter啟動器

Notifier1

User Interface

 

對話框

Clock1

Sensors(感測器)

TimerEnabled(啟用計時):不勾選
TimerInterval(
計時間隔):1000 (毫秒)

計時器,每隔1秒觸發計時事件程序。

CloudDB1

Storage(資料儲存)

 

CloudDB(雲端資料庫),儲存人的名稱、位置和日期時間。

註:

  • 不同的Screen,若使用相同的 TinyDB、CloundDB 名稱,是共用的關係。 
  • 不同的AppInventor 帳號,所使用的CloundDB 是不同的, 因為 CloudDB 的Token是不一樣。

WebView:


WebView 元件相關屬性表

元件

類別

屬性

功能

WebView

 

ScreenOrientation(螢幕方向):Portrait(鎖定直式畫面)
Title:從目前位置引到此物件

1Screen元件就是1個螢幕 (畫面)

WebViewer1

Layout(介面配置)

HomeUrl: https://www.google.com.tw

UsesLocation:(勾選)

網路瀏覽器元件


Screen_Cloud:


Screen_Cloud 元件相關屬性表

元件

類別

屬性

功能

Screen_Cloud

 

ScreenOrientation(螢幕方向):Portrait(鎖定直式畫面)
Title:追踨-顯示位置

1Screen元件就是1個螢幕 (畫面)

HorizontalArrangement1

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (
填滿)

水平配置元件,讓裏面的元件可以水平對齊。

ListPicker_Select

User Interface

Text:選一個人
Title:
選一個人

清單選擇器,

選一個人,以便秀出其位置。

Label_Location

User Interface

FontSize:12
Width:Fill Parent
Text:位置

標籤

HorizontalArrangement2

Layout(介面配置)

Width:Fill Parent (填滿)

水平配置元件

Button_WebView

User Interface

Enabled:(不勾選)
FontSize:12
Text:WebView

按鈕

Button_Activity

User Interface

Enabled:(不勾選)
FontSize:12
Text:GoogleMap

按鈕

Button_Delete

User Interface

Enabled:(不勾選)
FontSize:12
Text:刪除

按鈕

WebViewer1

Layout(介面配置)

HomeUrl: https://maps.google.com
UsesLocation:(勾選)

網路瀏覽器元件

CloudDB1

Storage(資料儲存)

 

CloudDB(雲端資料庫),儲存人的名稱、位置和日期時間。

Notifier1

User Interface

 

對話框

ActivityStarter1

Connectivity(通訊

 

ActivityStarter啟動器

位置的格式 : latitude,longitude。說明 :latitude[ˋlætə͵tjud]緯度 ,longitude [ˋlɑndʒəˋtjud] 經度。

  輸入文字

Taichung_Station,24.1374212,120.6869897
Groceries, Restaurants, Takeout, Gas, Bus,Ubike,Hotels, Coffee, Hospitals, Schools, Pharmacies, ATMs

Blocks(程式設計)拼塊

跟元件有關的拼塊,要先點選該元件後,再選擇是那一個拼塊;不是元件的拼塊,可以根據拼塊的顏色,判斷是屬於那一個類別。

Screen1的Block


----------------------------------------------------------------
說明:
全域性變數 Separator,表示 地址、位置的分隔字元,因地址可能有逗號,所以使用  "|" 為分隔字元。
儲存在資料庫的表示法,tag為物件名稱 ,內容為: 地址 合併 分隔字元 合併位置。
例如:
tag 為 機車,內容 : 台中市和平街50號|24.133726652419266, 120.68470052731615 。






全域性變數 Destination_Latitude,目的地的緯度。
全域性變數 Destination_Longitude,目的地的經度。
全域性變數 Delete_Which,祇要有刪除的動作,都要出現確認的對話框,以免使用者誤刪,這個變數用來記錄是刪除什麼。
全域性變數 Neighborhood,「附近有什麼」 的關鍵字字串,如 Groceries, Restaurants, Takeout, Gas, Bus,Ubike,Hotels, Coffee, Hospitals, Schools, Pharmacies, ATMs。
全域性變數  Tag_List , CloudDB(雲端資料庫)有那些標籤,為清單變數。
-----------------------------------------------------------------------------------

----------------------------------------------------------------
說明:
全域性變數 Message_List,訊息清單,含有4個元素。
-----------------------------------------------------------------------------------

----------------------------------------------------------------
說明:
Refresh 此程序,將一些欄位的內容重新設定。
----------------------------------------------------------------

---------------------------------------------------------------
說明:
CanNotLocateF 此程序,判斷是否可以定位,並傳回值。true 表示無法定位。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
Confirm_Delete 此程序,出現選擇對話框,有「是」和「否」2個按鈕,不要有 「取消」 按鈕。
---------------------------------------------------------------


---------------------------------------------------------------
說明:
如果使用者按「是」,看要作那一項刪除的動作,分成4種。
---------------------------------------------------------------
---------------------------------------------------------------
說明:
Screen1_initialize (初始化):當Screen1 出現(螢幕初始畫面),將 Neighborhood(附近有什麼)的關鍵字字串設定給清單選擇器當選單的內容。
Screen1.BackPressed 當使用者按了手機的返回鍵,就結束程式。
---------------------------------------------------------------


---------------------------------------------------------------
說明:
當 Button_DisplayCurrentLocation 被點選(Click)(即使用者按了「目前位置」按鈕) ,要執行的動作。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當ListPicker__Neighborhood 被選擇後,使用 GoogleMap 顯示附近的相關資訊。如選「Gas」,顯示附近的加油站。
20z 地圖放大的層級(zoom level)為 20,值愈大放愈大。  
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當 Button_OpenCloudScreen 被點選時,開啟 Screen_Cloud 此畫面。
當 Button_End 被點選時,關閉程式。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當按了「名稱」按鈕, 出現 「確定要清空物件名稱文字方塊的內容?」的對話框。
當 ListPicker_SelectObject 清單選擇器,準備選擇時,從資料庫取得所有Tags(標籤),放在  Tag_List,再設定給  ListPicker_SelectObject 的Elements (元素),當成選單內容。
---------------------------------------------------------------
---------------------------------------------------------------
說明:
當 ListPicker_SelectObject 清單選擇器,選擇完成時要執行的動作 。
如果選中項索引不等於0 (表示使用者有選一個項目),從資料庫取得 標籤為 選中項 (選取的項目名稱) 所對應的內容。將此內容以分割字元 "|" 來分割,得到地址和位置 二種資料。
位置 再以分割字元","來分割,得到 緯度和經度 二種資料。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當 Button_Save 被Click(點選) ,以物件名稱文字方塊的內容為標籤,將地址和位置,儲存到資料庫內。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當 Button_Delete 被Click(點選) ,從資料庫刪除 物件名稱文字方塊的內容 此標籤,其對應的內容(地址和位置)也被刪除。
---------------------------------------------------------------

---------------------------------------------------------------
說明:
當 Button_ClearDatabase 被Click(點選),刪除整個資料庫。
---------------------------------------------------------------

--------------------------------------------------------------
說明:
當 Button_WebView 被Click(點選),打開另一個Screen,名稱為: WebView  ,起始值是一個清單,含有目前位置的緯度、經度和目的地的緯度、經度。
--------------------------------------------------------------
--------------------------------------------------------------
說明:
當 Button_GoogleMap 被Click(點選),由 ActivityStarter 來啟動裝置上的第三方程式,並到指定網頁。
--------------------------------------------------------------

------------------------------------------------------------
說明:
當 Button_MyName 被Click(點選),可清空 TextBox_MyName的內容。
------------------------------------------------------------


------------------------------------------------------------
說明:
當 Button_SaveToCloud  被Click(點選),以 TextBox_MyName 文字方塊的內容 為標籤,標籤內容為 :緯度,經度,日期,時間。將標籤及其對應的內容儲存到雲端資料庫。
------------------------------------------------------------

------------------------------------------------------------
說明:
當雲端資料庫已更新,出現訊息。
------------------------------------------------------------

WebView Screen 的Block



------------------------------------------------------------
說明:
全域性變數 Location_List,接收從Screen1傳過來的值。
WebView.BackPressed 當使用者按了手機的返回鍵,就結束此screen。
------------------------------------------------------------

------------------------------------------------------------
說明:
當 WebView_Initialize (初始化),從目前位置導引到此物件的位置。saddr (Source Address):來源位址,daddr(Destination Address):目的位址。
------------------------------------------------------------

Screen_Cloud 的Block


------------------------------------------------------------
說明:
全域性變數 Taichung_Station,台中火車站的緯度、經度。
全域性變數 Menu_List,擷取雲端資料庫 CloudDB 內的所有標籤 ,變成 Menu_List 清單,再設定給ListPicker_Select 清單選擇器 中的元素。
全域性變數 Fetched_List,擷取雲端資料庫 CloudDB某個標籤的內容,原本是一個字串,其格式為 :緯度,經度,日期,時間。以逗號為分隔字元,變成 Fetched_List 清單。
------------------------------------------------------------

------------------------------------------------------------
說明:
Screen_Cloud.BackPressed 當使用者按了手機的返回鍵,就結束此screen。
網路瀏覽器 Url 為Google Map 的網址,參數包含緯度,經度,還有地圖放大的層級為16。 
------------------------------------------------------------


------------------------------------------------------------
說明:
當 Screen_Cloud_Initialize (初始化),網路瀏覽器打開Google Map,中心點為台中火車站。
擷取雲端資料庫 CloudDB 內的所有標籤 。
------------------------------------------------------------

------------------------------------------------------------
說明:
將擷取到的標籤清單,設定給 Menu_List 此變數。
ListPicker_Select 清單選擇器 中的元素為 Menu_List 此變數。
------------------------------------------------------------

------------------------------------------------------------
說明:
如果使用者沒有在 ListPicker_Select 清單選擇器 選一個項目(即 SelectIndex=0),出現訊息,將三個按鈕設定為無法啟用。
否則  ListPicker_Select 清單選擇器的文字為選到的項目名稱,將三個按鈕設定為啟用。
從雲端資料庫 CloudDB 內找標籤為 清單選擇器選到的項目名稱,將其內容擷取出來。
------------------------------------------------------------

------------------------------------------------------------
說明:
CloudDB1.GotValue , 當從雲端資料庫取得數值(也就是得到資料)。
擷取雲端資料庫 CloudDB某個標籤的內容,原本是一個字串,以逗號為分隔字元,變成Fetched_List 清單,內容為 : 緯度,經度,日期,時間 ,總共有4個元素。
Location.Text 為 Fetched_List  中4個元素的合併文字。
------------------------------------------------------------

------------------------------------------------------------
說明:
網路瀏覽器 (WebView) Url 為Google Map 的網址,參數為 Fetched_List  中第1個元素(即緯度) 合併 ","  合併 第2個元素(即經度)。 
------------------------------------------------------------

------------------------------------------------------------
說明:
geo:taichung_Station , 以台中火車站 為起點,查詢 某個位置(緯度,經度)。
此ActivityStarter,因為要使用到 Goolgle Map, 所以手機要先安裝 Goolgle Map 此App。
------------------------------------------------------------

------------------------------------------------------------
說明:
是否 確定要刪除某個標籤。
------------------------------------------------------------

------------------------------------------------------------
說明:
如果使用者按 "是" 的按鈕。就從雲端資料庫 CloudDB 清除此標籤。
 ListPicker_Select 清單選擇器的內容要移除此元素,因為已被刪除。
------------------------------------------------------------

心得與反思

        寫好的程式,若不能應用在日常生活,就變成很空虛。能務實致用,那才是最有成就感。本程式實際測試,在台北存到雲端,在嘉義可看到此位置。笛卡爾認為人是「我思故我在」,阿旺師認為程式是「我用故我在」。
        一般人都不喜歡被追踨,想要說服使用者安裝此程式,要有耐心溝通,這不是從網路隨意下載的,有原始程式嗎可以看,真的沒有侵犯隱私權。
       如果修改程式 ,改成有自動追踨的功能,在使用者沒同意下安裝,有隱私權的問題,會造成糾紛。遵重隱私權,這是資訊倫理和法律的問題。