第 7 章 安卓,我的車在哪?

2018-02-24 15:51 更新

你把車停得盡量靠近體育館,但演唱會一結(jié)束,你卻忘了車停在哪兒,你的同伴也很茫然。幸運(yùn)的是,你的Android手機(jī)還在,它從來不忘事,你新裝了一款熱門應(yīng)用“Android,我的車在哪兒?”有了這個(gè)應(yīng)用,在停車時(shí)點(diǎn)一下按鈕,Android的位置傳感器會“記住”車的GPS坐標(biāo)和地址。當(dāng)稍后重新打開應(yīng)用時(shí),它會指給你從現(xiàn)在位置到停車位置的方向,問題解決了!

{%}

學(xué)習(xí)要點(diǎn)

本章涵蓋如下概念:

  • LocationSensor組件:確定Android設(shè)備的位置;

  • TinyDB組件:直接在設(shè)備數(shù)據(jù)庫中記錄數(shù)據(jù);

  • ActivityStarter組件:在應(yīng)用中打開谷歌地圖,并顯示從一個(gè)位置到另一個(gè)位置的方向。

準(zhǔn)備開始

登陸App Inventor網(wǎng)站,開始一個(gè)新項(xiàng)目“AndroidWhere”(項(xiàng)目名稱不能有空格),將屏幕標(biāo)題設(shè)置為“Android,我的車在哪兒?”,連接測試手機(jī)。

設(shè)計(jì)組件

應(yīng)用包含下列可視組件:

  • 多個(gè)Label組件:顯示當(dāng)前位置和“記住”的位置信息,有些Label顯示靜態(tài)文本,如GPSLabel顯示“GPS:”;其他Label,如CurrentLatLabel顯示來自位置傳感器的數(shù)據(jù)。給這些Label設(shè)定一個(gè)默認(rèn)值(0,0),當(dāng)GPS取得位置信息時(shí),這個(gè)值將隨之改變;

  • 兩個(gè)Button組件:記錄位置和指示該位置的方向;

以及三個(gè)非可視組件:

  • LocationSensor組件:獲取當(dāng)前位置信息;

  • TinyDB組件:永久保存位置信息;

  • ActivityStarter組件:用于打開谷歌地圖,以獲得當(dāng)前位置和記住位置之間的路線。

按照圖7-1所示的組件設(shè)計(jì)器截圖來創(chuàng)建組件。

{%}

圖 7-1 組件設(shè)計(jì)器中應(yīng)用的用戶界面

跟隨表7-1,逐個(gè)拖出組件,并做相應(yīng)設(shè)置,創(chuàng)建如圖7-1所示的用戶界面。

表7-1 應(yīng)用中的所有組件

組件類型 面板中分組 命名 作用
Label User Interface CurrentHeaderLabel 顯示標(biāo)題“當(dāng)前位置”
HorizontalArrangement Screen Arrangement CurrentAddrArrangement 放置地址信息
Label User Interface CurrentAddressLabel 顯示“地址:”
Label User Interface CurrentAddressDataLabel 顯示動態(tài)數(shù)據(jù):當(dāng)前地址
HorizontalArrangement Screen Arrangement CurrentGPSArrangement 安置GPS信息
Label User Interface GPSLabel 顯示“GPS:”
Label User Interface CurrentLatLabel 顯示動態(tài)數(shù)據(jù):當(dāng)前緯度
Label User Interface CommaLabel 顯示“,”
Label ser Interface CurrentLongLabel 顯示動態(tài)數(shù)據(jù):當(dāng)前經(jīng)度
Button User Interface RememberButton 點(diǎn)擊記錄當(dāng)前位置
Label User Interface RememberedAddressTitleLabel 顯示“已記錄的地點(diǎn)”
HorizontalArrangement Screen Arrangement RememberAddrArrangement 安置已保存的GPS信息
Label User Interface RememberedAddressLabel 顯示“地址:”
Label User Interface RememberedAddressDataLabel 顯示動態(tài)數(shù)據(jù):已記錄的地址
HorizontalArrangement Screen Arrangement RememberGPSArrangement 安置已記錄的GPS信息
Label User Interface RememberedGPSlabel 顯示“GPS:”
Label User Interface RememberedLatLabel 顯示動態(tài)數(shù)據(jù):已記錄的緯度
Label User Interface Comma2Label 顯示“,”
Label User Interface RememberedLongLabel 顯示動態(tài)數(shù)據(jù):已記錄的經(jīng)度
Button User Interface DirectionsButton 點(diǎn)擊來顯示地圖
LocationSensor Sensors LocationSensor1 感知GPS信息
TinyDB Storage TinyDB1 永久保存已記錄的位置信息
ActivityStarter Connectivity ActivityStarter1 打開地圖

