註:本主題為阿旺師寫的專題實作啟蒙範例,不適合初學者觀看。
研究動機
- 出去旅行,把車停在停車場,當要回來取車,有時發現不知停在那裏,或者忘了停車場的位置。
- 把行李箱,寄放在某地的櫃子內,當要取回行李箱,忘記放在那裏。
- 小孩子跟朋友出去玩,不知現在在那裏,家長很擔心。
是否可以設計一個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
Projects/Start new project,輸入新專案的名稱,如 TrackWhere,按 「OK」鈕 。專案的名稱只能使用大小寫字母、數字及「 _」符號,名稱的第一個字元必須是英文字母,不能使用中文字。
Designer (畫面編排)
有三個 Screen,如下圖:
要新增 Screen, 選 Add Screen,選入 新 Screen的名字,命名規則和專案名稱一樣。
Screen1:
元件
|
類別
|
屬性
|
功能
|
Screen1
|
|
AppName:TrackWhere,可以改成「尋找物件和追蹤」(出現在手機上面的App名稱)
Icon :track_where.jpg
ScreenOrientation(螢幕方向):Portrait(鎖定直式畫面)
Title:尋找物件和追蹤
|
1個Screen元件就是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
|
位置感測器,每60秒1次。
|
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:從目前位置引到此物件
|
1個Screen元件就是1個螢幕 (畫面)。
|
WebViewer1
|
Layout(介面配置)
|
HomeUrl: https://www.google.com.tw
UsesLocation:(勾選)
|
網路瀏覽器元件
|
Screen_Cloud:
Screen_Cloud 元件相關屬性表
元件
|
類別
|
屬性
|
功能
|
Screen_Cloud
|
|
ScreenOrientation(螢幕方向):Portrait(鎖定直式畫面) Title:追踨-顯示位置
|
1個Screen元件就是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 清單選擇器的內容要移除此元素,因為已被刪除。
------------------------------------------------------------
心得與反思
寫好的程式,若不能應用在日常生活,就變成很空虛。能務實致用,那才是最有成就感。本程式實際測試,在台北存到雲端,在嘉義可看到此位置。笛卡爾認為人是「我思故我在」,阿旺師認為程式是「我用故我在」。
一般人都不喜歡被追踨,想要說服使用者安裝此程式,要有耐心溝通,這不是從網路隨意下載的,有原始程式嗎可以看,真的沒有侵犯隱私權。
如果修改程式 ,改成有自動追踨的功能,在使用者沒同意下安裝,有隱私權的問題,會造成糾紛。遵重隱私權,這是資訊倫理和法律的問題。