<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                你把車停得盡量靠近體育館,但演唱會一結束,你卻忘了車停在哪兒,你的同伴也很茫然。幸運的是,你的Android手機還在,它從來不忘事,你新裝了一款熱門應用“Android,我的車在哪兒?”有了這個應用,在停車時點一下按鈕,Android的位置傳感器會“記住”車的GPS坐標和地址。當稍后重新打開應用時,它會指給你從現在位置到停車位置的方向,問題解決了! ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa4089ec8.png) ## **學習要點** 本章涵蓋如下概念: * LocationSensor組件:確定Android設備的位置; * TinyDB組件:直接在設備數據庫中記錄數據; * ActivityStarter組件:在應用中打開谷歌地圖,并顯示從一個位置到另一個位置的方向。 ## **準備開始** 登陸App Inventor網站,開始一個新項目“AndroidWhere”(項目名稱不能有空格),將屏幕標題設置為“Android,我的車在哪兒?”,連接測試手機。 ## **設計組件** 應用包含下列可視組件: * 多個Label組件:顯示當前位置和“記住”的位置信息,有些Label顯示靜態文本,如GPSLabel顯示“GPS:”;其他Label,如CurrentLatLabel顯示來自位置傳感器的數據。給這些Label設定一個默認值(0,0),當GPS取得位置信息時,這個值將隨之改變; * 兩個Button組件:記錄位置和指示該位置的方向; 以及三個非可視組件: * LocationSensor組件:獲取當前位置信息; * TinyDB組件:永久保存位置信息; * ActivityStarter組件:用于打開谷歌地圖,以獲得當前位置和記住位置之間的路線。 按照圖7-1所示的組件設計器截圖來創建組件。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa418ef60.png) **圖 7-1 組件設計器中應用的用戶界面** 跟隨表7-1,逐個拖出組件,并做相應設置,創建如圖7-1所示的用戶界面。 **表7-1 應用中的所有組件** | 組件類型 | 面板中分組 | 命名 | 作用 | | --- | --- | --- | --- | | Label | User Interface | CurrentHeaderLabel | 顯示標題“當前位置”| | HorizontalArrangement | Screen Arrangement | CurrentAddrArrangement | 放置地址信息 | | Label | User Interface | CurrentAddressLabel | 顯示“地址:” | | Label | User Interface | CurrentAddressDataLabel | 顯示動態數據:當前地址 | | HorizontalArrangement | Screen Arrangement | CurrentGPSArrangement | 安置GPS信息 | | Label | User Interface | GPSLabel | 顯示“GPS:” | | Label | User Interface | CurrentLatLabel | 顯示動態數據:當前緯度| | Label | User Interface | CommaLabel | 顯示“,” | | Label | ser Interface | CurrentLongLabel | 顯示動態數據:當前經度| | Button | User Interface | RememberButton | 點擊記錄當前位置 | | Label | User Interface | RememberedAddressTitleLabel | 顯示“已記錄的地點” | | HorizontalArrangement | Screen Arrangement |RememberAddrArrangement | 安置已保存的GPS信息 | | Label | User Interface | RememberedAddressLabel | 顯示“地址:” | | Label | User Interface| RememberedAddressDataLabel | 顯示動態數據:已記錄的地址 | | HorizontalArrangement | Screen Arrangement | RememberGPSArrangement | 安置已記錄的GPS信息 | | Label | User Interface | RememberedGPSlabel | 顯示“GPS:” | | Label | User Interface | RememberedLatLabel | 顯示動態數據:已記錄的緯度 | | Label | User Interface | Comma2Label | 顯示“,” | | Label | User Interface | RememberedLongLabel | 顯示動態數據:已記錄的經度 | | Button | User Interface | DirectionsButton | 點擊來顯示地圖 | | LocationSensor | Sensors | LocationSensor1 | 感知GPS信息 | | TinyDB | Storage | TinyDB1| 永久保存已記錄的位置信息 | | ActivityStarter | Connectivity | ActivityStarter1 | 打開地圖 | 用以下方式設置組件屬性: * 設置顯示靜態文本的Label的Text屬性為固定文本,參照表7-1; * 設置顯示動態GPS數據的Label的Text屬性為“0.0”; * 設置顯示動態地址的Label的Text屬性為“未知”; * 取消勾選RememberButton和DirectionsButton的Enabled屬性(設置為不可用); * 設置ActivityStarter屬性(表7-2),以便ActivityStarter.startActivity可以打開谷歌地圖。(圖7-1中ActivityStarter的屬性顯示不完整。)表7-2中未列出的屬性可以留空。 **表7-2 打開谷歌地圖所要設定的ActivityStarter屬性 | 屬性 | 值 | | --- | --- | | Action | android.intent.action.VIEW | | ActivityClass | com.google.android.maps.MapsActivity | | ActivityPackage | com.google.android.apps.maps | > ![](https://box.kancloud.cn/2015-08-31_55e3fa4207fd1.png) 提示:ActivityStarter組件可在應用中打開安裝在設備上的任何其他Android應用。要打開地圖,表7-2中的屬性必須一字不差地輸入;要打開其他應用,請參閱[http://appinventor.googlelabs.com/learn/reference/other/activitystarter.html](http://appinventor.googlelabs.com/learn/reference/other/activitystarter.html)?中的App Inventor文檔。 ## **為組件添加行為** 需要為應用設定如下行為: * 當LocationSensor讀取到位置信息時,將數據填寫到相應的Label中,表示傳感器已經讀取到當前位置信息,用戶這時可以選擇保存此位置信息; * 當用戶點擊RememberButton時,當前位置信息被復制到“已記錄的地點”名下的Label中。這些信息要保存到設備數據庫中,以便用戶關閉并再次打開應用時,數據不會消失; * 當用戶點擊DirectionsButton時,打開谷歌地圖,并顯示“已記錄”位置的方向; * 當應用重新啟動時,從數據庫中加載“已記錄”的位置信息。 ### **顯示當前位置** 兩種情況會觸發LocationSensor.LocationChanged事件,(1)傳感器首次讀取位置信息時;(2)設備的位置變化,傳感器讀數更新時。首次讀數有時僅需幾秒鐘,但如果GPS衛星信號受到屏蔽,會一直沒有讀數(也與設備的設置有關)。有關GPS和LocationSensor的更多信息,請參見第23章。 在讀取到位置信息時,程序要將數據寫到相應的Label中。表7-3列出了所有相關的塊。 **表7-3 讀取到位置信息時,用戶界面顯示這些信息所需要的塊** | 塊的類型 | 所在抽屜 | 作用 | | --- | --- | --- | | LocationSensor1.LocationChanged | LocationSensor | 當手機收到新的GPS讀數時,觸發該事件 | | set CurrentAddressDataLabel.Text to | CurrentAddressDataLabel | 將當前地址的新數據寫入label | | LocationSensor1.CurrentAddress | LocationSensor | 該屬性保存了街道地址信息| | set CurrentLatLabel.Text to | CurrentLatLabel | 將緯度信息寫入相應的label | | get latitude | Variables | 插入set CurrentLatLabel.Text to塊的插槽 | | set CurrentLongLabel.Text to | CurrentLongLabel | 將經度信息寫入相應的label| | get longitude | Variables | 插入set CurrentLongLabel.Text to塊的插槽 | | set RememberButton.Enabled to | RememberButton | 設置“記住我現在的位置”按鈕屬性 | | true | Logic | 插入set RememberButton.Enabled to插槽 | #### **塊的作用** 如圖7-2所示,latitude(經度)和longitude(緯度)是LocationChanged事件的參數,因此可以從Variables抽屜中抓取;但CurrentAddress則不是參數,而是LocationSensor的屬性,因此要從LocationSensor抽屜里抓取。LocationSensor除了獲取GPS位置信息之外,還通過調用谷歌地圖,獲得了與位置信息相對應的街道地址信息。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa42548db.png) **圖 7-2 使用LocationSensor讀取當前位置信息** 事件處理程序還啟用了RememberButton,該按鈕的初始設置為禁用(未選中),因為在傳感器獲得讀數之前,用戶不需要“記住”什么,而現在我們可以為“記住”行為編寫程序了。 > ![](https://box.kancloud.cn/2015-08-31_55e3fa47aab9f.png) 測試:用手機(wifi與電腦連接)實時測試位置感知應用是無效的。將程序打包并下載到手機上:選擇“build?App(provide QR code for .apk)”,按照提示在手機上打開應用。GPS及地址信息顯示在屏幕上,同時RememberButton變為可用。 如果沒有獲得讀數,檢查一下Android設備的位置及安全性設置,并嘗試走到戶外。要了解更多信息,請參見第23章。 ### **記錄當前位置** 當用戶點擊RememberButton時,當前位置信息被寫入“已記錄的地點”下方的label中。表7-4顯示了實現這一功能所需要的塊。 **表7-4 記錄并顯示當前位置所需要的塊** | 塊的類型 | 所在抽屜 | 作用 | | --- | --- | --- | | RememberButton.Click | RememberButton | 用戶點擊按鈕時觸發該事件 | | set RememberedAddressDataLabel.Text to | RememberedAddressDataLabel | 將傳感器獲得的地址信息寫入“已記錄”label中 | | LocationSensor1.CurrentAddress | LocationSensor | 該屬性保存了街道地址信息| | set RememberedLatLabel.Text to | RememberedLatLabel | 將緯度信息寫入“已記錄”label中 | | LocationSensor1.Latitude | LocationSensor | 該屬性保存了緯度信息 | | set RememberedLongLabel.Text to | RememberedLongLabel | 將經度信息寫入“已記錄”label中 | | LocationSensor1.Longitude | LocationSensor | 該屬性保存了經度信息 | | set DirectionsButton.Enabled to | DirectionsButton|設置DirectionsButton的Enabled屬性 | | true | Logic | 設置DirectionsButton的Enabled屬性為真 | #### **塊的作用** 當用戶點擊RememberButton時,當前位置信息將寫入“已記錄”label中,如圖7-3所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa481f8e0.png) **圖 7-3 將當前位置信息寫入“已記錄”label中** 注意到DirectionsButton已可用,這會有點兒小麻煩,因為如果用戶立即點擊DirectionsButton,記住的位置也是當前位置,因而地圖中不會提供方向有關的信息。但是,人們似乎不會這么做,當用戶移動位置時(例如步行到演唱會),則當前位置將偏離已記錄的位置。 > ![](https://box.kancloud.cn/2015-08-31_55e3fa47aab9f.png) 測試:將應用的新版本下載到手機,并再次測試。當單擊RememberButton時,當前位置信息是否被寫入到“已記錄”的label中? ### **顯示“已記錄”位置的方向** 當用戶點擊DirectionsButton 時,應用將打開谷歌地圖,地圖中顯示從用戶當前位置到“已記錄”位置(即停車的位置)的方向。 ActivityStarter組件可以打開任何Android應用,也包括谷歌地圖,但必須做一些相應的設置。不過像打開瀏覽器或地圖這樣的應用,設置起來相當簡單。 打開地圖的關鍵是設置ActivityStarter.DataUri屬性,該屬性無異于你在瀏覽器中直接輸入的網址。要想搞清楚這一點,只需在瀏覽器中打開http://maps.google.com,并詢問,比如舊金山與奧克蘭之間的方向。當結果出來時,點擊地圖的左上部的鏈接按鈕,并檢查顯示的URL。這正是你在應用中所需要的URL。 所不同的是,帶有方向的地圖涉及到兩個位置,即起點和終點,它們分別用一組特定的GPS坐標來表示(而非城市之間)。該URL必須采用以下形式: http://maps.google.com/maps?saddr=37.82557,-122.47898&daddr=37.81079,-122.47710 在瀏覽器中輸入網址,說說看,它指引你跨越了那個著名的地標性建筑? 這里需要為URL設定動態參數:起點地址(saddr)和終點地址(daddr)。在前幾章中,你已經學會用join塊將文本連接起來,這里也是如此。將當前位置和已記錄位置的GPS數據插入到URL中,設置ActivityStarter.DataUri屬性為URL,然后調用ActivityStarter.StartActivity。表7-5列出了此項功能所需要的塊。 #### **塊的作用** 用戶點擊DirectionsButton時,事件處理程序生成一個地圖URL,然后調用ActivityStarter打開地圖應用并加載地圖,如圖7-4所示,用join創建的URL發送給地圖應用。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa48bb212.png) **圖 7-4 生成一個URL,用來打開地圖并指示方向** 最終的URL包含了地圖域名([http://maps.google.com/maps](http://maps.google.com/maps))以及兩個URL參數:saddr與daddr,用來指定方向的起點位置及終點位置。在本應用中,saddr被設定為當前位置的緯度和經度,而daddr被設定為已記錄的停車位置的緯度和經度。 **表7-5 打開一張帶有方向指示的地圖所需要的塊** | 塊的類型 | 所在抽屜 | 作用 | | --- | --- | --- | | DirectionsButton.Click | DirectionsButton | 用戶點擊”指示方向”按鈕觸發該事件 | | set ActivityStarter1.DataUri to | ActivityStarter1 | 設置要打開地圖的URL | | join | Text | 將URL的各組成部分連接起來 | | “http://maps.google.com/maps?saddr=” | Text | URL中固定的部分,后面接起點經緯度 | | CurrentLatLabel.Text | CurrentLatLabel | 當前位置的緯度值 | | “,” | Text | 放在經緯度值之間的逗號 | | CurrentLongLabel.Text | CurrentLongLabel | 當前位置的經度值 | | “&daddr=” | Text | URL中的第二個參數,后面接終點經緯度 | | RememberedLatLabel.Text | RememberedLatLabel | 已記錄位置的緯度 | | “,” | Text| 放在經緯度值之間的逗號 | | RememberedLongLabel.Text | RememberedLongLabel | 已記錄位置的經度 | | ActivityStarter1.StartActivity | ActivityStarter1 | 打開地圖 | > ![](https://box.kancloud.cn/2015-08-31_55e3fa47aab9f.png) 測試:用手機下載新的版本并再次測試,一旦取得讀數,單擊RememberButton然后走開。當單擊DirectionsButton時,地圖是否提示您如何追溯你的腳步?點擊幾次后退按鈕。你是否有回到了你的應用? ### **永久保存已記錄的位置信息** 現在已經具備了一個全功能的應用:記住起點位置,并從當前用戶所在的位置繪制一張回到起點的地圖。雖然用戶“記住”了位置,但假如應用被關閉,然后再重新打開,“記住”的信息也將消失。實際上你希望用戶能夠記錄下車的位置,關閉應用,走到別處,然后重新啟動應用,并獲取已記錄的車輛所在位置的方向。 如果你能想起“開車不發短信”應用(第4章),說明你的思路是正確的,我們需要使用TinyDB數據庫來永久保存這些數據,采取的方案也與之前的應用類似: 1\. 當用戶點擊RememberButton時,位置信息存儲到數據庫中; 2\. 當應用啟動時,從數據庫中加載位置信息并保存到一個變量或屬性中。 從修改RememberButton.Click事件處理程序開始,來存儲這些要被“記住”的信息。存儲緯度、經度和地址三組信息,需要三次調用TinyDB.StoreValue。表7-6列出了所要補充的塊。 **表7-6 永久保存位置信息所需要的塊** | 塊的類型 | 所在抽屜 | 作用 | | --- | --- | --- | | TinyDB1.StoreValue(3) | TinyDB1 | 將數據保存在設備數據庫中 | | “address” | Text | 插入TinyDB1.StoreValue的tag插槽中 | | LocationSensor1.CurrentAddress | LocationSensor1 | 插入TinyDB1.StoreValue的value插槽中,永久保存地址信息 | | “lat” | Text | 插入第二個TinyDB1.StoreValue的tag插槽中 | | LocationSensor.CurrentLatitude | LocationSensor | 插入第二個TinyDB1.StoreValue的value插槽中,永久保存緯度信息 | | “long” | Text | 插入第三個TinyDB1.StoreValue的tag插槽中 | | LocationSensor.CurrentLongitude | LocationSensor | 插入第三個TinyDB1.StoreValue的value插槽中,永久保存經度信息 | #### **塊的作用** 如圖7-5所示,TinyDB1.StoreValue將LocationSensor屬性中的位置信息保存到數據庫中。你該記得在“開車不發短信”中,StoreValue函數有兩個參數,tag與value,tag充當已存儲數據的標識,value是你實際想保存的數據,即本例中的LocationSensor數據。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa4e7dea2.png) **圖 7-5 在數據庫中存儲被“記住”的位置信息** ### **啟動應用時讀取“記住”的位置信息** 將數據保存在數據庫中,是為了以后可以調用它。在本應用中,如果用戶在保存了位置信息之后退出應用,那么當應用重新打開時,你希望從數據庫中讀出信息并顯示給用戶。 在前幾章中討論過,應用的啟動會觸發Screen.Initialize事件,而在啟動時從數據庫中讀取數據是一種慣例,我們也不例外。 使用TinyDB.GetValue函數來讀取存儲的GPS數據。要讀取的存儲數據包括地址、緯度及經度,因此要調用GetValue函數三次。像在“開車不發短信”中一樣,要事先檢查數據庫中否保存了數據(如,第一次啟動應用時,TinyDB.GetValue將返回一個空文本)。 挑戰一下自己,看看是否可以獨立創建這些塊,然后再與圖7-6進行比較。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa59050bf.png) **圖 7-6 在應用啟動時,從數據庫中讀取數據,如果數據不為空則顯示數據** #### **塊的作用** 理解這些塊的方法是設想用戶的使用過程:用戶首次打開應用,先保存位置信息,稍后再次打開應用。首次打開應用,數據庫中沒有信息可加載,也不必填寫“已記錄”label或啟用DirectionsButton。在后續的使用中,如果確有數據存儲,就要從數據庫中加載這些位置信息。 首先用“address”為tag(標簽)調用TinyDB1.GetValue函數,之前在存儲位置信息時使用過這個tag。讀取的值保存在變量tempAddress中,并檢查其是否為空。 if塊將檢查從數據庫中讀出的數據。如果TinyDB對指定的tag沒有返回值,則返回空文本。首次啟動應用時沒有數據可讀,直到用戶點擊了RememberButton。由于變量tempAddress中保存了數據庫的返回值,因此if塊將檢查tempAddress的長度,如果長度>0,則TinyDB有地址信息返回,也表明經緯度.GetValue讀出經緯度信息。當設置完所有信息,最后啟用DirectionsButton。 > ![](https://box.kancloud.cn/2015-08-31_55e3fa47aab9f.png) 測試:將新版本應用下載到手機,并再次測試。點擊RememberButton,并確保“記住”讀數。關閉應用并再次打開。那些數據是否還在? ## **完整的應用:Android,我的車在哪兒?** 圖7-7顯示了完整的“Android,我的車在哪兒?”應用中所用到的塊。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3fa59e2e32.png) **圖 7-7 “Android,我的車在哪兒”應用中所有的塊** ## **改進** 可以嘗試如下改進: * 創建一個“Android,他們在哪兒?”的應用,讓一群人可以了解彼此行蹤。無論你在徒步旅行還是在公園散步,這個應用都有助于你節省時間,甚至可能挽救生命。應用中的數據是共享的,因此要使用web數據庫,用TinyWebDB組件來替代TinyDB。更多信息請參見第22章。 * 創建一個“行蹤”應用,用列表來記錄自己的位置改變,即行蹤。當記錄數達到一定數量時,或超過一定時間時,開始一個新的“行蹤”,因為即使是輕微的位移也會產生一個新的位置讀數。這類應用需要使用列表來存儲位置記錄,需要幫助時請參見第19章。 ## **小結** 下面是本章涉及到的概念: * LocationSensor組件:可以報告用戶的緯度、經度及當前的街區地址。當傳感器首次獲得數據或數據發生變化(設備移動)時,將觸發LocationChanged事件。有關LocationSensor的更多信息,請參見第23章; * ActivityStarter組件:可以在一個應用中打開其他應用,包括谷歌地圖。對于地圖,需要將ActivityStarter的DataUri屬性設置為想要打開的地圖的URL地址。如果你想顯示兩個GPS坐標之間的方向,URL應該寫成下面的格式,你可以用實際位置的GPS坐標來替換下面的示例數據:http://maps.google.com/maps/?saddr=0.1,0.1&daddr=0.2,0.2; * join用來將文本片段拼湊(連擊)成單一的文本對象,也可以讓靜態文本與動態數據相連接。對于地圖URL來說,GPS坐標就是動態數據; * TinyDB讓數據永久地保存在在手機的數據庫中。保存在變量或屬性中數據,會隨著應用的關閉而丟失,但存儲在數據庫中的數據,可以在每次啟動應用時被載入。有關TinyDB和數據庫的詳細信息,請參見第22章。 ### **資源下載** [AndroidWhere.aia](http://www.17coding.net/download/7/AndroidWhere.aia) [AndroidWhere.apk](http://www.17coding.net/download/7/AndroidWhere.apk)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看