用以下方式設(shè)置組件屬性:

  • 設(shè)置顯示靜態(tài)文本的Label的Text屬性為固定文本,參照表7-1;

  • 設(shè)置顯示動態(tài)GPS數(shù)據(jù)的Label的Text屬性為“0.0”;

  • 設(shè)置顯示動態(tài)地址的Label的Text屬性為“未知”;

  • 取消勾選RememberButton和DirectionsButton的Enabled屬性(設(shè)置為不可用);

  • 設(shè)置ActivityStarter屬性(表7-2),以便ActivityStarter.startActivity可以打開谷歌地圖。(圖7-1中ActivityStarter的屬性顯示不完整。)表7-2中未列出的屬性可以留空。

**表7-2 打開谷歌地圖所要設(shè)定的ActivityStarter屬性

屬性
Action android.intent.action.VIEW
ActivityClass com.google.android.maps.MapsActivity
ActivityPackage com.google.android.apps.maps

{%}塊的類型 所在抽屜 作用 RememberButton.Click RememberButton 用戶點(diǎn)擊按鈕時(shí)觸發(fā)該事件 set RememberedAddressDataLabel.Text to RememberedAddressDataLabel 將傳感器獲得的地址信息寫入“已記錄”label中 LocationSensor1.CurrentAddress LocationSensor 該屬性保存了街道地址信息 set RememberedLatLabel.Text to RememberedLatLabel 將緯度信息寫入“已記錄”label中 LocationSensor1.Latitude LocationSensor 該屬性保存了緯度信息 set RememberedLongLabel.Text to RememberedLongLabel 將經(jīng)度信息寫入“已記錄”label中 LocationSensor1.Longitude LocationSensor 該屬性保存了經(jīng)度信息 set DirectionsButton.Enabled to DirectionsButton 設(shè)置DirectionsButton的Enabled屬性 true Logic 設(shè)置DirectionsButton的Enabled屬性為真

塊的作用

當(dāng)用戶點(diǎn)擊RememberButton時(shí),當(dāng)前位置信息將寫入“已記錄”label中,如圖7-3所示。

{%}

圖 7-3 將當(dāng)前位置信息寫入“已記錄”label中

注意到DirectionsButton已可用,這會有點(diǎn)兒小麻煩,因?yàn)槿绻脩袅⒓袋c(diǎn)擊DirectionsButton,記住的位置也是當(dāng)前位置,因而地圖中不會提供方向有關(guān)的信息。但是,人們似乎不會這么做,當(dāng)用戶移動位置時(shí)(例如步行到演唱會),則當(dāng)前位置將偏離已記錄的位置。

 測試:將應(yīng)用的新版本下載到手機(jī),并再次測試。當(dāng)單擊RememberButton時(shí),當(dāng)前位置信息是否被寫入到“已記錄”的label中?

顯示“已記錄”位置的方向

當(dāng)用戶點(diǎn)擊DirectionsButton 時(shí),應(yīng)用將打開谷歌地圖,地圖中顯示從用戶當(dāng)前位置到“已記錄”位置(即停車的位置)的方向。

ActivityStarter組件可以打開任何Android應(yīng)用,也包括谷歌地圖,但必須做一些相應(yīng)的設(shè)置。不過像打開瀏覽器或地圖這樣的應(yīng)用,設(shè)置起來相當(dāng)簡單。

打開地圖的關(guān)鍵是設(shè)置ActivityStarter.DataUri屬性,該屬性無異于你在瀏覽器中直接輸入的網(wǎng)址。要想搞清楚這一點(diǎn),只需在瀏覽器中打開http://maps.google.com,并詢問,比如舊金山與奧克蘭之間的方向。當(dāng)結(jié)果出來時(shí),點(diǎn)擊地圖的左上部的鏈接按鈕,并檢查顯示的URL。這正是你在應(yīng)用中所需要的URL。

