From 23b5f879aeeddc75fcc75dcdbeea8fc86955f30a Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Thu, 10 Nov 2011 16:51:10 -0800 Subject: [PATCH] merge heads --- MyTracks/res/layout/about.xml | 2 +- MyTracks/res/layout/send_to_google_result.xml | 2 +- MyTracks/res/values-ca/strings.xml | 9 +- MyTracks/res/values-de/strings.xml | 9 +- MyTracks/res/values-es/strings.xml | 10 +- MyTracks/res/values-fi/strings.xml | 8 +- MyTracks/res/values-fr/strings.xml | 7 +- MyTracks/res/values-it/strings.xml | 7 +- MyTracks/res/values-ja/strings.xml | 8 +- MyTracks/res/values-pl/strings.xml | 7 +- MyTracks/res/values-pt-rBR/strings.xml | 7 +- MyTracks/res/values-ru/strings.xml | 8 +- MyTracks/res/values-sv/strings.xml | 5 - MyTracks/res/values-zh-rCN/strings.xml | 9 - MyTracks/res/values/do_not_translate.xml | 13 +- MyTracks/res/values/keys.xml | 2 +- MyTracks/res/values/strings.xml | 141 ++++++-------- MyTracks/res/xml/preferences.xml | 9 +- .../mytracks/AutoCompleteTextPreference.java | 64 ++++++ .../android/apps/mytracks/CheckUnits.java | 72 +++---- .../apps/mytracks/ImportAllTracks.java | 82 ++++++-- .../apps/mytracks/SettingsActivity.java | 39 +--- .../android/apps/mytracks/io/SendToDocs.java | 13 +- .../apps/mytracks/io/SendToFusionTables.java | 14 +- .../apps/mytracks/io/SendToMyMaps.java | 18 +- .../apps/mytracks/io/file/ImportActivity.java | 184 ++---------------- .../apps/mytracks/io/mymaps/MapsFacade.java | 3 +- .../io/sendtogoogle/SendActivity.java | 9 +- .../mytracks/io/sendtogoogle/SendType.java | 6 +- .../services/TrackRecordingService.java | 6 + .../services/tasks/StatusAnnouncerTask.java | 6 +- .../apps/mytracks/util/StringUtils.java | 18 +- .../services/TrackRecordingServiceTest.java | 2 + .../tasks/StatusAnnouncerTaskTest.java | 52 +++++ 34 files changed, 378 insertions(+), 473 deletions(-) create mode 100644 MyTracks/src/com/google/android/apps/mytracks/AutoCompleteTextPreference.java diff --git a/MyTracks/res/layout/about.xml b/MyTracks/res/layout/about.xml index 0870154b7..56c721c37 100644 --- a/MyTracks/res/layout/about.xml +++ b/MyTracks/res/layout/about.xml @@ -119,7 +119,7 @@ limitations under the License. android:autoLink="web" android:layout_height="wrap_content" android:layout_width="wrap_content" - android:text="@string/about_weburl" + android:text="@string/my_tracks_web_url" android:textSize="18sp" /> diff --git a/MyTracks/res/layout/send_to_google_result.xml b/MyTracks/res/layout/send_to_google_result.xml index 32b7078d7..e457935cf 100644 --- a/MyTracks/res/layout/send_to_google_result.xml +++ b/MyTracks/res/layout/send_to_google_result.xml @@ -59,7 +59,7 @@ services. android:id="@+id/send_to_google_result_error" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="@string/error_generic" + android:text="@string/error_sending_to_google" android:visibility="gone" style="?android:attr/textAppearanceLarge"/> diff --git a/MyTracks/res/values-ca/strings.xml b/MyTracks/res/values-ca/strings.xml index d69bc6c7b..1c94be163 100644 --- a/MyTracks/res/values-ca/strings.xml +++ b/MyTracks/res/values-ca/strings.xml @@ -41,7 +41,7 @@ limitations under the License. No es pot aturar l\'enregistrament. Proveu de nou. No es pot llegir des del fitxer. El fitxer no conté un format GPX vàlid. - S\'ha produït un error. Proveu de nou. + S\'ha produït un error. Proveu de nou. No existeix la ruta. Aquest fitxer és massa gran (ha d\'ésser inferior a 500KB. S\'està cancel·lant. No es pot inserir un marcador. No hi ha cap ubicació fixa disponible. @@ -50,10 +50,6 @@ limitations under the License. S\'està esperant per tenir una posició GPS fixa. Assegureu-vos que el cel és visible. Ara s\'està enregistrant una ruta nova. S\'ha aturat l\'enregistrament de la ruta. - S\'ha creat un Google Fusion Table nou a google.com/fusiontables. - S\'ha enviat la ruta a maps.google.com. - S\'ha enviat la ruta a un full de càlcul a docs.google.com. - S\'ha enviat la ruta a docs.google.com. Toqueu aquí per anar als paràmetres de seguretat i ubicació i activeu \'habilita els satèl·lits GPS\'. Premeu el botó d\'anar enrere per tornar. Nota: Es mostra una ubicació determinada a partir de les xarxes sense fils i antenes telefòniques. No es pot determinar la ubicació. Habiliteu més fonts d\'ubicació (vegeu els paràmetres de seguretat i ubicació) i assegureu-vos que el cel és visible. Proveu de nou més tard. @@ -82,8 +78,7 @@ limitations under the License. Creat per My Tracks a l\'Android. - Creat per <a href=\'http://mytracks.appspot.com\'>My Tracks</a> a l\'Android. - + Enregistrat Tipus d\'activitat diff --git a/MyTracks/res/values-de/strings.xml b/MyTracks/res/values-de/strings.xml index a0118fa4a..fa0f01ad5 100644 --- a/MyTracks/res/values-de/strings.xml +++ b/MyTracks/res/values-de/strings.xml @@ -41,7 +41,7 @@ limitations under the License. Anhalten unmöglich. Bitte versuche es noch einmal. Konnte Datei nicht lesen. Datei ist nicht im GPX-Format. - Ein Fehler ist aufgetreten. Bitte versuche es noch einmal. + Ein Fehler ist aufgetreten. Bitte versuche es noch einmal. Track existiert nicht. Die Datei ist zu groß (maximal 500 KB). Operation abgebrochen. Der Wegpunkt kann nicht einfügt werden. Keine Positionsbestimmung möglich. @@ -50,10 +50,6 @@ limitations under the License. Warte auf ein besseres GPS-Signal. Bitte stelle sicher, dass der Himmel sichtbar ist. Ein neuer Track wird aufgezeichnet. Die Aufzeichnung wurde angehalten. - Eine neue Tabelle wurde auf google.com/fusiontables erstellt. - Dein Track wurde auf maps.google.com gespeichert. - Dein Track wurde in einer neuen Tabelle bei docs.google.com gespeichert. - Dein Track wurde an docs.google.com gesendet. Hier berühren, um zu den Sicherheits- und Positionseinstellungen zu gelangen. Aktiviere \'GPS-Satelliten\'. Drücke dann den Zurück-Knopf, um hierher zurückzukehren. Anmerkung: Eine ungefähre Position wird angezeigt, bestimmt mittels Mobilfunkstationen und WiFi-Netzwerken. Die Position kann derzeit nicht bestimmt werden. Aktiviere mehr Positionsquellen (siehe Sicherheits- und Positionseinstellungen) und stelle sicher, dass der Himmel sichtbar ist. @@ -82,8 +78,7 @@ limitations under the License. Erstellt von My Tracks für Android. - Erstellt von <a href=\'http://mytracks.appspot.com\'>My Tracks</a> für Android. - + Punkte Aufgezeichnet am diff --git a/MyTracks/res/values-es/strings.xml b/MyTracks/res/values-es/strings.xml index 2e6923f61..2fb745a3c 100644 --- a/MyTracks/res/values-es/strings.xml +++ b/MyTracks/res/values-es/strings.xml @@ -43,7 +43,7 @@ limitations under the License. No se puede detener la grabación. Inténtelo de nuevo. No pude leer del archivo. El archivo no tiene un format GPX válido. - A ocurrido un error. Por favor, inténtelo de nuevo. + A ocurrido un error. Por favor, inténtelo de nuevo. El recorrido no existe. La operación fue cancelada. El archivo es demasiado grande (tiene que ser menor a 500 KB). Abortando. @@ -53,11 +53,6 @@ limitations under the License. Esperando una ubicación mas exacta del GPS. Asegúrese que el cielo sea visible. Grabando un nuevo recorrido. Grabación interrumpida. - Un nuevo sitio ha sido añadido en maps.google.com. - Una nueva tabla de Google Fusion ha sido creada en google.com/fusiontables. - Su recorrido ha sido enviado a maps.google.com. - Su recorrido ha sido enviado a una nueva hoja de cálculo de docs.google.com. - Su recorrido ha sido enviado a docs.google.com. Es posible que pasen unos minutos hasta que los nuevos recorridos aparezcan. Por favor, presione aquí para ir al menú de Seguridad y Ubicación, y asegúrese que el GPS esté habilitado. Presione el botón "atrás" para regresar. Nota: Una ubicación aproximada es determinada a partir de torres de telefonía celular y redes WIFI. @@ -92,8 +87,7 @@ limitations under the License. Creado por My Tracks para Android. - Creado por <a href=\'http://mytracks.appspot.com\'>My Tracks</a> en Android. - + Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> en Android. Nuevo Sitio diff --git a/MyTracks/res/values-fi/strings.xml b/MyTracks/res/values-fi/strings.xml index 9929e7f53..b88779a81 100644 --- a/MyTracks/res/values-fi/strings.xml +++ b/MyTracks/res/values-fi/strings.xml @@ -53,11 +53,6 @@ limitations under the License. Odotetaan parempaa GPS-yhteyttä. Varmista että taivas on näkyvissä. Tallennetaan uutta reittiä. Reitin tallentaminen lopetettiin. - Uusi Google My Map on luotu osoitteeseen maps.google.com. - Uusi Google Fusion taulukko on luotu osoitteeseen google.com/fusiontables. - Reittisi on lähetetty osoitteeseen maps.google.com. - Reittisi on luotu taulukoksi osoitteeseen docs.google.com. - Reittisi on lähetetty osoitteeseen docs.google.com. Reitin näkyminen saattaa kestää muutaman minuutin. Avaa tästä Sijainti ja suojaus -asetukset ja valitse \'Käytä GPS-satelliitteja\'. Palaa ohjelmaan painamalla Takaisin-näppäintä. Huomio: Näkyvä sijainti perustuu kännykkämastoista ja WLAN-verkoista arvioituun paikkatietoon. @@ -91,8 +86,7 @@ limitations under the License. Created by My Tracks on Android. - Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> on Android. - + Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> on Android. Uusi kartta diff --git a/MyTracks/res/values-fr/strings.xml b/MyTracks/res/values-fr/strings.xml index 034e017f6..12ba8761e 100644 --- a/MyTracks/res/values-fr/strings.xml +++ b/MyTracks/res/values-fr/strings.xml @@ -51,10 +51,6 @@ limitations under the License. Attente du signal GPS. Assurez-vous que le ciel est bien visible. Parcours en cours d\'enregistrement. Enregistrement du parcours terminé. - Une nouvelle table Google Fusion vient d\'être créée sur google.com/fusiontables. - Votre parcours a été envoyé à maps.google.com. - Votre parcours a été envoyé dans un tableur à docs.google.com. - Votre parcours a été envoyé à docs.google.com. Cliquez ici et allez dans \'Paramètres\', \'Sécurité et Localisation\' et selectionnez \'Activer les satellites GPS\'. Appuyez sur le bouton de retour pour revenir au menu. Note : Votre position est approximative, elle a été déterminée par les antennes de téléphonie ou le réseau WiFi. Votre position ne peut être déterminée. Vérifiez votre configuration dans \'Paramètres\', \'Sécurité et Localisation\'. Assurez-vous également que le ciel soit bien visible. @@ -83,8 +79,7 @@ limitations under the License. Créée par My Tracks sous Android. - Créée par <a href=\'http://mytracks.appspot.com\'>My Tracks</a> sous Android. - + Enregistré Type d\'activité diff --git a/MyTracks/res/values-it/strings.xml b/MyTracks/res/values-it/strings.xml index eef86e8e7..b19d7366d 100644 --- a/MyTracks/res/values-it/strings.xml +++ b/MyTracks/res/values-it/strings.xml @@ -48,10 +48,6 @@ limitations under the License. Sto aspettando il fix del GPS. Accertati che il cielo sia visibile. Sto registrando un nuovo percorso. Registrazione del percorso terminata. - - Il tuo percorso è stato inviato a maps.google.com. - Il tuo percorso è stato inviato ad un nuovo foglio di calcolo su docs.google.com. - Il tuo percorso è stato inviato a docs.google.com. Premi qui per andare a «Impostazioni di posizione e protezione» e attiva «Utilizza satelliti GPS». Poi premi il tasto di ritorno per tornare qui. Nota: la posizione indicata è un\'approssimazione determinata in base alle antenne cellulari e reti WIFI vicine. La posizione non può essere determinata. Attiva più fonti di posizione (vedi «Impostazioni di posizione e protezione») e eccertati che il cielo sia visibile. Riprova più tardi. @@ -80,8 +76,7 @@ limitations under the License. Creato da My Tracks su Android. - Creato da <a href=\'http://mytracks.appspot.com\'>My Tracks</a> su Android. - + Punti Registrato diff --git a/MyTracks/res/values-ja/strings.xml b/MyTracks/res/values-ja/strings.xml index 1c43bdf28..213f27308 100644 --- a/MyTracks/res/values-ja/strings.xml +++ b/MyTracks/res/values-ja/strings.xml @@ -51,11 +51,6 @@ limitations under the License. GPS位置精度がよくなるまで待機しています.空が見えるところにいて下さい. 新しいトラックを記録中です. トラック記録を停止しました. - 新しいマイマップをmap.google.comに作成しました. - 新しいGoogle Fusion Tableをgoogle.com/fusiontablesに作成しました. - トラックをmaps.google.comに送信しました. - トラックをdocs.google.comの新しいスプレッドシートに送信しました. - トラックをdocs.google.comに送信しました. 新しいトラックが表示されるまでに数分かかることがあります. ここをタップして「位置情報とセキュリティの設定」を開いて「GPS機能を使用」にチェックを入れて下さい.バックボタンで戻ってください. ご注意: 携帯電話中継局とWi-Fiネットワークから大まかな位置を特定します. @@ -88,8 +83,7 @@ limitations under the License. Android用My Tracksで作成 - Android用<a href=\'http://mytracks.appspot.com\'>My Tracks</a>で作成しました. - + Android用<a href=\'http://mytracks.appspot.com\'>My Tracks</a>で作成しました. 新規マップ diff --git a/MyTracks/res/values-pl/strings.xml b/MyTracks/res/values-pl/strings.xml index 3870dd830..9f4f27d02 100644 --- a/MyTracks/res/values-pl/strings.xml +++ b/MyTracks/res/values-pl/strings.xml @@ -49,10 +49,6 @@ limitations under the License. Oczekiwanie na lepsze ustalenie pozycji GPS. Upewnij się, że niebo jest widoczne. Rejestrowanie nowej trasy. Zatrzymano rejestrowanie nowej trasy. - - Twoja trasa został wysłana do maps.google.com. - Twoja trasa została wysłana do nowego arkusza na docs.google.com. - Twoja trasa została wysłana do docs.google.com. Tapnij tutaj, aby przejść do ustawień Lokalizacji i zabezpieczeń, a następnie zaznacz Użyj satelitów GPS. Naciśnij klawisz Wstecz, aby powrócić. Uwaga: używana jest przybliżona lokalizacja ustalona za pomocą stacji komórkowych i sieci WIFI. Lokalizacja nie może być obecnie ustalona. Włącz wiecej źródeł (zobacz ustawienia Lokalizacji i zabezpieczeń) i upewnij się, że niebo jest widoczne. Spróbuj później. @@ -81,8 +77,7 @@ limitations under the License. Utworzono za pomocą My Tracks na Android. - Utworzona przez <a href=\'http://mytracks.appspot.com\'>My Tracks</a> na Android. - + Punkty Zapisana diff --git a/MyTracks/res/values-pt-rBR/strings.xml b/MyTracks/res/values-pt-rBR/strings.xml index f7c29ade4..2efa9e137 100644 --- a/MyTracks/res/values-pt-rBR/strings.xml +++ b/MyTracks/res/values-pt-rBR/strings.xml @@ -48,10 +48,6 @@ limitations under the License. Esperando por um sinal melhor do GPS. Assegure-se de que o céu está visível. Gravando um novo caminho. Gravação interrompida. - Uma nova Fusion Table Google foi criada em google.com/fusiontables. - Seu caminho foi enviado para maps.google.com. - Seu caminho foi enviado para uma nova planilha em docs.google.com. - Seu caminho foi enviado para docs.google.com. "Por favor pressione aqui para ir aos ajustes de segurança e localização e verifique que o GPS esteja habilitado. Pressione o botão de voltar para retornar. Nota: Uma localização aproximada, determinada por torres de telefonia celular, está sendo mostrada. Sua localização não pôde ser determinada. Habilite fontes adicionais de localização (veja configurações de Segurança e Localização) e assegure-se de que o céu está visível. @@ -80,8 +76,7 @@ limitations under the License. "Criado por My Tracks no Android. - "Criado por <a href='http://mytracks.appspot.com'>My Tracks</a> no Android. - + Pontos Gravado diff --git a/MyTracks/res/values-ru/strings.xml b/MyTracks/res/values-ru/strings.xml index f780e3ef5..9aa6ef319 100644 --- a/MyTracks/res/values-ru/strings.xml +++ b/MyTracks/res/values-ru/strings.xml @@ -52,11 +52,6 @@ limitations under the License. Ожидание сигнала GPS. Убедитесь в том, что вы находитесь под открытым небом. Записывается новый трек. Запись вашего трека остановлена. - Новая Google \"Мои карты\" была создана на maps.google.com. - Новая таблица Google Fusion была создана на google.com/fusiontables. - Твой трек был отправлен на maps.google.com. - Ваш трек был отправлен в новую электронную таблицу на docs.google.com. - Ваш трек был отправлен в docs.google.com. Это может занять несколько минут, прежде чем появятся новые треки. Пожалуйста, нажмите здесь для перехода к разделу настроек Координаты и отметьте пункт \"Спутники GPS\". Для возвращения нажмите кнопку Назад. Примечание: приблизительное местоположение определено относительно вышек сотовой связи и беспроводных сетей. @@ -90,8 +85,7 @@ limitations under the License. Создано My Tracks на Android. - Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android. - + Создано <a href=\'http://mytracks.appspot.com\'>My Tracks</a> на Android. Новая карта diff --git a/MyTracks/res/values-sv/strings.xml b/MyTracks/res/values-sv/strings.xml index c1d579373..38116b013 100644 --- a/MyTracks/res/values-sv/strings.xml +++ b/MyTracks/res/values-sv/strings.xml @@ -49,10 +49,6 @@ limitations under the License. Väntar på bättre GPS-position. Se till att himlen är synlig. Spelar nu in ett nytt spår. Stoppade inspelning av ditt spår. - - Ditt spår har skickats till maps.google.com. - Ditt spår har skickats till ett nytt kalkylblad på docs.google.com. - Ditt spår har skickats till docs.google.com. Klicka här för att gå till Säkerhet och Platsinställningar och kryssa i \'aktivera gps-satteliter\'. Tryck på tillbakaknappen för att återgå. OBS: En ungefärlig position som avgörs från mobilmaster och WIFI-nät visas. En position kan för närvarande inte fastställas. Aktivera mer platskällor (se Säkerhet och Platsinställningar) och se till att himlen är synlig. Försök igen senare. @@ -81,7 +77,6 @@ limitations under the License. Skapad av My Tracks på Android. - Skapad av <a href=\'http://mytracks.appspot.com\'>My Tracks</a> på Android. Punkter diff --git a/MyTracks/res/values-zh-rCN/strings.xml b/MyTracks/res/values-zh-rCN/strings.xml index bf31481c4..ff8205959 100644 --- a/MyTracks/res/values-zh-rCN/strings.xml +++ b/MyTracks/res/values-zh-rCN/strings.xml @@ -53,11 +53,6 @@ limitations under the License. 等待更准确的 GPS 定位. 请确定可以看见天空. 现在开始记录新的轨迹. 停止记录你的轨迹. - 已在 maps.google.com 创建了新的 Google My Map. - 已在 google.com/fusiontables 创建新 Google Fusion Table. - 你的轨迹已经发送到 maps.google.com. - 你的轨迹已经作为新的电子表格发送到 docs.google.com. - 你的轨迹已经发送到 docs.google.com. 可能需要等待几分钟才能看见新的轨迹. 请点击这里进入\'安全和位置设置\'并勾选上\'启用 GPS 卫星\'. 然后用后退键返回. 注意: 当前显示的位置是根据无线信号和无线网络计算的近似位置. @@ -91,10 +86,6 @@ limitations under the License. 由 Android 平台的 My Tracks 创建. - 由 Android 平台的 <a href=\'http://mytracks.appspot.com\'>My Tracks</a> 创建. - - - 由 Android 上的 <a href=\'http://mytracks.appspot.com\'>My Tracks</a> 创建. 新地图 diff --git a/MyTracks/res/values/do_not_translate.xml b/MyTracks/res/values/do_not_translate.xml index 4fe28ab38..fa8935ed5 100644 --- a/MyTracks/res/values/do_not_translate.xml +++ b/MyTracks/res/values/do_not_translate.xml @@ -20,8 +20,10 @@ limitations under the License. My Tracks - - mytracks.appspot.com + mytracks.appspot.com + + + mytracks@googlegroups.com m.google.com/privacy Bartłomiej Niechwiej Dylan Casey @@ -45,9 +47,9 @@ limitations under the License. - - maps.google.com - google.com/fusiontables - docs.google.com + google.com/fusiontables + maps.google.com + docs.google.com UA-7222692-2 @@ -57,7 +59,6 @@ limitations under the License. android.intent.action.SAVE - android.intent.action.settings.OPEN com.google.android.apps.mytracks.START_NEW_TRACK com.google.android.apps.mytracks.END_CURRENT_TRACK diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index def4309b5..1c023e303 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -23,6 +23,7 @@ limitations under the License. autoResumeTrackTimeout bluetoothPairing bluetoothSensor + defaultCategory defaultMapPublic maxRecordingDistance metricUnits @@ -57,7 +58,6 @@ limitations under the License. antOptions backupToSd - displaySettingsScreen resetToDefaults restoreFromSd sensorOptions diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index cb701b6a3..7e8dbb15d 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -86,14 +86,12 @@ limitations under the License. Unable to insert marker. No GPS location. Try again. - - + + An error occurred. Please try again. - - @@ -108,27 +106,8 @@ limitations under the License. translation_description="When sending a track to Google Docs, a message indicating that an error has occurred."> There was an error while sending your track to Google Docs. - - - - - Unable to read from file. - - - File does not have a valid GPX format. - - - - - This file is too big (must be less than 500 KB). Aborting. - - + + It may take a few minutes before new tracks appear. - - A new Google My Map has been created at maps.google.com. + + Your track has been sent to %s. - - Your track has been sent to maps.google.com. + + A new spreadsheet is created at %s. - - A new Google Fusion table has been created at google.com/fusiontables. + page indicating success. E.g., 'A new Google Fusion table has been created at + google.com/fusiontables.'"> + A new Google Fusion table has been created at %s. - - A new spreadsheet is created at docs.google.com. + + Your track has been sent to %s. - - Your track has been sent to docs.google.com. + + A new Google My Map has been created at %s. - + - Importing a track from the SD card. This may take a while. - + @@ -310,12 +289,12 @@ limitations under the License. - - - Created by <a href=\'http://mytracks.appspot.com\'>My Tracks</a> on Android. + My Tracks on Android. The two string placeholders are used to insert the html link tags around + 'My Tracks'. E.g., 'Created by <a href=\'http://mytracks.appspot.com\'>My Tracks + </a> on Android.'."> + Created by %1$sMy Tracks%2$s on Android. @@ -528,7 +507,7 @@ limitations under the License. - Imported %1$d of %2$d GPX files from %3$s + Imported to My Tracks %1$d of %2$d GPX files from %3$s Import error for file %s - - Successfully imported %d track(s) from file. - - - Show track - Use a number as the default track name - + + Default activity type + + + Default activity type for a new track. + + @@ -1630,18 +1610,23 @@ limitations under the License. My Tracks total distance %1$.2f %2$s in %3$s at %4$s %5$s - - + + Preferred Units - - Do you want to use metrics as the preferred units? + + Metric - + + Imperial + + - + + + diff --git a/MyTracks/src/com/google/android/apps/mytracks/AutoCompleteTextPreference.java b/MyTracks/src/com/google/android/apps/mytracks/AutoCompleteTextPreference.java new file mode 100644 index 000000000..0096b1815 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/AutoCompleteTextPreference.java @@ -0,0 +1,64 @@ +package com.google.android.apps.mytracks; + +import com.google.android.maps.mytracks.R; + +import android.content.Context; +import android.preference.EditTextPreference; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; + +/** + * The {@link AutoCompleteTextPreference} class is a preference that allows for + * string input using auto complete . It is a subclass of + * {@link EditTextPreference} and shows the {@link AutoCompleteTextView} in a + * dialog. + *