所不同的是,帶有方向的地圖涉及到兩個(gè)位置,即起點(diǎn)和終點(diǎn),它們分別用一組特定的GPS坐標(biāo)來表示(而非城市之間)。該URL必須采用以下形式:

http://maps.google.com/maps?saddr=37.82557,-122.47898&daddr=37.81079,-122.47710

在瀏覽器中輸入網(wǎng)址,說說看,它指引你跨越了那個(gè)著名的地標(biāo)性建筑?

這里需要為URL設(shè)定動態(tài)參數(shù):起點(diǎn)地址(saddr)和終點(diǎn)地址(daddr)。在前幾章中,你已經(jīng)學(xué)會用join塊將文本連接起來,這里也是如此。將當(dāng)前位置和已記錄位置的GPS數(shù)據(jù)插入到URL中,設(shè)置ActivityStarter.DataUri屬性為URL,然后調(diào)用ActivityStarter.StartActivity。表7-5列出了此項(xiàng)功能所需要的塊。

塊的作用

用戶點(diǎn)擊DirectionsButton時(shí),事件處理程序生成一個(gè)地圖URL,然后調(diào)用ActivityStarter打開地圖應(yīng)用并加載地圖,如圖7-4所示,用join創(chuàng)建的URL發(fā)送給地圖應(yīng)用。

{%}

圖 7-4 生成一個(gè)URL,用來打開地圖并指示方向

最終的URL包含了地圖域名(http://maps.google.com/maps)以及兩個(gè)URL參數(shù):saddr與daddr,用來指定方向的起點(diǎn)位置及終點(diǎn)位置。在本應(yīng)用中,saddr被設(shè)定為當(dāng)前位置的緯度和經(jīng)度,而daddr被設(shè)定為已記錄的停車位置的緯度和經(jīng)度。

表7-5 打開一張帶有方向指示的地圖所需要的塊

塊的類型 所在抽屜 作用
DirectionsButton.Click DirectionsButton 用戶點(diǎn)擊”指示方向”按鈕觸發(fā)該事件
set ActivityStarter1.DataUri to ActivityStarter1 設(shè)置要打開地圖的URL
join Text 將URL的各組成部分連接起來
http://maps.google.com/maps?saddr=” Text URL中固定的部分,后面接起點(diǎn)經(jīng)緯度
CurrentLatLabel.Text CurrentLatLabel 當(dāng)前位置的緯度值
“,” Text 放在經(jīng)緯度值之間的逗號
CurrentLongLabel.Text CurrentLongLabel 當(dāng)前位置的經(jīng)度值
“&daddr=” Text URL中的第二個(gè)參數(shù),后面接終點(diǎn)經(jīng)緯度
RememberedLatLabel.Text RememberedLatLabel 已記錄位置的緯度
“,” Text 放在經(jīng)緯度值之間的逗號
RememberedLongLabel.Text RememberedLongLabel 已記錄位置的經(jīng)度
ActivityStarter1.StartActivity ActivityStarter1 打開地圖

 測試:用手機(jī)下載新的版本并再次測試,一旦取得讀數(shù),單擊RememberButton然后走開。當(dāng)單擊DirectionsButton時(shí),地圖是否提示您如何追溯你的腳步?點(diǎn)擊幾次后退按鈕。你是否有回到了你的應(yīng)用?

永久保存已記錄的位置信息

現(xiàn)在已經(jīng)具備了一個(gè)全功能的應(yīng)用:記住起點(diǎn)位置,并從當(dāng)前用戶所在的位置繪制一張回到起點(diǎn)的地圖。雖然用戶“記住”了位置,但假如應(yīng)用被關(guān)閉,然后再重新打開,“記住”的信息也將消失。實(shí)際上你希望用戶能夠記錄下車的位置,關(guān)閉應(yīng)用,走到別處,然后重新啟動應(yīng)用,并獲取已記錄的車輛所在位置的方向。

如果你能想起“開車不發(fā)短信”應(yīng)用(第4章),說明你的思路是正確的,我們需要使用TinyDB數(shù)據(jù)庫來永久保存這些數(shù)據(jù),采取的方案也與之前的應(yīng)用類似:

1. 當(dāng)用戶點(diǎn)擊RememberButton時(shí),位置信息存儲到數(shù)據(jù)庫中;

2. 當(dāng)應(yīng)用啟動時(shí),從數(shù)據(jù)庫中加載位置信息并保存到一個(gè)變量或?qū)傩灾小?/p>

從修改RememberButton.Click事件處理程序開始,來存儲這些要被“記住”的信息。存儲緯度、經(jīng)度和地址三組信息,需要三次調(diào)用TinyDB.StoreValue。表7-6列出了所要補(bǔ)充的塊。

表7-6 永久保存位置信息所需要的塊

塊的類型 所在抽屜 作用
TinyDB1.StoreValue(3) TinyDB1 將數(shù)據(jù)保存在設(shè)備數(shù)據(jù)庫中
“address” Text 插入TinyDB1.StoreValue的tag插槽中
LocationSensor1.CurrentAddress LocationSensor1 插入TinyDB1.StoreValue的value插槽中,永久保存地址信息
“l(fā)at” Text 插入第二個(gè)TinyDB1.StoreValue的tag插槽中
LocationSensor.CurrentLatitude LocationSensor 插入第二個(gè)TinyDB1.StoreValue的value插槽中,永久保存緯度信息
“l(fā)ong” Text 插入第三個(gè)TinyDB1.StoreValue的tag插槽中
LocationSensor.CurrentLongitude LocationSensor 插入第三個(gè)TinyDB1.StoreValue的value插槽中,永久保存經(jīng)度信息

塊的作用

如圖7-5所示,TinyDB1.StoreValue將LocationSensor屬性中的位置信息保存到數(shù)據(jù)庫中。你該記得在“開車不發(fā)短信”中,StoreValue函數(shù)有兩個(gè)參數(shù),tag與value,tag充當(dāng)已存儲數(shù)據(jù)的標(biāo)識,value是你實(shí)際想保存的數(shù)據(jù),即本例中的LocationSensor數(shù)據(jù)。

{%}

圖 7-5 在數(shù)據(jù)庫中存儲被“記住”的位置信息

啟動應(yīng)用時(shí)讀取“記住”的位置信息

將數(shù)據(jù)保存在數(shù)據(jù)庫中,是為了以后可以調(diào)用它。在本應(yīng)用中,如果用戶在保存了位置信息之后退出應(yīng)用,那么當(dāng)應(yīng)用重新打開時(shí),你希望從數(shù)據(jù)庫中讀出信息并顯示給用戶。

在前幾章中討論過,應(yīng)用的啟動會觸發(fā)Screen.Initialize事件,而在啟動時(shí)從數(shù)據(jù)庫中讀取數(shù)據(jù)是一種慣例,我們也不例外。

使用TinyDB.GetValue函數(shù)來讀取存儲的GPS數(shù)據(jù)。要讀取的存儲數(shù)據(jù)包括地址、緯度及經(jīng)度,因此要調(diào)用GetValue函數(shù)三次。像在“開車不發(fā)短信”中一樣,要事先檢查數(shù)據(jù)庫中否保存了數(shù)據(jù)(如,第一次啟動應(yīng)用時(shí),TinyDB.GetValue將返回一個(gè)空文本)。

挑戰(zhàn)一下自己,看看是否可以獨(dú)立創(chuàng)建這些塊,然后再與圖7-6進(jìn)行比較。

{%}

圖 7-6 在應(yīng)用啟動時(shí),從數(shù)據(jù)庫中讀取數(shù)據(jù),如果數(shù)據(jù)不為空則顯示數(shù)據(jù)

塊的作用

理解這些塊的方法是設(shè)想用戶的使用過程:用戶首次打開應(yīng)用,先保存位置信息,稍后再次打開應(yīng)用。首次打開應(yīng)用,數(shù)據(jù)庫中沒有信息可加載,也不必填寫“已記錄”label或啟用DirectionsButton。在后續(xù)的使用中,如果確有數(shù)據(jù)存儲,就要從數(shù)據(jù)庫中加載這些位置信息。