+ * This preference will store a string into the SharedPreferences. + * + * @author Rimas Trumpa (with Matt Levan) + */ +public class AutoCompleteTextPreference extends EditTextPreference { + + private AutoCompleteTextView mEditText = null; + + public AutoCompleteTextPreference(Context context, AttributeSet attrs) { + super(context, attrs); + mEditText = new AutoCompleteTextView(context, attrs); + mEditText.setThreshold(0); + + // Gets autocomplete values for 'Default Activity' preference + if (getKey().equals(context.getString(R.string.default_category_key))) { + ArrayAdapter adapter = ArrayAdapter.createFromResource(context, + R.array.activity_types, android.R.layout.simple_dropdown_item_1line); + mEditText.setAdapter(adapter); + } + } + + @Override + protected void onBindDialogView(View view) { + AutoCompleteTextView editText = mEditText; + editText.setText(getText()); + + ViewParent oldParent = editText.getParent(); + if (oldParent != view) { + if (oldParent != null) { + ((ViewGroup) oldParent).removeView(editText); + } + onAddEditTextToDialogView(view, editText); + } + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + if (positiveResult) { + String value = mEditText.getText().toString(); + if (callChangeListener(value)) { + setText(value); + } + } + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java b/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java index 104242f75..a35f4409d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java +++ b/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java @@ -23,73 +23,63 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; -import java.util.Locale; - /** - * Check to see if the units are the default for the locale. - * This comes down to warning Americans that the default is metric. + * Checks with the user if he prefers the metric units or the imperial units. * * @author Sandor Dornbush */ class CheckUnits { - private static final String PREFERENCE_UNITS_CHECKED = "checkunits.checked"; - private static final String PREFERENCES_CHECK_UNITS = "checkunits"; + private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits"; + private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked"; + private static boolean metric = true; - static void check(final Context context) { - final SharedPreferences preferences = - context.getSharedPreferences(PREFERENCES_CHECK_UNITS, Activity.MODE_PRIVATE); - - // Has the user already warned about the default units? - if (preferences.getBoolean(PREFERENCE_UNITS_CHECKED, false)) { + public static void check(final Context context) { + final SharedPreferences checkUnitsSharedPreferences = context.getSharedPreferences( + CHECK_UNITS_PREFERENCE_FILE, Activity.MODE_PRIVATE); + if (checkUnitsSharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false)) { return; } - // Is the user in the US? - Locale current = Locale.getDefault(); - Locale enUs = new Locale(Locale.ENGLISH.getLanguage(), - Locale.US.getCountry()); - if (!current.equals(enUs)) { - return; - } - - final AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.check_units_title); - builder.setCancelable(true); - builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(context.getString(R.string.preferred_units_title)); + CharSequence[] items = { context.getString(R.string.preferred_units_metric), + context.getString(R.string.preferred_units_imperial) }; + builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int which) { - recordCheckPerformed(preferences); + if (which == 0) { + metric = true; + } else { + metric = false; + } } }); - builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + builder.setCancelable(true); + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - changeDefaultUnits(context, preferences); + recordCheckPerformed(checkUnitsSharedPreferences); + SharedPreferences useMetricPreferences = context.getSharedPreferences( + Constants.SETTINGS_NAME, Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = useMetricPreferences.edit(); + String key = context.getString(R.string.metric_units_key); + ApiFeatures.getInstance().getApiAdapter().applyPreferenceChanges( + editor.putBoolean(key, metric)); } }); builder.setOnCancelListener(new DialogInterface.OnCancelListener() { public void onCancel(DialogInterface dialog) { - recordCheckPerformed(preferences); + recordCheckPerformed(checkUnitsSharedPreferences); } }); - builder.setMessage(R.string.check_units_message); builder.show(); } - private static void changeDefaultUnits(Context context, SharedPreferences preferences) { - recordCheckPerformed(preferences); - Intent startIntent = new Intent(context, SettingsActivity.class); - startIntent.putExtra(context.getString(R.string.open_settings_screen), - context.getString(R.string.display_settings_screen_key)); - context.startActivity(startIntent); - } - private static void recordCheckPerformed(SharedPreferences preferences) { ApiFeatures.getInstance().getApiAdapter().applyPreferenceChanges( - preferences.edit().putBoolean(PREFERENCE_UNITS_CHECKED, true)); + preferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true)); } - private CheckUnits() { - } + private CheckUnits() {} } diff --git a/MyTracks/src/com/google/android/apps/mytracks/ImportAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/ImportAllTracks.java index dfea7d5d5..248899c65 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ImportAllTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ImportAllTracks.java @@ -16,6 +16,7 @@ package com.google.android.apps.mytracks; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; +import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.io.file.GpxImporter; import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.SystemUtils; @@ -24,7 +25,11 @@ import com.google.android.maps.mytracks.R; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.ContentUris; +import android.content.DialogInterface; +import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.PowerManager.WakeLock; import android.util.Log; import android.widget.Toast; @@ -49,22 +54,36 @@ import org.xml.sax.SAXException; public class ImportAllTracks { private final Activity activity; + private FileUtils fileUtils; + private boolean singleTrackSelected; + private String gpxPath; private WakeLock wakeLock; private ProgressDialog progress; - private FileUtils fileUtils; - private String gpxPath; private int gpxFileCount; private int importSuccessCount; - + private long importedTrackIds[]; + public ImportAllTracks(Activity activity) { - this.activity = activity; - Log.i(Constants.TAG, "ImportAllTracks: Starting"); - fileUtils = new FileUtils(); - gpxPath = fileUtils.buildExternalDirectoryPath("gpx"); - - new Thread(runner).start(); + this(activity, null); } + /** + * Constructor to import tracks. + * + * @param activity the activity + * @param path path of the gpx file to import and display. If null, then just + * import all the gpx files under MyTracks/gpx and do not display any + * track. + */ + public ImportAllTracks(Activity activity, String path) { + Log.i(Constants.TAG, "ImportAllTracks: Starting"); + this.activity = activity; + fileUtils = new FileUtils(); + singleTrackSelected = path != null; + gpxPath = path == null ? fileUtils.buildExternalDirectoryPath("gpx") : path; + new Thread(runner).start(); + } + private final Runnable runner = new Runnable() { public void run() { aquireLocksAndImport(); @@ -81,7 +100,7 @@ public class ImportAllTracks { if (prefs != null) { recordingTrackId = prefs.getLong(activity.getString(R.string.recording_track_key), -1); } - if (recordingTrackId != -1) { + if (recordingTrackId == -1) { wakeLock = SystemUtils.acquireWakeLock(activity, wakeLock); } @@ -107,12 +126,26 @@ public class ImportAllTracks { Log.i(Constants.TAG, "ImportAllTracks: Done"); AlertDialog.Builder builder = new AlertDialog.Builder(activity); if (gpxFileCount == 0) { - builder.setMessage(activity.getString(R.string.import_multi_empty, gpxPath + "/")); + builder.setMessage(activity.getString(R.string.import_multi_empty, gpxPath)); } else { builder.setMessage(activity.getString(R.string.import_multi_done, importSuccessCount, gpxFileCount, - gpxPath + "/")); + gpxPath)); } - builder.setPositiveButton(R.string.ok, null); + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (singleTrackSelected) { + long lastTrackId = importedTrackIds[importedTrackIds.length - 1]; + Uri trackUri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, lastTrackId); + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(trackUri, TracksColumns.CONTENT_ITEMTYPE); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + activity.startActivity(intent); + activity.finish(); + } + } + }); builder.show(); } @@ -185,7 +218,7 @@ public class ImportAllTracks { private boolean importFile(File gpxFile, MyTracksProviderUtils providerUtils) { Log.i(Constants.TAG, "ImportAllTracks: importing: " + gpxFile.getName()); try { - GpxImporter.importGPXFile(new FileInputStream(gpxFile), providerUtils); + importedTrackIds = GpxImporter.importGPXFile(new FileInputStream(gpxFile), providerUtils); return true; } catch (FileNotFoundException e) { Log.w(Constants.TAG, "GPX file wasn't found/went missing: " @@ -203,15 +236,22 @@ public class ImportAllTracks { } /** - * Returns a list of the GPX Files found in the GPX directory. + * Gets a list of the GPX files. If singleTrackSelected is true, returns a + * list containing just the gpxPath file. If singleTrackSelected is false, + * returns a list of GPX files under the gpxPath directory. */ private List getGpxFiles() { - List gpxFiles = new LinkedList(); - File[] gpxFileCandidates = new File(gpxPath).listFiles(); - if (gpxFileCandidates != null) { - for (File file : gpxFileCandidates) { - if (!file.isDirectory() && file.getName().endsWith(".gpx")) { - gpxFiles.add(file); + List gpxFiles = new LinkedList(); + File file = new File(gpxPath); + if (singleTrackSelected) { + gpxFiles.add(file); + } else { + File[] gpxFileCandidates = file.listFiles(); + if (gpxFileCandidates != null) { + for (File candidate : gpxFileCandidates) { + if (!candidate.isDirectory() && candidate.getName().endsWith(".gpx")) { + gpxFiles.add(candidate); + } } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java index c659a4c87..6bf1a5547 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java @@ -54,10 +54,6 @@ import java.util.Set; /** * An activity that let's the user see and edit the settings. * - * This activity has two entry points, "root" and "display" preference screen. - * If bundle.getString("open_settings_screen") is set to "display_settings_screen_key", then - * the "display" preference screen is shown, otherwise, the "root" display preference is shown. - * * @author Leif Hendrik Wilden * @author Rodrigo Damazio */ @@ -104,16 +100,6 @@ public class SettingsActivity extends PreferenceActivity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); - initActivityCommons(); - - // If we only need the display setting screen nothing else needs to load. - if (processIntent()) - return; - - initActivitySpecifics(); - } - - private void initActivityCommons() { // The volume we want to control is the Text-To-Speech volume ApiFeatures apiFeatures = ApiFeatures.getInstance(); int volumeStream = @@ -146,9 +132,7 @@ public class SettingsActivity extends PreferenceActivity { setRecordingIntervalOptions(); setAutoResumeTimeoutOptions(); - } - - private void initActivitySpecifics() { + // Hook up switching of displayed list entries between metric and imperial // units CheckBoxPreference metricUnitsPreference = @@ -259,23 +243,6 @@ public class SettingsActivity extends PreferenceActivity { list.setEntries(options); } - private boolean processIntent() { - boolean showDisplaySettings = false; - Bundle bundle = getIntent().getExtras(); - PreferenceScreen preferenceScreen; - String intentString = getString(R.string.open_settings_screen); - - if (bundle != null) { - preferenceScreen = (PreferenceScreen) findPreference(bundle.getString(intentString)); - if (preferenceScreen != null) { - showDisplaySettings = true; - setPreferenceScreen(preferenceScreen); - } - } - - return showDisplaySettings; - } - private void customizeSensorOptionsPreferences() { ListPreference sensorTypePreference = (ListPreference) findPreference(getString(R.string.sensor_type_key)); @@ -352,10 +319,6 @@ public class SettingsActivity extends PreferenceActivity { protected void onResume() { super.onResume(); - // If we only need the display setting screen nothing else needs to load. - if (processIntent()) - return; - configureBluetoothPreferences(); Preference backupNowPreference = findPreference(getString(R.string.backup_to_sd_key)); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java index 472d1db0c..2ba84887f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java @@ -22,6 +22,7 @@ import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.io.docs.DocsHelper; import com.google.android.apps.mytracks.io.gdata.GDataClientFactory; import com.google.android.apps.mytracks.io.gdata.GDataWrapper; +import com.google.android.apps.mytracks.io.sendtogoogle.SendType; import com.google.android.common.gdata.AndroidXmlParserFactory; import com.google.android.maps.mytracks.R; import com.google.wireless.gdata.client.GDataClient; @@ -115,13 +116,11 @@ public class SendToDocs { Log.d(Constants.TAG, "SendToDocs: Uploading to spreadsheet"); success = uploadToDocs(track); if (success) { - if (createdNewSpreadSheet) { - statusMessage = activity.getString( - R.string.sending_to_docs_success_new_doc); - } else { - statusMessage = activity.getString( - R.string.sending_to_docs_success_existing_doc); - } + String format = createdNewSpreadSheet + ? activity.getString(R.string.send_google_docs_new_doc_success) + : activity.getString(R.string.send_google_docs_existing_doc_success); + String url = activity.getString(SendType.DOCS.getServiceUrl()); + statusMessage = String.format(format, url); } else { statusMessage = activity.getString(R.string.error_sending_to_docs); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java index 8b6e83be1..571ee6dfd 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java @@ -24,6 +24,7 @@ import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.io.gdata.GDataWrapper; import com.google.android.apps.mytracks.io.gdata.GDataWrapper.QueryFunction; +import com.google.android.apps.mytracks.io.sendtogoogle.SendType; import com.google.android.apps.mytracks.stats.DoubleBuffer; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.ApiFeatures; @@ -71,7 +72,7 @@ public class SendToFusionTables implements Runnable { * Listener invoked when sending to fusion tables completes. */ public interface OnSendCompletedListener { - void onSendCompleted(String tableId, boolean success, int statusMessage); + void onSendCompleted(String tableId, boolean success, String statusMessage); } /** The GData service id for Fusion Tables. */ @@ -168,7 +169,7 @@ public class SendToFusionTables implements Runnable { } private void doUpload() { - int statusMessageId = R.string.error_sending_to_fusion_tables; + String statusMessage = context.getString(R.string.error_sending_to_fusion_tables); boolean success = true; try { progressIndicator.setProgressValue(PROGRESS_INITIALIZATION); @@ -205,17 +206,18 @@ public class SendToFusionTables implements Runnable { return; } - statusMessageId = R.string.sending_to_fusion_tables_success; + String format = context.getString(R.string.send_google_fusion_tables_success); + String url = context.getString(SendType.FUSION_TABLES.getServiceUrl()); + statusMessage = String.format(format, url); Log.d(Constants.TAG, "SendToFusionTables: Done: " + success); progressIndicator.setProgressValue(PROGRESS_COMPLETE); } finally { final boolean finalSuccess = success; - final int finalStatusMessageId = statusMessageId; + final String finalStatusMessage = statusMessage; context.runOnUiThread(new Runnable() { public void run() { if (onCompletion != null) { - onCompletion.onSendCompleted( - tableId, finalSuccess, finalStatusMessageId); + onCompletion.onSendCompleted(tableId, finalSuccess, finalStatusMessage); } } }); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java index 84a6cb0de..9c38d9b8a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java @@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.io.mymaps.MapsFacade; +import com.google.android.apps.mytracks.io.sendtogoogle.SendType; import com.google.android.apps.mytracks.stats.DoubleBuffer; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.LocationUtils; @@ -75,7 +76,7 @@ public class SendToMyMaps implements Runnable { private int totalSegmentsUploaded; public interface OnSendCompletedListener { - void onSendCompleted(String mapId, boolean success, int statusMessage); + void onSendCompleted(String mapId, boolean success, String statusMessage); } public SendToMyMaps(Activity context, String mapId, AuthManager auth, @@ -98,7 +99,7 @@ public class SendToMyMaps implements Runnable { } private void doUpload() { - int statusMessageId = R.string.error_sending_to_my_maps; + String statusMessage = context.getString(R.string.error_sending_to_my_maps); boolean success = true; try { progressIndicator.setProgressMessage( @@ -173,9 +174,11 @@ public class SendToMyMaps implements Runnable { } if (success) { - statusMessageId = isNewMap - ? R.string.sending_to_my_maps_success_new_map - : R.string.sending_to_my_maps_success_existing_map; + String format = isNewMap + ? context.getString(R.string.send_google_my_maps_new_map_success) + : context.getString(R.string.send_google_my_maps_existing_map_success); + String url = context.getString(SendType.MYMAPS.getServiceUrl()); + statusMessage = String.format(format, url); } Log.d(TAG, "SendToMyMaps: Done: " + success); progressIndicator.setProgressValue(100); @@ -185,12 +188,11 @@ public class SendToMyMaps implements Runnable { } final boolean finalSuccess = success; - final int finalStatusMessageId = statusMessageId; + final String finalStatusMessage = statusMessage; context.runOnUiThread(new Runnable() { public void run() { if (onCompletion != null) { - onCompletion.onSendCompleted( - mapId, finalSuccess, finalStatusMessageId); + onCompletion.onSendCompleted(mapId, finalSuccess, finalStatusMessage); } } }); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/ImportActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/ImportActivity.java index f6323aba3..027e35002 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/ImportActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/ImportActivity.java @@ -17,56 +17,21 @@ package com.google.android.apps.mytracks.io.file; import static com.google.android.apps.mytracks.Constants.TAG; -import com.google.android.apps.mytracks.content.MyTracksProviderUtils; -import com.google.android.apps.mytracks.content.TracksColumns; +import com.google.android.apps.mytracks.ImportAllTracks; import com.google.android.apps.mytracks.util.UriUtils; -import com.google.android.maps.mytracks.R; import android.app.Activity; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.ContentUris; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.util.Log; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import javax.xml.parsers.ParserConfigurationException; - -import org.xml.sax.SAXException; - /** - * Helper activity which imports tracks from a file. + * An activity that imports a track from a file and displays the track in My Tracks. * * @author Rodrigo Damazio */ public class ImportActivity extends Activity { - private static final int PROGRESS_DIALOG = 1; - private static final int SUCCESS_DIALOG = 2; - private static final int FAILURE_DIALOG = 3; - - private MyTracksProviderUtils providerUtils; - - private ProgressDialog progressDialog; - private int resultMessage; - private long importedTrackIds[]; - - @Override - public void onCreate(Bundle savedState) { - super.onCreate(savedState); - - providerUtils = MyTracksProviderUtils.Factory.get(this); - } - @Override public void onStart() { super.onStart(); @@ -74,143 +39,20 @@ public class ImportActivity extends Activity { Intent intent = getIntent(); String action = intent.getAction(); Uri data = intent.getData(); - if (!(Intent.ACTION_VIEW.equals(action) || Intent.ACTION_ATTACH_DATA.equals(action)) - || !UriUtils.isFileUri(data)) { - Log.e(TAG, "Received an intent with unsupported action or data: " + intent); + if (!(Intent.ACTION_VIEW.equals(action) || Intent.ACTION_ATTACH_DATA.equals(action))) { + Log.e(TAG, "Received an intent with unsupported action: " + intent); finish(); return; } - - Log.i(TAG, "Importing GPX file at " + data); - startTrackImport(data.getPath()); - } - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case PROGRESS_DIALOG: - progressDialog = new ProgressDialog(this); - progressDialog.setIcon(android.R.drawable.ic_dialog_info); - progressDialog.setTitle(R.string.progress_title); - progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - progressDialog.setMessage(getString(R.string.progress_message_import)); - return progressDialog; - case SUCCESS_DIALOG: - final Builder dialogBuilder = new AlertDialog.Builder(this); - dialogBuilder.setCancelable(true); - dialogBuilder.setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface arg0, int arg1) { - finish(); - } - }); - dialogBuilder.setNegativeButton(R.string.import_show_track, new OnClickListener() { - @Override - public void onClick(DialogInterface arg0, int arg1) { - showImportedTrack(); - finish(); - } - }); - return dialogBuilder.create(); - case FAILURE_DIALOG: - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setPositiveButton(R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface arg0, int arg1) { - finish(); - } - }); - builder.setIcon(android.R.drawable.ic_dialog_alert); - builder.setTitle(R.string.error); - return builder.create(); - + + if (!UriUtils.isFileUri(data)) { + Log.e(TAG, "Received an intent with unsupported data: " + intent); + finish(); + return; } - - return null; - } - - @Override - protected void onPrepareDialog(int id, Dialog dialog) { - super.onPrepareDialog(id, dialog); - - switch (id) { - case SUCCESS_DIALOG: - AlertDialog successDialog = (AlertDialog) dialog; - successDialog.setMessage(getString(R.string.import_success, importedTrackIds.length)); - break; - case FAILURE_DIALOG: - AlertDialog failureDialog = (AlertDialog) dialog; - failureDialog.setMessage(getString(resultMessage)); - break; - } - } - - protected void showImportedTrack() { - long lastTrackId = importedTrackIds[importedTrackIds.length - 1]; - Uri trackUri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, lastTrackId); - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(trackUri, TracksColumns.CONTENT_ITEMTYPE); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - finish(); - } - - private void startTrackImport(final String fileName) { - showDialog(PROGRESS_DIALOG); - - Thread t = new Thread() { - @Override - public void run() { - resultMessage = R.string.success; - - importedTrackIds = null; - - try { - try { - InputStream is = new FileInputStream(fileName); - importedTrackIds = GpxImporter.importGPXFile(is, providerUtils); - } catch (SAXException e) { - Log.e(TAG, "Caught an unexpected exception.", e); - resultMessage = R.string.error_generic; - } catch (ParserConfigurationException e) { - Log.e(TAG, "Caught an unexpected exception.", e); - resultMessage = R.string.error_generic; - } catch (IOException e) { - Log.e(TAG, "Caught an unexpected exception.", e); - resultMessage = R.string.error_import_unable_to_read_file; - } catch (NullPointerException e) { - Log.e(TAG, "Caught an unexpected exception.", e); - resultMessage = R.string.error_import_invalid_gpx_format; - } catch (OutOfMemoryError e) { - Log.e(TAG, "Caught an unexpected exception.", e); - resultMessage = R.string.error_import_out_of_memory; - } - - boolean success = (importedTrackIds != null && importedTrackIds.length > 0); - showImportResult(success); - } finally { - runOnUiThread(new Runnable() { - public void run() { - dismissDialog(PROGRESS_DIALOG); - } - }); - } - } - }; - t.start(); - } - - private void showImportResult(boolean success) { - final int dialogToShow = success ? SUCCESS_DIALOG : FAILURE_DIALOG; - - // Show a dialog telling the user about the import, and asking if he wishes - // to open the track right away. - runOnUiThread(new Runnable() { - @Override - public void run() { - showDialog(dialogToShow); - } - }); + + String path = data.getPath(); + Log.i(TAG, "Importing GPX file at " + path); + new ImportAllTracks(this, path); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/mymaps/MapsFacade.java b/MyTracks/src/com/google/android/apps/mytracks/io/mymaps/MapsFacade.java index a5b817dc1..722f614c1 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/mymaps/MapsFacade.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/mymaps/MapsFacade.java @@ -3,6 +3,7 @@ package com.google.android.apps.mytracks.io.mymaps; import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.io.AuthManager; +import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.maps.GeoPoint; import com.google.android.maps.mytracks.R; import com.google.wireless.gdata.client.HttpException; @@ -119,7 +120,7 @@ public class MapsFacade { MyMapsMapMetadata metaData = new MyMapsMapMetadata(); metaData.setTitle(title); metaData.setDescription(description + " - " - + category + " - " + context.getString(R.string.send_to_google_by_mytracks)); + + category + " - " + StringUtils.getCreatedByMyTracks(context, false)); metaData.setSearchable(isPublic); Entry entry = MyMapsGDataConverter.getMapEntryForMetadata(metaData); Log.d(MyMapsConstants.TAG, "Title: " + entry.getTitle()); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java index 573e95765..395688c92 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java @@ -429,9 +429,9 @@ public class SendActivity extends Activity implements ProgressIndicator { SendToMyMaps.OnSendCompletedListener onCompletion = new SendToMyMaps.OnSendCompletedListener() { @Override - public void onSendCompleted(String mapId, boolean success, int statusMessage) { + public void onSendCompleted(String mapId, boolean success, String statusMessage) { // TODO: Use this message - sendToMyMapsMessage = getString(statusMessage); + sendToMyMapsMessage = statusMessage; sendToMyMapsSuccess = success; if (sendToMyMapsSuccess) { sendToMyMapsMapId = mapId; @@ -491,10 +491,9 @@ public class SendActivity extends Activity implements ProgressIndicator { OnSendCompletedListener onCompletion = new OnSendCompletedListener() { @Override - public void onSendCompleted(String tableId, boolean success, - int statusMessage) { + public void onSendCompleted(String tableId, boolean success, String statusMessage) { // TODO: Use this message - sendToFusionTablesMessage = getString(statusMessage); + sendToFusionTablesMessage = statusMessage; sendToFusionTablesSuccess = success; if (sendToFusionTablesSuccess) { sendToFusionTablesTableId = tableId; diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendType.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendType.java index 66feccf41..37d382a63 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendType.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendType.java @@ -24,11 +24,11 @@ import com.google.android.maps.mytracks.R; */ public enum SendType { MYMAPS(R.string.sendtogoogle_google_mymaps, - R.string.sendtogoogle_google_mymaps_url), + R.string.send_google_my_maps_url), FUSION_TABLES(R.string.sendtogoogle_google_fusiontables, - R.string.sendtogoogle_google_fusiontables_url), + R.string.send_google_fusion_tables_url), DOCS(R.string.sendtogoogle_google_docs, - R.string.sendtogoogle_google_docs_url); + R.string.send_google_docs_url); private int serviceName; private int serviceUrl; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index c32f88c10..c266cf26b 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -559,6 +559,11 @@ public class TrackRecordingService extends Service { Log.d(TAG, "Location listener now unregistered w/ TrackRecordingService."); } + + private String getDefaultActivityType(Context context) { + SharedPreferences prefs = context.getSharedPreferences(Constants.SETTINGS_NAME, 0); + return prefs.getString(context.getString(R.string.default_category_key), ""); + } /* * Recording lifecycle. @@ -582,6 +587,7 @@ public class TrackRecordingService extends Service { track.setId(recordingTrackId); track.setName(new DefaultTrackNameFactory(this).newTrackName( recordingTrackId, startTime)); + track.setCategory(getDefaultActivityType(this)); isRecording = true; isMoving = true; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java index a1dbaba2f..9e66f8d37 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java @@ -24,6 +24,7 @@ import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.UnitConversions; import com.google.android.maps.mytracks.R; +import com.google.common.annotations.VisibleForTesting; import android.content.Context; import android.content.SharedPreferences; @@ -327,7 +328,8 @@ public class StatusAnnouncerTask implements PeriodicTask { * * @param time the time */ - private String getAnnounceTime(long time) { + @VisibleForTesting + String getAnnounceTime(long time) { int[] parts = StringUtils.getTimeParts(time); String secLabel = context.getString(parts[0] == 1 ? R.string.voice_second : R.string.voice_seconds); @@ -343,6 +345,7 @@ public class StatusAnnouncerTask implements PeriodicTask { sb.append(hourLabel); sb.append(" "); sb.append(parts[1]); + sb.append(" "); sb.append(minLabel); } else { sb.append(parts[1]); @@ -350,6 +353,7 @@ public class StatusAnnouncerTask implements PeriodicTask { sb.append(minLabel); sb.append(" "); sb.append(parts[0]); + sb.append(" "); sb.append(secLabel); } return sb.toString(); diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java index 308905fdc..b86ca9162 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java @@ -303,7 +303,7 @@ public class StringUtils implements DescriptionGenerator { + "", // Line 1 - context.getString(R.string.send_to_google_by_mytracks), + getCreatedByMyTracks(context, true), // Line 2 context.getString(R.string.total_distance_label), @@ -353,6 +353,22 @@ public class StringUtils implements DescriptionGenerator { ChartURLGenerator.getChartUrl(distances, elevations, track, context)); } + /** + * Returns the 'Created by My Tracks on Android' string. + * + * @param context the context + * @param addLink true to add a link to the My Tracks web site + */ + public static String getCreatedByMyTracks(Context context, boolean addLink) { + String format = context.getString(R.string.send_google_by_my_tracks); + if (addLink) { + String url = context.getString(R.string.my_tracks_web_url); + return String.format(format, "", ""); + } else { + return String.format(format, "", ""); + } + } + private String getSpeedString(double speed, int speedLabel, int paceLabel, boolean displaySpeed) { double speedInKph = speed * 3.6; diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java index 16b7af12a..71fe422d1 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java @@ -382,6 +382,8 @@ public class TrackRecordingServiceTest Track track = providerUtils.getTrack(id); assertNotNull(track); assertEquals(id, track.getId()); + assertEquals(sharedPreferences.getString(context.getString(R.string.default_category_key), ""), + track.getCategory()); assertEquals(id, sharedPreferences.getLong( context.getString(R.string.recording_track_key), -1)); assertEquals(id, service.getRecordingTrackId()); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java index 4f7c2e600..48d52bc5b 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java @@ -478,7 +478,59 @@ public class StatusAnnouncerTaskTest extends AndroidTestCase { task.runWithStatistics(null); AndroidMock.verify(mockTask, tts); } + + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with time zero. + */ + public void testGetAnnounceTime_time_zero() { + long time = 0; // 0 seconds + assertEquals("0 minutes 0 seconds", task.getAnnounceTime(time)); + } + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with time one. + */ + public void testGetAnnounceTime_time_one() { + long time = 1 * 1000; // 1 second + assertEquals("0 minutes 1 second", task.getAnnounceTime(time)); + } + + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with singular + * numbers with the hour unit. + */ + public void testGetAnnounceTime_singular_has_hour() { + long time = (1 * 60 * 60 * 1000) + (1 * 60 * 1000) + (1 * 1000); // 1 hour 1 minute 1 second + assertEquals("1 hour 1 minute", task.getAnnounceTime(time)); + } + + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with plural numbers + * with the hour unit. + */ + public void testGetAnnounceTime_plural_has_hour() { + long time = (2 * 60 * 60 * 1000) + (2 * 60 * 1000) + (2 * 1000); // 2 hours 2 minutes 2 seconds + assertEquals("2 hours 2 minutes", task.getAnnounceTime(time)); + } + + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with singular + * numbers without the hour unit. + */ + public void testGetAnnounceTime_singular_no_hour() { + long time = (1 * 60 * 1000) + (1 * 1000); // 1 minute 1 second + assertEquals("1 minute 1 second", task.getAnnounceTime(time)); + } + + /** + * Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with plural numbers + * without the hour unit. + */ + public void testGetAnnounceTime_plural_no_hour() { + long time = (2 * 60 * 1000) + (2 * 1000); // 2 minutes 2 seconds + assertEquals("2 minutes 2 seconds", task.getAnnounceTime(time)); + } + private void startTask(int state) { AndroidMock.resetToNice(tts); AndroidMock.replay(tts);