首先用“address”為tag(標(biāo)簽)調(diào)用TinyDB1.GetValue函數(shù),之前在存儲位置信息時(shí)使用過這個(gè)tag。讀取的值保存在變量tempAddress中,并檢查其是否為空。

if塊將檢查從數(shù)據(jù)庫中讀出的數(shù)據(jù)。如果TinyDB對指定的tag沒有返回值,則返回空文本。首次啟動應(yīng)用時(shí)沒有數(shù)據(jù)可讀,直到用戶點(diǎn)擊了RememberButton。由于變量tempAddress中保存了數(shù)據(jù)庫的返回值,因此if塊將檢查tempAddress的長度,如果長度>0,則TinyDB有地址信息返回,也表明經(jīng)緯度.GetValue讀出經(jīng)緯度信息。當(dāng)設(shè)置完所有信息,最后啟用DirectionsButton。

 測試:將新版本應(yīng)用下載到手機(jī),并再次測試。點(diǎn)擊RememberButton,并確保“記住”讀數(shù)。關(guān)閉應(yīng)用并再次打開。那些數(shù)據(jù)是否還在?

完整的應(yīng)用:Android,我的車在哪兒?

圖7-7顯示了完整的“Android,我的車在哪兒?”應(yīng)用中所用到的塊。

{%}

圖 7-7 “Android,我的車在哪兒”應(yīng)用中所有的塊

改進(jìn)

可以嘗試如下改進(jìn):

  • 創(chuàng)建一個(gè)“Android,他們在哪兒?”的應(yīng)用,讓一群人可以了解彼此行蹤。無論你在徒步旅行還是在公園散步,這個(gè)應(yīng)用都有助于你節(jié)省時(shí)間,甚至可能挽救生命。應(yīng)用中的數(shù)據(jù)是共享的,因此要使用web數(shù)據(jù)庫,用TinyWebDB組件來替代TinyDB。更多信息請參見第22章。

  • 創(chuàng)建一個(gè)“行蹤”應(yīng)用,用列表來記錄自己的位置改變,即行蹤。當(dāng)記錄數(shù)達(dá)到一定數(shù)量時(shí),或超過一定時(shí)間時(shí),開始一個(gè)新的“行蹤”,因?yàn)榧词故禽p微的位移也會產(chǎn)生一個(gè)新的位置讀數(shù)。這類應(yīng)用需要使用列表來存儲位置記錄,需要幫助時(shí)請參見第19章。

小結(jié)

下面是本章涉及到的概念:

  • LocationSensor組件:可以報(bào)告用戶的緯度、經(jīng)度及當(dāng)前的街區(qū)地址。當(dāng)傳感器首次獲得數(shù)據(jù)或數(shù)據(jù)發(fā)生變化(設(shè)備移動)時(shí),將觸發(fā)LocationChanged事件。有關(guān)LocationSensor的更多信息,請參見第23章;

  • ActivityStarter組件:可以在一個(gè)應(yīng)用中打開其他應(yīng)用,包括谷歌地圖。對于地圖,需要將ActivityStarter的DataUri屬性設(shè)置為想要打開的地圖的URL地址。如果你想顯示兩個(gè)GPS坐標(biāo)之間的方向,URL應(yīng)該寫成下面的格式,你可以用實(shí)際位置的GPS坐標(biāo)來替換下面的示例數(shù)據(jù):http://maps.google.com/maps/?saddr=0.1,0.1&daddr=0.2,0.2;

  • join用來將文本片段拼湊(連擊)成單一的文本對象,也可以讓靜態(tài)文本與動態(tài)數(shù)據(jù)相連接。對于地圖URL來說,GPS坐標(biāo)就是動態(tài)數(shù)據(jù);

  • TinyDB讓數(shù)據(jù)永久地保存在在手機(jī)的數(shù)據(jù)庫中。保存在變量或?qū)傩灾袛?shù)據(jù),會隨著應(yīng)用的關(guān)閉而丟失,但存儲在數(shù)據(jù)庫中的數(shù)據(jù),可以在每次啟動應(yīng)用時(shí)被載入。有關(guān)TinyDB和數(shù)據(jù)庫的詳細(xì)信息,請參見第22章。

資源下載

AndroidWhere.aia

AndroidWhere.apk

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號