Aplikacja mobilna realizująca powiadomienia głosowe za ...kopel/mgr/2015.02 mgr Herman.pdf ·...

59
Wydział Informatyki i Zarządzania kierunek studiów: Informatyka specjalność: Teleinformatyka Praca dyplomowa - magisterska Aplikacja mobilna realizująca powiadomienia głosowe za pomocą metod Text-To-Speech Inż. Michał Herman słowa kluczowe: Android, text-to-speech, Powiadomienia android, notyfikacjię Notyfikacje głosowe, przetwarzanie teksu na mowę Niniejsza praca dyplomowa zawiera informacje o metodach pozyskiwania powiadomień w systemie Android oraz przetwarzania danych zawartych w tych powiadomieniach. Druga część pracy opisuje implementację mechanizmów przetwarzania tekstu (powiadomień z części pierwszej) na mowę w systemie Android. Finalnie w pracy przedstawiona została aplikacja, która przekazuje powiadomienia systemu, takie jak wiadomości tekstowe, emaila czy informacje z portali społecznościowych w formie głosowej dla użytkownika opiekun pracy dyplomowej .................................................. ....................... ....................... Tytuł/stopień naukowy/imię i nazwisko ocena podpis Do celów archiwalnych pracę dyplomową zakwalifikowano do:* a) kategorii A (akta wieczyste) b) kategorii BE 50 (po 50 latach podlegające ekspertyzie) * niepotrzebne skreślić pieczątka Instytutu, w którym student wykonywał pracę Wrocław 2015

Transcript of Aplikacja mobilna realizująca powiadomienia głosowe za ...kopel/mgr/2015.02 mgr Herman.pdf ·...

Wydział Informatyki i Zarządzania

kierunek studiów: Informatyka specjalność: Teleinformatyka

Praca dyplomowa - magisterska

Aplikacja mobilna realizująca powiadomienia głosowe

za pomocą metod Text-To-Speech

Inż. Michał Herman

słowa kluczowe:

Android, text-to-speech,

Powiadomienia android, notyfikacjię

Notyfikacje głosowe, przetwarzanie teksu na mowę

Niniejsza praca dyplomowa zawiera informacje o metodach pozyskiwania

powiadomień w systemie Android oraz przetwarzania danych zawartych w tych

powiadomieniach. Druga część pracy opisuje implementację mechanizmów

przetwarzania tekstu (powiadomień z części pierwszej) na mowę w systemie Android.

Finalnie w pracy przedstawiona została aplikacja, która przekazuje powiadomienia

systemu, takie jak wiadomości tekstowe, emaila czy informacje z portali

społecznościowych w formie głosowej dla użytkownika

opiekun pracy

dyplomowej

.................................................. ....................... ....................... Tytuł/stopień naukowy/imię i nazwisko ocena podpis

Do celów archiwalnych pracę dyplomową zakwalifikowano do:*

a) kategorii A (akta wieczyste)

b) kategorii BE 50 (po 50 latach podlegające ekspertyzie) * niepotrzebne skreślić

pieczątka Instytutu, w którym

student wykonywał pracę

Wrocław 2015

2

Spis Treści

Spis Treści .................................................................................................................................. 2

Spis Tabel ................................................................................................................................... 3

Spis Listingów ............................................................................................................................ 3

Spis Ilustracji .............................................................................................................................. 4

1. Wstęp .................................................................................................................................. 6

2. Przegląd dostępnych aplikacji ............................................................................................ 7

2.1. SMS Reader ................................................................................................................. 7

2.2. Notification Avatar ...................................................................................................... 8

2.3. Voice Notify ................................................................................................................. 9

2.4. Notification Reader .................................................................................................... 10

2.5. Speak Me .................................................................................................................... 11

2.6. Zestawienie funkcji istniejących aplikacji ................................................................. 12

3. Powiadomienia w systemie Android ................................................................................ 13

4. Metody przechwytywania powiadomień ......................................................................... 16

4.1. Accessibility Service - usługa ułatwiania dostępu ..................................................... 17

4.2. Notification Listener Service - usługa nasłuchiwana notyfikacji .............................. 19

4.3. Usługa telefonu dla systemu Android ....................................................................... 20

4.4. Podsumowanie i porównanie metod pozyskiwania notyfikacji................................. 21

5. Przetwarzanie obiektów Powiadomień ............................................................................ 21

6. Metody i implementacje silników Text-To-Speech .......................................................... 26

6.1. Text-To-Speech .......................................................................................................... 26

6.2. Budowa systemu Text-to-Speech ............................................................................... 29

7. Synteza mowy w środowisku Android ............................................................................. 31

7.1. Dragon Mobile SDK .................................................................................................. 31

7.2. iSpeech API ................................................................................................................ 35

7.3. Text To Speech API Google ...................................................................................... 37

7.4 Porównanie syntezatorów mowy ............................................................................... 40

8. Aplikacja Notification Catcher. ....................................................................................... 45

8.1. Wymagania funkcjonalne i niefunkcjonalne aplikacji .............................................. 46

8.1.1. Wymagania funkcjonalne ................................................................................... 46

8.1.2. Wymagania niefunkcjonalne .............................................................................. 47

8.2. Model aplikacji .......................................................................................................... 48

8.3. Zastosowane technologie ........................................................................................... 49

8.4. Struktura aplikacji ...................................................................................................... 49

9. Interfejs użytkownika aplikacji ........................................................................................ 53

3

10. Podsumowanie .............................................................................................................. 58

11. Bibliografia .................................................................................................................... 59

Spis Tabel

Tabela 1. Porównanie aplikacji czytających notyfikacje. ........................................................ 13 Tabela 2. Porównanie sposobów pozyskiwania notyfikacji. .................................................... 21 Tabela 3. Lista stałych klasy Notification ważnych przy odczytywaniu powiadomienia ....... 22 Tabela 4. Wyniki testu na syntezatora Dragon Mobile ............................................................ 41 Tabela 5. Wyniki testu dla syntezatora iSpeech. ...................................................................... 42

Tabela 6. Wynik testu dla syntezatora Google. ........................................................................ 43 Tabela 7. Zestawieni wyników testu syntezatorów mowy ....................................................... 44

Tabela 8. Wymagania funkcjonalne aplikacji Notification Catcher. ....................................... 46 Tabela 9. Wymagania niefunkcjonalne aplikacji Notification Catcher. .................................. 47

Spis Listingów

Listing 1. Fragment kodu realizującego wystawienie powiadomienia .................................... 15 Listing 2. Fragment kodu przechwytującego powiadomienia za pomocą Accessibility Service

.................................................................................................................................................. 18 Listing 3. Fragment kodu źródłowego realizującego pobieranie notyfikacji za pomocą

Notification Listener. ............................................................................................................... 20 Listing 4. Implementacja wydobycia obiektu Bundle z obiektu Notification .......................... 23 Listing 5. Pobieranie elementów tekstowych z klasy Bundle. ................................................. 23

Listing 6. Analiza widoku powiadomienia w celu wyodrębnienia tytułu i treści

powiadomienia. ........................................................................................................................ 25 Listing 7. Pobieranie nazwy aplikacji w przypadku użycia metody opartej na

NotifiactionListenerSercice. ..................................................................................................... 26

Listing 8. Pobieranie nazwy aplikacji wystawiającej notyfikacje w przypadku użycia metody

Accessibility Service. ............................................................................................................... 26

Listing 9. Realizacja usługi TTS korzystającej z Dragon Mobile API .................................... 34 Listing 10. Przykład implementacji syntezatora mowy opartego na API iSpeech. ................. 36

Listing 11. Przykładowy kod inicjalizujący Text-To-Speech Google API. ............................. 38

4

Spis Ilustracji

Rys. 1. Interfejs użytkownika aplikacji SMS Reader ................................................................. 7 Rys. 2. Uprawnienia aplikacji SMS Reader. .............................................................................. 8 Rys. 3. Interfejs użytkownika aplikacji Notification Avatar. ..................................................... 9

Rys. 4. Interfejs użytkownika aplikacji Voice Notify .............................................................. 10 Rys. 5. Interfejs użytkownika aplikacji Notification Reader ................................................... 11 Rys. 6. Interfejs użytkownika aplikacji Speak Me. .................................................................. 12 Rys. 7. Notyfikacja w widoku normalnym .............................................................................. 14 Rys. 8. Notyfikacja w widoku dużym ...................................................................................... 14

Rys. 9. Cykl życia notyfikacji .................................................................................................. 15 Rys. 10. Schemat budowy moduły NLP. ................................................................................. 29 Rys. 11. Architektura biblioteki Speech Kit. ........................................................................... 31

Rys. 12. Schemat działania Text-to-Speech Dragon Mobile API ............................................ 32 Rys. 13. Struktura pakietu dragon mobile API. ....................................................................... 33 Rys. 14. Struktura pakietu iSpeech API ................................................................................... 35 Rys. 15. Struktura pakietu Android TTS . ................................................................................ 37 Rys. 16. Schemat działania aplikacji Notification Catcher. ..................................................... 48 Rys. 17. Struktura pakietu aplikacji Notification Catcher........................................................ 50

Rys. 18. Ekran startowy aplikacji przy pierwszym uruchomieniu (po lewej), w trybie

normalnego działania (po prawej). ........................................................................................... 53 Rys. 19. Ekran ustawień aplikacji. ........................................................................................... 54

Rys. 20. Ekran ustawień Ułatwień dostępu z włączonymi uprawnieniami dla aplikacji

Notification Catcher. ................................................................................................................ 55

Rys. 21. Ekran Zabezpieczenia z informacją, że jedna aplikacja ma dostęp do powiadomień.

.................................................................................................................................................. 55

Rys. 22. Ekran Dostępu do powiadomień informujący prawach dostępu aplikacji Notification

Catcher do powiadomień. ......................................................................................................... 56

Rys. 23. Ekran Ustawienia Powiadomień aplikacji Notifiacation Catcher. ............................. 56 Rys. 24. Ekran Historia Powiadomień z notyfikacjami zebranymi przez aplikację. ............... 57

5

Niniejsza praca dyplomowa zawiera informacje o metodach pozyskiwania

powiadomień w systemie Android oraz przetwarzania danych zawartych w tych

powiadomieniach. W pierwszej części scharakteryzowanie zostały metody pozyskiwania

informacji o powiadomieniach z systemu Android. Opisane zostały metody używające usługi

ułatwiania dostępu, telefonii oraz usługi Notification Service. Przedstawiony został również

sposób przetwarzania pobranych informacji z notyfikacji, który umożliwia późniejsze

przeczytanie tych informacji przez lektora.

Druga część pracy opisuje implementację mechanizmów przetwarzania tekstu

(powiadomień z części pierwszej) na mowę w systemie Android. Przedstawione zostały tu

zarówno mechanizmy bazujące na natywnych aplikacjach oraz usługi oparte o platformy

oprogramowanie jako usługa. Mechanizmy przetwarzania dźwięku na mowę zostały

przetestowane i porównane pod kątem czytanie języka polskiego. Finalnie w pracy

przedstawiona została aplikacja, która przekazuje powiadomienia systemu, takie jak

wiadomości tekstowe, emaila czy informacje z portali społecznościowych w formie głosowej

dla użytkownika. Aplikacja ta korzysta z mechanizmów opisanych w niniejszej pracy,

zaimplementowane w niej obsługę kilku mechanizmów pozyskiwania powiadomień oraz

kilka mechanizmów przetwarzania tekstu na mowę.

This thesis contains information about methods of collecting notifications in Android

operating systems. It also contains information about transformation of notification data to

data format which can be handled by different part of applications. First part of this document

tells how to get notification data in Android operating systems using methods based on

Accessibility Service, Notification Listener service and Telephony Service. It also shows how

to transform data from notification to text data which can be read by lector.

Second part of this thesis shows various implementation of Text-To-Speech methods

(which can read information from notification) in Android operation system. It tells about

standalone Android Text-To-Speech solutions and also about solutions based of Software as

Service application model. Text-To-Speech solutions were tested for pronunciation of Polish

language. Finally, thesis presents Android application which can get information about

notifications (emails, incoming calls, short text messages, social portal notifications) and then

read that information using Text-To-Speech methods.

6

1. Wstęp

Przetwarzanie teksu na mowę w ostatnich latach uległo znacznemu rozwojowi.

Jeszcze kilka lat temu syntezatory imitujące ludzką mowę brzmiały sztucznie i mało kto miał

ochotę ich słuchać. Dziś TTS (Text-to-Speech) odnajdziemy w wielu dziedzinach życia:

smartphone’ach, komputerach czy samochodach. Wszystkie te urządzenia mogą

komunikować się z użytkownikiem za pomocą głosu, czy to poprzez reagowanie na

polecenia (rozpoznawanie mowy), czy też pytanie lub oznajmianie użytkownikowi

informacji(przetwarzanie tekstu na mowę). Wszystkie te urządzenia mogą czytać za

użytkownika treści stron internetowych, wiadomości czy książki. Natomiast jakość i

upodobnienie do ludzkiego głosu jest coraz to lepsze, z każdą następną wersją popularnych

silników przetwarzania teksu na mowę.

Na początku należy zaznajomić się z terminami powiadomienie i notyfikacja,

ponieważ pojęcia te będą przetaczały się przez całą pracę. Pierwsze z nich to powiadomienie,

czyli informacja pojawiająca się na pasku aktywności systemu Android w momencie, gdy

wystąpi jakieś zdarzenie. Kolejnym pojęciem jest notyfikacja, czyli zapożyczone z języka

angielskiego słowo, oznaczające to samo co powiadomienie. Oba te terminy będą w niniejszej

pracy używane zamienianie, i będą miały to samo znaczenie.

Celem niniejszej pracy dyplomowej jest analiza rozwiązań przetwarzania

powiadomień wystawianych przez aplikacje systemu Android w kontekście ich przekazania

użytkownikowi za pomocą technologii przetwarzania tekstu na mowę (Text-To-Speech). W

kolejnych rozdziałach zostaną przedstawione sposoby pozyskiwania powiadomień z aplikacji

i systemu operacyjnego w środowisku Android. Przeanalizowane w drugiej kolejności zostaną

metody Text-To-Speech dostępne w środowisku Android oraz sposoby ich użycia. Omówione

zostaną silniki przetwarzania tekstu, dostępne jako natywne programy systemu Android oraz

dostępne rozwiązania, oferowane w modelu oprogramowanie jako usługa (Software as a

Service - SaaS), wymagająca od aplikacji ciągłego połączenia internetowego.

Aby pokazać możliwości powiadomień oraz ich przekazywania użytkownikowi w

sposób nie wymagający odblokowywania ekranu, czy wyjmowania telefonu, przedstawiono

przykład aplikacji, zajmującej się przekazywaniem informacji znajdujących się w

powiadomieniach w sposób głosowy, za pomocą metod przetwarzania dźwięku na mowę.

7

2. Przegląd dostępnych aplikacji

Rynek aplikacji na urządzenia z Androidem jest ogromny. Liczba aplikacji w sklepie

Play sięga 1.3 miliona. Można jednak znaleźć tam niewiele aplikacji, które umożliwiają

czytanie wiadomości tekstowych, przychodzących maili, powiadomień z aplikacji

społecznościach czy komunikatorów. Czytających takie informacje aplikacji można policzyć

na palcach jednej ręki. W kolejnych podrozdziałach przedstawione zostały najpopularniejsze

aplikacje tego typu, dostępne dla systemu Android. Aplikacje testowane i opisane w

poniższym rozdziale, zostały wybrane na podstawie najczęściej pobieranych ze sklepu Google

Play, po podaniu frazy „czytanie powiadomień” (ang. Notification Reader ).

2.1. SMS Reader

SMS Reader jest aplikacją czytającą przychodzące wiadomości tekstowe. Dodatkowo

informuje głosowo o nadchodzącym połączeniu, czytając identyfikator dzwoniącego. W

preferencjach aplikacji można dodać ekranowy widget, umożliwiający włączenie lub

wyłączenie funkcji powiadomień głosowych. Domyślnie, z powodów bezpieczeństwa,

włączona jest opcja czytania jedynie nadawcy połączenia i wiadomości tekstowej. Działanie

aplikacji można zdefiniować korzystając z ustawień [13].

Rys. 1. Interfejs użytkownika aplikacji SMS Reader

SMS Reader oferuje jedynie bardzo podstawowe funkcje w dziedzinie notyfikacji

głosowych. Nie potrafi odczytać nic więcej, oprócz wiadomości tekstowych i identyfikacji

przyszłego rozmówcy. Powodem tak małej funkcjonalności aplikacji jest wykorzystywany

8

przez nią sposób pobierania powiadomień z systemu. SMS Reader korzysta przy

przechwytywaniu notyfikacji z usługi telefonu. Usługa ta nie jest przeznaczona do

przechwytywania powiadomień a do obsługi wiadomości tekstowych, oraz połączeń

telefonicznych. Dlatego też program ma z góry narzucone ograniczenia związane z wybraną

architekturą.

Rys. 2. Uprawnienia aplikacji SMS Reader.

Ponadto warto wspomnieć, iż instalując SMS Reader musimy nadać uprawnienia do

telefonu i wiadomości tekstowych. Jest to potencjalnie niebezpieczne, aplikacja taka może

zbierać informację z tych funkcji telefonu. Jednak w przypadku tej aplikacji nie ma takich

obaw, ponieważ program nie posiada na liście uprawnień dostępu do sieci co uniemożliwia

przesyłanie gromadzonych informacji do twórcy. Należy również wspomnieć, iż aplikacja

korzysta z systemowej implementacji silnika Text-to-Speach. Aby w pełni z niej korzystać

użytkownik musi zainstalować pakiety językowe do standardowej usługi, lub pobrać jeden z

syntezatorów mowy dostępny dla systemu Android oraz go skonfigurować.

2.2. Notification Avatar

W aplikacji Notification Avatar powiadomienia prezentowane są przez animowanego

awatara kobiety. Czyta ona wiadomości tekstowe, emaile oraz inne zdarzenia pojawiające się

w pasku notyfikacji. Aplikacja korzysta z ułatwiania dostępu, którą należy włączyć.

Informację o tym użytkownik dostaje przy pierwszym uruchomieniu programu. Następnie

zostaje przekierowany do ustawień ułatwień dostępu, aby zmienić uprawnienia. Bez tej

operacji, program nie będzie spełniał swojej funkcji. Po nadaniu uprawnień użytkownik może

cieszyć się słuchając powiadomień, a mówiąc dokładniej fragmentów powiadomień,

ponieważ aplikacja ta ma problemy z odczytywaniem całości informacji zawartych w

notyfikacjach [14]. W przypadku najpopularniejszego klienta poczty Gmail, zamiast nadawcy

i choćby tytułu maila, aplikacja przeczyta informację, że notyfikacja pochodzi z aplikacji

Gmail. Użytkownik nie usłyszy żadnych dodatkowych informacji, i aby dowiedzieć się jaka

jest treść wiadomości, zmuszony jest spojrzeć na ekran telefonu. Tu czeka go kolejna

niespodzianka: animowana postać dziewczyny czytającej notyfikację. Pojawia się on w

momencie przechwycenia przez aplikację powiadomienia, i znika dopiero po przeczytaniu

komunikatu. Jest to rozwiązanie nie praktyczne. Ponadto może irytować niektórych

użytkowników. Dobrze, że istnieje możliwość wyłączenia tej opcji w ustawieniach aplikacji.

9

Rys. 3. Interfejs użytkownika aplikacji Notification Avatar.

W ustawieniach znajduje się jeszcze kilka opcji pozwalających dostosować działanie

aplikacji do potrzeb użytkownika. Jest między innymi możliwość czytania notyfikacji tylko

gdy ekran jest wyłączony, czy opcja potrząśnięcia telefonem w celu zatrzymania czytania

notyfikacji. Na szczególną uwagę zasługuje lista uprawnień wymaganych przez aplikację. Jest

ona bardzo długa w porównaniu choćby z SMS Reader. Notification Avatar prócz

wspomnianych wcześniej uprawnień do ułatwień dostępu wymaga między innym dostępu do:

odczytywania stanu i informacji o telefonie, nagrywania dźwięków, odczytywania kontaktów,

wyłączania blokady telefonu, kont na urządzeniu, czy pełnego dostępu do sieci. Jak na

aplikację próbującą czytać powiadomienia to o wiele za dużo. Skoro aplikacja korzysta z

wbudowanego silnika Test-to-Speech i ułatwień dostępu, to te wymienione dwa uprawnienia

powinny w zupełności wystarczyć, aby Notification Avatar mógł pracować. Z punktu

widzenia bezpieczeństwa i dostępu do danych nie jest już tak oczywiste, jak w przypadku

SMS Reader, że oprogramowanie to nie zbierania ani nie przesyła poufnych informacji z

telefonu użytkownika do twórców.

2.3. Voice Notify

Voice Notify jest bardziej rozbudowaną aplikacją głoszącą powiadomienia używając

metod przetwarzania tekstu na mowę (Text-To-Speech). Posiada ona wiele funkcji:

czytanie notyfikacji toast,

widget włączający/wyłączający głosowe notyfikacje,

konfigurowalne wiadomości TTS,

wybór silnika TTS,

ustawienia czytania, gdy ekran czy zestaw słuchawkowy jest włączony/wyłączony,

lub telefon jest w trybie cichym/wibracji,

ustawienia czasu, gdy notyfikacje nie będą czytane,

opcję potrząśnij, aby wyciszyć,

konfigurowalne opóźnienia pomiędzy notyfikacjami,

powtarzanie powiadomień co określony interwał, gdy ekran jest wyłączony,

historie notyfikacji [15].

10

Rys. 4. Interfejs użytkownika aplikacji Voice Notify

Aplikacja ta, jak wynika z powyższych funkcji jest dość rozbudowana. Jednak interfejs

użytkownika nie jest czytelny i zajmuje trochę czasu za czym użytkownik przyzwyczai się do

jego obsługi. Również ta aplikacja do czytania powiadomień używa systemowego silnika

Text-to-Speech, co i w tym przypadku wymaga dodatkowej konfiguracji przez użytkownika.

Liczba funkcji aplikacji niesie to za sobą szereg uprawnień, które użytkownik musi nadać

aplikacji by mogła poprawnie funkcjonować. Voice Notify wymaga między innymi dostępu

do systemu Bluetooth, ustawień audio czy wibracji. Potrzebuje również uprawnień ułatwień

dostępu (Accessibility Service). Nadając programowi dostęp do ułatwień dostępu, może on

gromadzić wszystkie zdarzenia zachodzące w systemie, zaczynając od powiadomień, poprzez

wszystkie kliknięcia użytkownika, a kończąc na przechwytywaniu wpisywanych haseł. Z tego

powodu użytkownik powinien zastanowić się dwa razy czy aplikacja, która wymaga takich

uprawnień jest godna zaufania i pochodzi ze znanego źródła.

2.4. Notification Reader

Notification Reader to aplikacja przeznaczona do czytania powiadomień podczas

korzystania z zestawu słuchawkowego czy to Bluetooth, czy przewodowego. Twórcy

przekonują, iż jest ona idealna, gdy słucha się muzyki na urządzeniu, lub chce się po prostu

dowiedzieć o powiadomieniu, bez wyciągania telefonu z kieszeni i patrzenia na ekran.

Głównymi funkcjami aplikacji są:

wykrywanie przychodzącego połączenia, aby nie odtwarzać powiadomień podczas

rozmowy,

włączanie lub wyłączanie odpowiednich wyjść audio,

komunikacja przez Bluetooth,

czytanie tylko notyfikacji wystawianych przez wybrane aplikacje.

Aby używać tej aplikacji użytkownik musi nadać jest dostęp do notyfikacji w ustawieniach

bezpieczeństwa systemu [16]. Jako jedyna z aplikacji opisanych w tym rozdziale

wykorzystuje usługę dostępu do notyfikacji jak metodę pobierania powiadomień. Przyczyną

zapewne jest wiek aplikacji, który w momencie powstawanie tej pracy wynosi około

miesiąca. Aplikacja poprosi o włączenie tych uprawnień przy pierwszym uruchomieniu. W

11

przypadku, gdy uprawnienia nie zostaną nadane, Notification Reader nie przeczyta żadnego

powiadomienia. Aplikacja wykorzystuje standardową usługę przetwarzania tekstu na mowę

dostępną w systemie Android. Co za tym idzie, wymaga zainstalowania danych językowych,

oraz indywidualnego ich ustawienia w systemie.

Rys. 5. Interfejs użytkownika aplikacji Notification Reader

Twórca w opisie programu podaje, iż aplikacja potrafi czytać informację z różnych

programów zainstalowanych w systemie oraz jak je konfigurować pod dany program. Jednak

w rzeczywistości po zainstalowaniu aplikacji użytkownik ma możliwość słuchania

powiadomień i konfigurowania ich dla losowej liczby aplikacji znajdujących się w systemie.

Domyślnie zawartość czytanych notyfikacji zależy od ustawień pod konkretną aplikację w

ustawieniach Notification Reader. Przykładowo, odtwarzana wiadomość tekstowa będzie

zawierać tylko treść, wiadomość email natomiast informację o nadawcy i temat bez treści.

2.5. Speak Me

Speak Me pozwala telefonowi czytać notyfikacje, ale nie ze wszystkich aplikacji.

Tylko z tych, z których użytkownik chce, aby były przeczytane. Umożliwi ustawienie

długości przerwy pomiędzy powiadomieniami z tej samej aplikacji, tak aby nie przeszkadzały

one użytkownikowi. Aplikacja ta również wymaga dostępu do uprawnień ułatwień dostępu,

czyli jest kolejną w zestawieniu używającą tej metody. Text-to-Speech, z którego korzysta

aplikacja, to również systemowy silnik androida [17]. Tak naprawdę aplikacja poza

wyglądem nie różni prawie wcale od wcześniej scharakteryzowanej aplikacji Voice Notify.

Posiada bardzo podobny zestaw funkcji, i tak jak wcześniejsza aplikacja ma problemy z

przeczytaniem całego powiadomienia. Również i w tym przypadku o przychodzącym emailu

poinformuje użytkownika (jeśli w ogóle to się stanie, gdyż podczas testów nie udało się tej

aplikacji przeczytać wszystkich powiadomień z Gmail) o temacie maila. Nie zostanie

przeczytana informacja o treści ani nadawcy.

12

Rys. 6. Interfejs użytkownika aplikacji Speak Me.

Na uwagę i jedyny plus aplikacji są uprawnienia jakich wymaga do poprawnego

działania. Jako jedyna aplikacja w zestawieniu potrzebuje jedynie dostępu do ułatwień

dostępu oraz wibracji. Wypada więc pod tym względem najlepiej z opisywanych aplikacji.

2.6. Zestawienie funkcji istniejących aplikacji

Wszystkie aplikacje opisane w punktach 2.1-2.5 prócz Notification Reader korzystają

przy przechwytywaniu powiadomień z usługi ułatwień dostępu systemu Android. A tym

samym umożliwiają twórcą dostęp do wszystkiego, co wyświetlane jest na ekranie

smatphone’a oraz wszystkich informacji wprowadzanych przez użytkownika. Z punktu

widzenia bezpieczeństwa nie jest to dobra praktyka, aby aplikacja posiadała taki dostęp do

systemu. Może to zostać wykorzystane przez autora aplikacji do gromadzenia bardzo

poufnych danych o zachowaniu użytkownika. Co gorsza, daje niemalże nieograniczone

możliwości dostępu do wprowadzanych do urządzenia. Z drugiej jednak strony twórcy

systemu operacyjnego Android aż do wersji Jelly Bean (4.2) nie pomyśleli o udostępnieniu

innej metody na dostęp przez aplikacje do powiadomień pochodzących od innych aplikacji.

Dopiero w Jelly Bean programiści dostali do dyspozycji usługę nasłuchującą notyfikacje

(Notification Listener Service). Jedyną aplikacją korzystającą z tej metody dostępną w

momencie powstawania tej pracy jest Notification Reader. Odczytywanie notyfikacji przez

aplikację wykorzystując Notification Listener jest bezpieczniejsze, niż w przypadku usługi

ułatwiania dostępu. Dzieje się tak dlatego, że użytkownik zmuszony jest nadać aplikacji

uprawnienia jedynie do czytania powiadomień z paska notyfikacji i żadnych innych, o ile

aplikacja nie posiada dodatkowych innych funkcji wymagających specyficznych uprawnień.

Użyty w aplikacji mechanizm powiadomień informuje o tym, iż aplikacje korzystające z

niego, powstały jeszcze przed wydaniem Androida w wersji 4.2. Może to powodować

problemy z odczytem notyfikacji na urządzeniach wyposażonych w wersję systemu nowszą

niż Jelly Bean. Powodem tego jest rozbudowany widok powiadomień, który został

wprowadzony wraz z tą wersją systemu. A mianowicie programiści uzyskali większe

13

możliwości konfigurowania treści, i dużo większy wpływ na wygląd wystawianych przez

aplikację powiadomień.

Poniższa tabela zawiera porównanie aplikacji realizujących powiadomienia głosowe

przy użyciu metod przetwarzania tekstu na mowę.

Tabela 1. Porównanie aplikacji czytających notyfikacje.

SMS Reader Notifiaction

Avatar

Voice Notify Notification

Reader

SpeakMe

Metoda

pozyskiwania

powiadomień

Usługa

telefonu dla

systemu

Android

Accessibility

Service

Accessibility

Service

Notifiction

Listener

Accessibility

Service

Historia

powiadomień

- X x - -

Aplikacja TTS Systemowa Systemowa Systemowa Systemowa Systemowa

Rodzaje

czytanych

powiadomień

Wiadomości

tekstowe,

informację o

połączeniach

wszystkie wszystkie Wiadomości

tekstowe,

kalendarz,

system,

wszystkie

Wybór

aplikacji, z

których

powiadomienia

będą czytane

- x x X,

ograniczony

x

Podsumowując, żadna z aplikacji nie potrafi odczytać wszystkich powiadomień

systemu Android, jak również całej treści powiadomienia. Sytuacja ta wygląda lepiej dla

wiadomości tekstowych, z którymi bez problemu radzi sobie każda z aplikacji. Jednak typowe

wiadomości tekstowe nie są już tak popularne jak kilka lat temu. Dziś dużo większym

zainteresowaniem cieszą się komunikatory takie jak Facebook Messanger, Skype, Hangouts.

Z wiadomościami z takich programów aplikacje czytające notyfikacje jednak sobie w pełni

nie radzą. Jeszcze gorzej wypada choćby obsługa poczty, gdzie wypowiedziana przez

program jest tylko nazwa aplikacji nadającej powiadomienia lub sam tytuł, bądź nadawca

wiadomości.

3. Powiadomienia w systemie Android

Wszystkie informacje o zdarzeniach istotne z punktu widzenia użytkownika w

systemie Android przekazywane są za pomocą notyfikacji. Notyfikacje są skróconymi

informacjami o nowej wiadomości sms, emailu, nieodebranym połączeniu czy wiadomości z

komunikatora skocznościowego. Pojawiają się one w tak zwanym pasku stanu systemu

umieszczonym w górnej części ekranu. Wszystkie powiadomienia dla użytkowania są

zunifikowane. Wystawiane zostają zawsze przez ten sam mechanizm. Posiadają własny cykl

życia. Reprezentowane są przez klasę Notification a zarządzane przez klasę

NotificationManger.

W wersji Jelly Bean, notyfikacje zostały zaktualizowane zarówno pod względem

funkcjonalnym, jak i graficznym. Było to najpoważniejsze odświeżenie funkcjonalności od

początku Androida. Od tej pory notyfikacje mogą zawierać akcje, dzięki którym użytkownik

może wykonać czynność bezpośrednio z paska powiadomień. Wygląd stał się bardziej

elastyczny, może być rozszerzany, aby pokazać dodatkowe informacje. Wprowadzona została

również obsługa priorytetów, pomagająca sortować powiadomienia według ważności a

14

następnie wyświetlać je w kolejności od najistotniejszych, tak aby krytyczne informację były

przekazywane użytkownikowi z wyższym priorytetem. Notyfikacje mogą być wyświetlane w

jednym z dwóch styli:

Normal View(widok normalny),

Big view(duży widok).

Widok normalny to standardowy styl notyfikacji znany z starszych wersji Androida. Poniższy

rysunek przedstawia elementy notyfikacji w widoku normalnym. Układ ten zawiera takie

elementu jak:

Rys. 7. Notyfikacja w widoku normalnym

1. Tytuł/nazwę nadawcy powiadomienia.

2. Ikonę aplikacji wystawiającej powiadomienie lub zdjęcie nadawcy.

3. Treść powiadomienia.

4. Ilość podobnych wiadomości.

5. Druga ikonę identyfikującą aplikacje wysyłająca powiadomienia gdy zdjęcie nadawcy

znajduję się w miejscu. (2)

6. Czas wystąpienia notyfikacji.

Duży widok powiadomień dostarcza więcej informacji o zdarzeniu, które wystawiło

notyfikację. Jak łatwo zauważyć (rys. 7) duży widok posiada większość elementów z widoku

podstawowego. Jedyną różnicą jest oznaczona numerem 7 przestrzeń na dodatkowe

informacje. Przestrzeń ta może zawierać zarówno tekst jak i elementy graficzne.

Rys. 8. Notyfikacja w widoku dużym

Jak już wspomniano wcześniej, zaczynając od wersji Jelly Bean, Android wspiera opcjonalne

akcje wyświetlane w dolnej części notyfikacji. Dzięki akcją użytkownik ma możliwość

obsłużenia najczęstszych zadać wprost z powiadomienia bez potrzeby otwierania aplikacji

15

wystawiającej notyfikację. Przyspiesza to interakcję, a w połączeniu z opcją ‘przesuń aby

usunąć’ pomaga użytkownikowi zajmować się zdarzeniami. Notyfikacja może posiadać

maksymalnie trzy takie akcje. Natomiast każda akcją składa się z ikony oraz nazwy.

Przechodząc do tematu tworzenia powiadomień należy rozpocząć od obiektów, które

każda notyfikacja musi posiadać. Są to 3 elementy: mała ikona, tytuł i informacje dodatkowe.

Wszystkie inne obiekty są opcjonalne i ich obecność na ekranie zależy od twórcy aplikacji.

Jest to istotne z punktu widzenia późniejszego pobierania informacji z notyfikacji. Należy

mieć na uwadze, iż nie wszystkie obiekty muszą znajdować się w powiadomieniu i

zabezpieczyć się przed tym podczas zbierania informacji z powiadomienia. Poniższy

fragment kodu przedstawia tworzenie prostej notyfikacji.

Listing 1. Fragment kodu realizującego wystawienie powiadomienia

Z punktu widzenia aplikacji, która ma za zadanie zebranie informacji z notyfikacji ważnym

elementem jest cykl życia takiej notyfikacji. Ilustruje to poniższy rysunek.

Rys. 9. Cykl życia notyfikacji

Notyfikacja rozpoczyna swoje istnienie od stworzenia obiektu NotifictionCompact, który

przechowuje całą treść i wygląd notyfikacji. Gdy już taki obiekt powstanie, zostanie on

Intent intent = new Intent(this, MainActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0); Notification n = new Notification.Builder(this) .setContentTitle("Czytanie powiadomień włączone") .setContentText("Przejdź do aplikacji aby wyłączyć") .setSmallIcon(R.drawable.ic_launcher) .setContentIntent(pIntent) .setAutoCancel(true).build(); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationManager.notify(notificationID, n);

16

przekazany do obiekty klasy NotificationManager, która to zanim wyświetli notyfikację musi

uzyskać dostęp do usługi Notyfikacji czyli NotificationService. Następnie metoda notify()

klasy Notification Manager wysyła notyfikacje na ekran smartphone’a. Wtedy dopiero

użytkownik ma szansę ją zobaczyć. Wystawieniu notyfikacji na ekran może towarzyszyć

odtworzeniu dźwięku lub uruchomienie się wibracji, mających na celu przyciągnięcie uwagi

użytkownika. W przypadku, gdy użytkownik nie usunie notyfikacji do czasu nadejścia

nowego powiadomienia z tej samej aplikacji nastąpi w większości przypadków

zaktualizowanie istniejącej notyfikacji. Tej akcji również mogą towarzyszyć sygnały

odtwarzane przy publikowaniu powiadomienia.

Analizując cykl życia notyfikacji, powiadomienie powinno być pobrane w momencie

pojawienia się informacji o niej na ekranie. W najlepszym przypadku jeszcze przed

odtworzeniem dźwięki lub wibracji, albo tuż po niej z odpowiednim opóźnieniem. Należy też

wziąć po uwagę stan ekranu telefonu w momencie nadejścia wiadomości, ponieważ w tym

momencie użytkownik może zajmować się rozmową, grą lub inną czynnością, która nie

powinna zostać zakłócona odtworzeniem notyfikacji głosowej. W najprostszym przypadku

odtworzenie notyfikacji powinno być włączone gdy ekran jest wyłączony.

4. Metody przechwytywania powiadomień

Pierwszym wyzwaniem, który napotykamy przy tworzeniu aplikacji czytającej

powiadomienia jest sam dostęp aplikacji trzeciej do tych powiadomień. Jak już wspomniano

wcześniej różne aplikacje mogą wysyłać powiadomienia. System Android natomiast musi

zarządzać ich publikacją i usuwaniem. Łatwo można się domyślić, iż dostęp do notyfikacji

powinna mieć tylko aplikacja tworząca ją oraz system operacyjny. Tak też było aż do wersji

4.3 Jelly Bean, w której została wprowadzona usługa Notification Listener Service.

Umożliwia ona zarządzanie dostępem do powiadomień dla aplikacji trzecich. Usługa ta

opisana została w kolejnych rozdziałach pracy. Zanim jednak twórcy androida dodali

zarządzanie notyfikacjami do systemu, dostęp do powiadomień z innej aplikacji niż

macierzysta był trudny, ale nie niemożliwy. Aplikacyjne podglądanie notyfikacji we

wcześniejszych wersjach systemu umożliwia Accessibility Service, czyli usługa ułatwień

dostępu. Jest do usługa zaprojektowana na potrzeby ułatwienia korzystania z telefonu przez

osoby słabowidzące lub słabosłyszące. Dostęp do powiadomień poprzez Accessibility Service

nie jest jednak dostępem bezpośrednim. Korzystając z tej usługi należy wyciągnąć informację

o nadchodzącym powiadomieniu oraz jego treść z innych obiektów systemu. Temat ten

zostanie dogłębnie przeanalizowany w sekcji opisującej przechwytywanie notyfikacji za

pomocą Accessibility Service. Oprócz wyżej wymienionych Notification Service i

Accessibility Service istnieje jeszcze jedna metoda na przechwycenie powiadomień o

nadchodzących zdarzeniach w systemie, a mianowicie usługa telefonu. Jest ona najmniej

pomocna jeśli mamy zamiar gromadzić wszystkie notyfikacji, gdyż dzięki niej jest możliwe

zdobycie jedynie informacji o nadchodzących rozmowach telefonicznych i wiadomościach

tekstowych. Korzystając z usługi telefonu aplikacja może zebrać treść i nadawcę wiadomości

tekstowych, jak również identyfikator rozmówcy. Należy również wspomnieć, iż opisane

metody dostępu do notyfikacji w urządzeniach z Androidem w wersjach wcześniejszych niż

4.3 nie należą do najbezpieczniejszych z punktu widzenia użytkownika końcowego. Jednak

używając aplikacji korzystających z powiadomień należy mieć świadomość jakich uprawnień

ów program żąda od użytkownika.

17

4.1. Accessibility Service - usługa ułatwiania dostępu

Wielu użytkowników ma różne trudności, które zmuszają ich do korzystania z

urządzenia z Androidem w nieco inny sposób. Użytkownicy z fizycznymi, wizualnymi i

wiekowymi ograniczeniami mają trudności z widzeniem całego ekranu czy używaniu ekranu

dotykowego. Użytkownicy z problemami słuchowymi mogą również nie być wstanie odebrać

informacji audio czy powiadomień. Dlatego też system Android dostarcza dodatki i usługi

ułatwiania dostępu, aby pomóc tym użytkownikom operować urządzaniem w prostszy

sposób, włączając w to przetwarzanie tekstu na mowę, nawigację za pomocą gestów czy

rozpoznawanie mowy. Dzięki temu programiści mogą uczynić swoje aplikacje bardziej

dostępnymi. Usługa ułatwiania dostępu (Accessibility Service) umożliwia programiście

również bardzo duże możliwości w przechwytywaniu zdarzeń systemu Android. A

mianowicie, co najważniejsze w kontekście zbierania powiadomień dostęp do zdarzeń

notyfikacji.

Serwisem tym zarządza klasa AccessibilityService. Serwis ten działa w tle i odbiera

wszystkie sygnały z systemu operacyjnego gdy wystąpi zdarzenie AccessibilityEvent.

Wystąpienie AccessibilityEvent oznacza zmianę w interfejsie użytkownika systemu np.

zmianę podświetlenia, kliknięcie przycisku itd.. Oznaczać również może powstanie nowej

notyfikacji.

Aplikacja korzystająca z ułatwień dostępu musi posiadać odpowiednie uprawnienia. A

mianowicie wymaga w manifeście aplikacji uprawnia BIND_ACCESSIBILITY_SERVICE.

Uprawnienie to jest wymagane aby zapewnić aplikacji dostęp do usługi ułatwiania dostępu.

Oprócz uprawnień, aby program posiadał dostęp do odbierania zdarzeń, niezbędne jest

stworzenie serwisu rozszerzającego usługę Accessibility Service. Przykładowa implementacja

takiej usługi przedstawia poniższy fragment kodu.

18

Listing 2. Fragment kodu przechwytującego powiadomienia za pomocą Accessibility Service

Zawiera on niezbędne informacje, które muszą się znaleźć w pliku manifestu. Kolejnym

elementem jest zidentyfikowanie przychodzącej notyfikacji. Przychodzi tu z pomocą flaga

TYPE_NOTIFICATION_STATE_CHANGE, która informuje o tym iż nastąpiło zdarzenie

zmiany stanu notyfikacji, co z tym idzie powiadomienie dla użytkownika w pasku notyfikacji

zostało wystawione lub istniejące powiadomienie zostało aktualizowane o nowe informację.

Należy tutaj jednak wspomnieć iż flaga informująca o zmianie stanu

powiadomienia(TYPE_NOTIFICATION_STATE_CHANGE) nie informuje o tym czy

notyfikacja pojawiła się w pasku notyfikacji, czy też została wywołana przez klasę Toast

wystawiającą powiadomienia dla użytkownika w formie paska informacyjnego pojawiającego

się na tle aplikacji w dolnej części ekranu. Informacja ta jest istotna z tego powodu, iż w

większości przypadków powiadomienia w formie toast wystawiane są w trakcie działania

aplikacji na pierwszym planie i w bezpośredniej interakcji z użytkownikiem. Dlatego też

czytanie takich powiadomień nie niesie ze sobą wartości dodanej dla zwykłego użytkownika

pragnącego aplikacji do czytania notyfikacji. Co więcej, może przynieść odwrotny skutek, a

mianowicie stać się irytującym elementem programu. W związku z czym należy wprowadzić

mechanizm rozróżniania notyfikacji od powiadomienia typu Toast. Najprostszym, a zarazem

najpewniejszym sposobem rozpoznania twórcy klasy wystawiającej powiadomienie jest

wyciagnięciem tej informacji za pomocą metody getClassName klasy AccessibilityEvent.

Każde powiadomienie typu Toast będzie zawierało klasę źródłową com.android.Toast. Aby

upewnić się, że przechwycone zdarzenie zawiera treść powiadomienia, należy wyciągnąć z

obiektu event typu AccessibilityEvent obiekt Parcelable przy użyciu metody getParcelabe

public class ExampleAccessibilityService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { final int eventType = event.getEventType(); if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { if (event.getClassName().toString().contains(Toast.class.getName())) { // zdarzenie przychodzące to powiadomienie Toast } else { Parcelable parcelable = event.getParcelableData(); if (parcelable instanceof Notification) { // zdarzenie zawiera notyfikację } } } } @Override public void onInterrupt() { } @Override public void onServiceConnected() { } }

19

Data() a następnie sprawdzić czy wyłuskany obiekt jest instancją klasy Notification.

Posiadając zidentyfikowany obiekt notyfikacji można wydobyć z niego informację o treści

powiadomienia, nadawcy, czasie wystąpienia itd.. Sposób wyodrębniania informacji z

obiektów notyfikacji zostanie opisany dalszej części pracy w rozdziale Prasowanie

notyfikacji.

Mając na uwadze zagrożenia przed dostępem aplikacji trzeciej do tak wrażliwych

danych jak kliknięcia, czy zmiany interfejsu użytkownika, aby aplikacja mogła w pełni

korzystać ze swoich uprawnień zapisanych w manifeście, do użytkownika należy jeszcze

zadanie dodania uprawień do serwisu aplikacji w ustawieniach systemowych. Aby dodać te

uprawienie należy (w zależności od wersji systemu) przejść do Ustawień. Następnie odnaleźć

dział Ułatwienia dostępu. Wewnątrz tego działu odnaleźć aplikację i włączyć serwis. System

Android w momencie włączania poinformuje użytkownika o uprawnieniach jakie nadaje oraz

potencjalnym ryzyku dostarczania takich informacji dla aplikacji.

Nazwanie opisanej procedury metodą pozyskiwania powiadomień jest trochę na

wyrost, ponieważ jest ona tylko obejściem API notyfikacji, którego w starszych wersjach

Androida po prostu nie ma. Umożliwia, oprócz notyfikacji z paska powiadomień, wydobycie

również informacji przekazywanych do użytkownika przez klasę Toast. Jak już wspominano

wcześniej może być zarówna zaletą, jak i wadą rozwiązania w zależności od implementacji.

Co więcej dzięki Accessibility Service można wydobyć dużo więcej informacji o działaniu

aplikacji w systemie użytkownika, jak i o samym zachowaniu tegoż użytkownika. Tak więc

metoda ta może posłużyć do wyłuskiwania poufnych informacji z telefonu nieświadomego

użytkownika. Dlatego też trzeba mieć na uwadze uprawnienia jakie nadaję się aplikacji.

4.2. Notification Listener Service - usługa nasłuchiwana notyfikacji

Usługa Notification Listener Service została wprowadzona Androidzie 4.3 (API 18).

Serwis ten odbiera sygnały, gdy notyfikacja jest tworzona lub usuwana. Wraz z nową usługą

użytkownik dostaje dodatkową opcje w ustawieniach systemowych. Jest to dostęp do

powiadomień wewnątrz ustawień zabezpieczeń. Każda aplikacja korzystająca z Notification

Listener będzie po zainstalowaniu widoczna na liście uprawnionych do czytania notyfikacji.

Oczywiście domyślnie uprawnienia te nie są ustawiane same przez aplikację, lecz wymagają

ręcznego ustawienia przez użytkownika. Domyślnie nowa aplikacja pojawia się na liście

dostępu do powiadomień z wyłączonymi uprawnieniami. Usługa nasłuchiwania notyfikacji

daje użytkownikowi większy wpływ na dane przekazywane przez system do aplikacji trzeciej

niż ma to miejsce w przypadku usługi Accessibility Service. Jest to niewątpliwie na duży plus

dla usługi dostępu do notyfikacji w porównaniu z ułatwieniami dostępu. Również z powodów

bezpieczeństwa w systemie Android to kolejny krok do przodu. Wprowadzenie tej usługi

umożliwia programistom, bez tworzenia obejść (poprzez Accessibility Service), stworzenie

aplikacji zarządzających powiadomieniami czy przesyłającymi je do innych urządzeń,

systemów itp.. Używając Notification Listener można pracować tylko i wyłącznie z

powiadomieniami pojawiającymi się w pasku notyfikacji. Usługa ta nie dostarcza możliwości

przechwytywania powiadomień typu Toast. Nie trzeba również filtrować zdarzeń

nasłuchiwanych przez serwis ponieważ wszystkie one są notyfikacjami. Sprawia to iż użycie

tej metody jest łatwiejsze niż za pomocą Accessibility Service.

Klasą reprezentującą tą usługę jest NotificationListenerService. Posiada ona dwie

abstrakcyjne metody:

onNotifiactionPosted(),

onNotificationRemoved()

za pomocą których programista jest w stanie przechwycić informację o powstaniu lub

usunięciu notyfikacji. Oprócz tego pozwala również na programowe usunięcie

20

powiadomienia z ekranu telefonu bez angażowania użytkownika. Opcja ta jest niewątpliwie

przydatna w aplikacji czytającej notyfikacje, ponieważ dzięki niej po przeczytaniu treści

powiadomienia może zostać ono usunięte z ekranu, by nie informować użytkownika kolejny

raz o zdarzeniu, które zostało przekazane w sposób głosowy. Przykładową implementację

użycia Notification Listener Servie przedstawia poniższy listing.

Listing 3. Fragment kodu źródłowego realizującego pobieranie notyfikacji za pomocą Notification Listener.

Prosta implementacja Notification Listener musi zawierać jedynie przeciążenie dwóch

podstawowych metod serwisu. Z punktu widzenia aplikacji gromadzącej powiadomienia

najważniejsza jest metoda onNotificationPosted(), która pobiera obiekt StatusBarNotification

zawierający wszystkie informacje wyświetlone w powiadomieniu. Wewnątrz tej metody

należy zaimplementować proces ekstraktownia informacji z notyfikacji. Opisany zostanie on

w rozdziale opisującym prasowanie notyfikacji. Ważnym elementem, niezbędnym do

działania Listenera, jest nadanie odpowiednich uprawnień aplikacji w pliku manifestu. W

przypadku Notifification Listener te uprawnienia to

BIND_NOTIFICATION_LISTENER_SERVICE. Podobnie jak w przypadku wcześniejszej

metody niezbędne i w tym przypadku jest stworzenie odpowiedniej usługi w pliku manifestu.

Rozwiązanie opisane powyżej posiada jednak jedną wadę, a mianowicie dostępne jest

tylko dla systemu Android w wersji API większej lub równej 18, co w przypadku dość sporej

fragmentacji wersji sytemu zmusza twórców aplikacji do implementacji więcej niż jednej

metody pobierania notyfikacji. Z drugiej jednak strony jest to sposób przeznaczony do tego

typu działań, i w porównaniu do Accessibility Service w dużym stopniu przyśpiesza

pobieranie notyfikacji. Jest również rozwiązaniem znacznie bezpieczniejszym od

poprzednika.

4.3. Usługa telefonu dla systemu Android

Ostatnią z metod pozyskiwania informacji o powiadomieniach jest użycie usługi

telefonu systemu Android. Google udostępnia usługę telefonu jako jeden z elementów API,

dzięki niej programista ma możliwość w swojej aplikacji użyć elementów telefonu, takich jak

wysyłanie wiadomości czy wykonywania połączeń. Przy użyciu tej usługi jest również

możliwe przechwytywanie informacji o nadchodzącym połączeniu lub przychodzącej

wiadomości tekstowej. Użycie tego sposobu pozyskiwania notyfikacji ma jednak bardzo duże

ograniczenia, a mianowicie za pomocą tej usługi możliwe jest tylko pobieranie powiadomień

@SuppressLint("NewApi") public class ExampleListener extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { // kod realizujący zadanie gdy notyfikacja zostaje wystawiona do paska // notyfikacji } @Override public void onNotificationRemoved(StatusBarNotification sbn) { // kod realizujący zadanie gdy notyfikacja zniknie z paska notyfikacji } }

21

o wiadomości tekstowej i nadchodzącym połączeniu. Na tle pozostałych dwóch metod, usługa

telefonii wypada dość blado.

Z uwagi na to, iż metoda ta używa funkcji telefonu do gromadzenia informacji,

aplikacja z niej korzystająca musi posiadać dość duże uprawnienia. Z przyczyn

bezpieczeństwa nie jest to optymalne rozwiązanie, ponieważ dzięki takim uprawnieniom

aplikacja może nie tylko odbierać informację o wiadomościach tekstowych, ale również

wysyłać takowe bez wiedzy użytkownika. Jest to kolejny argument za tym, iż metoda ta nie

należy do dobrych.

4.4. Podsumowanie i porównanie metod pozyskiwania notyfikacji

Przedstawione w poprzednich podrozdziałach sposoby pobierania informacji z

powiadomień wymagają porównania. W poniższej tabeli przedstawiono możliwości o raz

ograniczenia poszczególnych sposobów przechwytywania powiadomień w systemie Android.

Tabela 2. Porównanie sposobów pozyskiwania notyfikacji.

Accessibility

Service

Notification

Listener

Service

Telephony Service

Bezpośredni dostęp do powiadomień X - -

Rodzaj powiadomień, które można

odczytać za pomocą metody

Wszystkie Wszystkie Tylko wiadomości

tekstowe i informacje

o połączniu

Czytanie powiadomień typu Toast X - -

Możliwość usunięcia przechwyconego

powiadomienia z pulpitu

X - -

Dostęp do wrażliwych danych

użytkownika

Bardzo duży,

wszystkie

zdarzenia w

systemie

Tylko

powiadomienia

Wszystkie informacje

telefonu

Możliwość wyłączenia dźwięku

przychodzącego powiadomienia

- X -

Wyodrębnienie obiektu Notification z

przechwyconych informacji

X X -

Jak łatwo zauważyć analizując powyższą tabelę, najlepszą metodą okazuje się korzystanie z

Notification Listener Service. Metoda ta posiada najwięcej zalet ze wszystkich

wspomnianych, a przy tym jest najmniej skomplikowana w użyciu. Jako jedyna również

dostarcza możliwość wyłączenia dźwięku oraz usunięcia powiadomienia. Jest to bardzo duży

atut przy użyciu tej metody, gdyż pozwala na lepsze zarządzanie powiadomieniami w

aplikacji.

5. Przetwarzanie obiektów Powiadomień

Opisane we wcześniejszych rozdziałach metody pozyskiwania notyfikacji zwracają w

wyniku najczęściej obiekt Notification. Kolejnym zadaniem, które należy wykonać aby

notyfikacja mogła zostać przeczytana jest wyodrębnienie z tego obiektu informacji jakie

zawierała notyfikacja. Rozwiązanie tego problemu zostanie przedstawione właśnie w tym

rozdziale.

22

Należy zacząć od struktury obiektu Notification. Klasa ta zawiera osiem klas

odpowiedzialnych za akcje, które można wykonać na powiadomieniach oraz za generowanie

wyglądu notyfikacji, oraz interfejs obsługujący rozszerzanie notyfikacji. Oprócz tego kilka

metod oraz dużą ilość flag informujących o tym co jest treścią powiadomienia. Najważniejsze

z punktu widzenia aplikacji do przechwytywania notyfikacji przedstawia poniższa tabela.

Tabela 3. Lista stałych klasy Notification ważnych przy odczytywaniu powiadomienia

Nazwa Flagi Opis

EXTRA_TITLE_BIG Klucz klasy Extras: duży tytuł notyfikacji,

najczęściej nazwa nadawcy lub tytuł

wiadomości

EXTRA_TITLE Klucz klasy Extras: tytuł powiadomienia

ustawiony wcześniej za pomocą

metody setContentTitle(CharSequence).

EXTRA_INFO_TEXT Klucz klasy Extras: krótki kawałek tekstu

ustowiony poprzednio za pomocą

metody setContentInfo(CharSequence).

EXTRA_SUB_TEXT Klucz klasy Extras: trzecia lina tekstu

ustawiono wcześniej za pomocą

metody setSubText(CharSequence).

EXTRA_SUMMARY_TEXT Klucz klasy Extras: dodadkowa linka teskstu

wyświetlana gdy powiadominienie zostaje

rozciągnięta do dużego widoku.

EXTRA_TEXT Klucz klasy Extras: Główny tekst

powiadomienia wystawiony przez

metodę setContentText(CharSequence).

EXTRA_TEXT_LINES Klucz klasy Extras: Dodadkowe linie teskstu

wyświetlane gdy powiadomienie występuje

w rozszerzonej formie (duży widok)

wystawione przez metodę

addLine(CharSequence).

Wymienione w powyższej tabeli flagi klasy Notifiaction będą pomocne do

wyekstrahowania informacji z przechwyconej notyfikacji. Przeszukując obiekt Notification z

uwzględnieniem tych danych będzie możliwe odczytanie informacji zawartych w

powiadomieniu.

Na potrzeby wydobycia informacji z notyfikacji stworzono klasę Extractor. W jej

ciele umieszczono wszystkie niezbędne elementy służące do przetwarzania informacji

zawartych w powiadomieniu. Klasa ta składa się z trzech prywatnych metod, oraz jednej

publicznej loadTexts(Context context,StatusBarNotification sbn, NotificationDAO data), która

w wyniku zwraca obiekt NotificationDAO zawierający informacje przekazywane w

późniejszym etapie do syntezatora mowy. Należy mieć na uwadze iż informacje tekstowe

zawarte w wyświetlanej notyfikacji znajdują się w dwóch głównych obiektach: jest to

wcześniej wspomniany obiekt klasy Notification oraz obiekt klasy Bundle (Klasa Bundle

używana jest do przetrzymywania mapowania z obiektów String na różne typy Parcalable.

Najwcześniej służy do przesyłania danych między aktywnościami w systemie Android).

Należy więc rozpocząć od próby wydobycia z obiektu Notification obiekty klasy Bundle. W

przypadku najnowszej wersji Androida 4.4 Kitkat wystarczy odczytać obiekt extras. Sytuacja

komplikuje się nieco we wcześniejszych wersjach systemu. Należy więc skorzystać z

refleksji. Fragment kodu pokazujący użycie refleksji przedstawiono poniżej.

23

Listing 4. Implementacja wydobycia obiektu Bundle z obiektu Notification

W tym przypadku należy mieć na uwadze, iż sposób ten może generować niespodziewany

wyjątek, dlatego też należy się przed tym zabezpieczyć używając bloku try catch.

Podsumowując metoda getExtras() pobiera obiekt klasy Notification, zwraca obiekt typu

Bundle lub null w przypadku błędu. Dlatego też należy mieć tę własność na uwadze w

korzystaniu z tej metody.

Kolejnym krokiem jest wyekstrahowanie informacji tekstowych z obiektu extras klasy

Bundle. W tym momencie zostają użyte wymienione w tabeli 3 klucze z klasy Notification.

Na podstawie kluczy wyciągane są wartości tekstowe za pomocą metody getcharSequence()

klasy Bundle.

Listing 5. Pobieranie elementów tekstowych z klasy Bundle.

Dla usprawnienia późniejszego czytania, zdecydowano się dodatkowo na usunięcie

nadmiarowych spacji z informacji pod kluczem EXTRA_TEXT. To działanie zostało

wprowadzone z uwagi na to iż syntezator mowy może różnie interpretować spacje w tekście,

przez co wiadomość może nie być dobrze zrozumiała. W tym celu stworzono metodę

removeSpaces(), która usuwa wielokrotne spacje w tekście. Z kolei w tekście pod kluczem

EXTRA_TEXT_LINES zwykle może znajdować długa wiadomość składająca się z kilku

@SuppressLint("NewApi") private Bundle getExtras(Notification notification) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { return notification.extras; } try { Field field = Notification.class.getDeclaredField("extras"); field.setAccessible(true); return (Bundle) field.get(notification); } catch (Exception e) { Log.w(TAG, "Failed to access extras on Jelly Bean."); return null; } }

titleText = extras.getCharSequence(Notification.EXTRA_TITLE_BIG); if ( titleText == null) { titleText = extras.getCharSequence(Notification.EXTRA_TITLE); } infoText = extras.getCharSequence(Notification.EXTRA_INFO_TEXT); subText = extras.getCharSequence(Notification.EXTRA_SUB_TEXT); summaryText = extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT); messageText = Utils.removeSpaces(extras.getCharSequence(Notification.EXTRA_TEXT)); messageTextLarge = Utils.mergeLargeMessage(extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES));

24

odrębnych linii tekstu. Należy więc połączyć wszystkie linie w jeden tekst, czyli jeden obiekt

typu String. W tym celu stworzono metodę mergeLargeMessage(), która skleja pojedyncze

linie w jedną oraz usuwana z tego tekstu wielokrotne spacje. Gdyby na tym zakończyć

wydobywanie tekstu z powiadomienia w większości przypadków, szczególnie w

powiadomieniach ze stale aktualizowanych aplikacji, efektem było by otrzymanie wszystkich

informacji zawartych w notyfikacji. Niestety może się zdarzyć iż przetwarzana notyfikacja

nie zawiera obiektu typu Bundle lub metoda getExtras() zwróciła wyjątek. W takiej sytuacji

gdyby pozostać przy wyciągnięciu elementów z klasy Bundle mogłoby się okazać, iż

notyfikacja nie zostanie przetworzona i przeczytana.

Z uwagi na istniejącą możliwość utraty informacji wykorzystując element Bundle,

zdecydowano się w przypadku braku wyniku przetwarzania go wykonać jeszcze jeden krok,

który umożliwi pobranie informacji w przypadku niepowodzenia pierwszej opcji. W tym celu

wykonano analizę widoku powiadomienia, aby wyodrębnić tytuł i treść wiadomości

notyfikacji. Analizę tą przedstawia poniższy fragment kodu. Czytając go należy mieć na

uwadze, iż wprowadzona pętla while znajduję się tutaj nie z powodu wielokrotnego

przetwarzania notyfikacji, ale aby dostarczyć użyteczniej funkcji break.

25

Listing 6. Analiza widoku powiadomienia w celu wyodrębnienia tytułu i treści powiadomienia.

Wykorzystując dwie metody pobierania informacji z powiadomień osiągnięto większą

skuteczność pobierania tekstu powiadomień.

Kolejną ważna informacją, jaką można uzyskać z powiadomienia jest aplikacja, która

wystawiła powiadomienie. Informacja ta jest istotna choćby z punktu widzenia konfiguracji

aplikacji czytającej powiadomienia aby umożliwić użytkownikowi wybór powiadomień, które

mają być odczytywanie głosowo. W tym przypadku należy rozróżnić z której metody

pobierania powiadomień korzysta aplikacja, ponieważ informację o wystawiającej

while (true) { final Notification n = sbn.getNotification(); final Context contextNotify = context; final RemoteViews rvs = n.bigContentView == null ? n.contentView : n.bigContentView; if (rvs == null) { break; } LayoutInflater inflater = (LayoutInflater) contextNotify.getSystemService(Context.LAYOUT_INFLATER_SERVICE); ViewGroup view = (ViewGroup) inflater.inflate(rvs.getLayoutId(), null); if (view == null) { break; } try { rvs.reapply(contextNotify, view); } catch (Exception e) { break; } ArrayList<TextView> textViews = new RecursiveFinder<>(TextView.class).expand(view); if (textViews.size() == 0) break; TextView title = findTitleTextView(textViews); textViews.remove(title); titleText = title.getText(); if (textViews.size() == 0) break; int length = textViews.size(); CharSequence[] messages = new CharSequence[length]; for (int i = 0; i < length; i++) { messages[i] = textViews.get(i).getText(); } messageText = (String) Utils.mergeLargeMessage(messages); break; }

26

powiadomienie aplikacji będzie pobierało się w nieco inny sposób. I tak w przypadku metody

opartej na NotifiactionListenerService informacja ta znajduje się wewnątrz obiektu klasy

StatusBarNotification i pobiera się ja za pomocą metody getPackageName().

Listing 7. Pobieranie nazwy aplikacji w przypadku użycia metody opartej na NotifiactionListenerSercice.

Z kolei w przypadku korzystania z metody dostępu do powiadomień za pomocą ułatwień

dostępu (Accessibility Service) informację o aplikacji wystawiającej notyfikacje otrzymać

można za pomocą metody getPackageName() klasy AccesibilityEvent.

Listing 8. Pobieranie nazwy aplikacji wystawiającej notyfikacje w przypadku użycia metody Accessibility Service.

Informacje wyodrębnione za pomocą opisanych w powyższym rozdziale sposobów w

kolejnym kroku w łatwy sposób mogą być przekazane do komponentu aplikacji, zajmującego

się przetwarzaniem tekstu na mowę.

6. Metody i implementacje silników Text-To-Speech

6.1. Text-To-Speech

Synteza mowy (speech synthesis) jest działem przetwarzania mowy, polegającym na

mechanicznej zamianie tekstu zapisanego w postaci znakowej, na wypowiedź w postaci

dźwiękowej. Program komputerowy zamieniający tekst na mowę jest określany mianem

syntezatora mowy (speech synthesizer). Celem nowoczesnych projektów jest zapewnienie

takiej jakości syntezy mowy, aby słuchający nie był zdolny do odróżnienia dźwięku mowy

syntezowalnej od naturalnej mowy człowieka. Im bardziej synteza ta jest naturalna i płynna,

tym bardziej jest doskonała.

Moduł przetwarzania tekstu na mowę (Test-to-Speech System) odpowiada za zamianę

translacji z postaci elektronicznej do formy dźwiękowej. Zadaniem tego modułu jest

przeczytanie każdego tekstu w postaci znaków alfanumerycznych. Znacznie prostszym

systemem jest Voice Response System, czyli system, który generuje jedynie słowa, czy też

pojedyncze frazy z jakiejś dziedziny (np. informacje od odjazdach pociągów). Skala

możliwości systemów TTS jest znacznie większa, gdyż generuje pełen zakres słów.

Jak łatwo można się domyślić, nie jest możliwe stworzenie i nagranie wszystkich form

i wszystkich słów dla danego języka. Dlatego też system TTS definiuje się jako system

automatycznego generowania mowy z transkrypcja fonetyczną wraz z modułami

odpowiedzialnymi za prozodie i intonację. Może się wydawać, iż taki system nie jest trudny

do zrealizowani i wyuczenia.

Patrząc na to jednak z drugiej strony, możemy porównać taki system do czynności

czytania. Człowiek z łatwością porusza się w świecie informacji pisanych i czytanie nie

sprawia mu problemu, ale jeśli spojrzymy jak długi czas zajmuje proces zdobywania

@Override public void onNotificationPosted(StatusBarNotification sbn) { //kod został pominięty

notification.setPackageName(sbn.getPackageName()); }

notification.setPackageName((String) event.getPackageName());

27

zdolności czytelniczych i jak trudny jest na początku, dochodzimy do wniosku iż nie jest to

prosty proces.

Należy mieć na uwadze, iż system informatyczny nie nauczy się niczego, o ile nie

zostanie zaprogramowany w odpowiedni sposób. Błędnym jest stwierdzenie, że tak jak

nauczenie czytania – zaprogramowanie tego zagadnienia jest łatwe. Komputer jest tylko

mechanizmem pozbawionym inteligencji, a człowiek musi się zmierzyć z rozwiązaniem

każdego problemu w sposób algorytmiczny. Dlatego liczba dobrze działających i

wykorzystywanych systemów Text-to-Speech jest niewielka. Aby dobrze ocenić jakość i

poprawność wypowiedzi generowanych przez syntezatory mowy, należy wziąć pod uwagę

poniższe aspekty:

Zrozumiałość

Zdania generowane przez syntezator powinny być bez problemów rozumiane przez ludzi

posługujących się danym językiem.

Naturalność

Wydźwięk mowy dobrego programu czytającego powinien być jak najbardziej zbliżony

do dźwięku mowy wypowiadanej naturalnie przez człowieka.

Wymowę liczb

W zależności od programu, syntezator może wymawiać liczby literując je jako cyfry lub

składać liczby na postać mówioną.

Przykład: „1857”

Najgorszy wynik jaki można uzyskać to gdy syntezator przeczyta liczbę jako „jeden

osiem pięć siedem”, dobrym wynikiem jest „jeden tysiąc osiemset pięćdziesiąt siedem”.

Natomiast najlepszym wynikiem będzie „tysiąc osiemset pięćdziesiąt siedem”, czyli z

pominięciem zbędnego w tym przypadku słowa „jeden”.

Wymowę godzin i dat

Dobry syntezator powinien być w stanie rozpoznać w tekście format daty (z kropkami,

myślnikami lub ukośnikami jako separatory) lub godziny (z dwukropkiem jako separator) i

odczytywać go zgodnie z zasadami.

Przykład: „ Spotkanie odbędzie się 15.12.2014 o 15:20”

W najgorszym przypadku syntezator odczyta powyższe zdanie literując kolejne cyfry w

dacie i godzinie. Trochę lepszym będzie rozwiązanie, gdy w czytanym zdaniu lektor

przeczyta liczby oddzielone separatorami „Spotkanie odbędzie się piętnaście dwanaście dwa

tysiące czternaście o piętnaście dwadzieścia”. Najlepszym wynikiem będzie charakteryzował

się program, który przeczyta to zdanie uwzględniając datę i godzinę „Spotkanie odbędzie się

piętnastego grudnia dwa tysiące czternastego roku o godzinie piętnastej dwadzieścia”.

Rozpoznawanie skrótów i skrótowców

28

Kolejnym aspektem, na który należy zwrócić uwagę, jest rozpoznawanie skrótów. Dobry

syntezator mowy polskiej powinien nie mieć problemów z rozwinięciem skrótów: „inż.”,

„tel.”, „płn.”, „jw.”, „np. „, „dr”, „mgr”, „p.n.e.” do postaci „inżynier”, „telefon”, „północ”,

„jak wyżej”, „i tak dalej”, „na przykład”, „doktor”, „magister”, „przed naszą erą”.

Bardzo dobrym wynikiem było by też odczytanie przez program skrótów matematycznych

oraz podstawowych jednostek fizycznych takich jak: „sin”, „cos”, „log”, „kg”, „l”, „km” jako

: „sinus”, „kosinus”, „logarytm”, „kilogram”, „litr”, „kilometr”.

Duże znaczenie ma również sposób odczytywania skrótowców literowych i głoskowych.

Przy natrafieniu na skrótowce dobry syntezator powinien umieć rozpoznać z jakim

skrótowcem ma do czynienia i wypowiedzieć litery osobno w przypadku literowców, lub

łączenie jako suma głosek w przypadku głoskowców.

Przykład: „AGD”, „NBP”

Litery skrótowca powinny być odczytanie osobno: „a-gie-de”, „n-be-pe”

Przykład: „NATO”, „ZUS”

Litery skrótowca powinny być odczytane łącznie „nato”, „zus”

Wymowę wyjątków

W języku polskim istnieje szereg wyrazów, które odbiegają od przyjętych reguł

wymowy. Dobry syntezator mowy w przypadku napotkania takiego wyrazu powinien

odczytać go w poprawny sposób odbiegając od ogólnych zasad dla języka.

Przykład: „tarzan”, „marznąc”

Najlepszym wynikiem przy odczytaniu powyższych słów przez syntezator mowy jest nie

złożenie „r” i „z” w „rz” tylko rozdzielenie tych liter. W gorszym przypadku słowa te mogą

brzmieć bardzo nienaturalnie, lub być niezrozumiałe.

Akcentowanie

Akcent w języku polskim jest stały. Zasadniczo pada na drugą sylabę od końca. Od tej

zasady są jednak pewne wyjątki. W niektórych formach akcentowana jest sylaba trzecia od

końca (np. botanika, logika, informatyka, matematyka, komitet, ryzyko). Poprawnie

stworzony syntezator mowy powinien odpowiednio stosować się do zasad akcentowania

włączając w to wyjątki.

Reakcja na znaki interpunkcyjne

Aby czytane przez syntezatora zdania brzmiały naturalnie, powinien on reagować w

odpowiedni sposób na znaki interpunkcyjne: ‘,’’.’’?’’!’ oraz ich brak (zdania niezakończone

kropką powinno brzmieć inaczej, niż to samo zdanie zakończone kropką).

Mając na uwadze powyższe zasady oraz wiedząc, że język polski jest jednym z

najtrudniejszych języków, można stwierdzić iż dobrej klasy syntezator przetwarzający tekst

na mowę polską jest trudny do stworzenia. Szczegółowe informacje o tym jak syntezatory

mowy radzą sobie z tym językiem zostanie przedstawione w kolejnych podrozdziałach

dotykających zagadnienia Text-to-Speech.

29

6.2. Budowa systemu Text-to-Speech

System Text-to-Speech składa się zasadniczo z dwóch podstawowych elementów:

modułu NLP (Natural Language Processing) – odpowiedzialny za przetwarzanie

języka naturalnego,

modułu DSP (Digital Signal Processing) – element, który przetwarza sygnał cyfrowy.

Schemat funkcjonalny systemu przetwarzania tekstu na mowę przedstawiony jest poniżej. Na

schemacie można wyróżnić dwa odrębne moduły wchodzące z skład systemu Text-to-Speech.

Rys. 10. Schemat budowy moduły NLP.

Celem modułu NLP jest przekształcenie tekstu na zapis fonetyczny, czyli zapis słów,

wypowiedzi, przy użyciu podziału fonetycznego głosek. NLP jest odpowiedzialny również za

wygenerowanie odpowiedniej intonacji i prozodii (Brzmieniowe właściwości mowy

nakładające się na głoskowy, sylabiczny i wyrazowy ciąg wypowiedzi. Należą do nich akcent,

intonacja i iloczas) tekstu. Moduł Natural Language Processing składa się z następujących

elementów:

Pre-pocessor (normalizator tekstu) – dzieli on zdania na wyrazy. Proces podziału

dla języka polskiego jest skomplikowany, z powodu iż występuje w nim duża

30

liczba skrótów. Moduł ten wydziela z tekstu skróty, liczby, idiomy, akronimy i

rozwija je do pełnego tekstu. Po przetworzeniu takie dane są przechowywane w

wewnętrznym module struktur danych.

Analizator morfologiczny – wyznacza części mowy dla każdego ze słów

(rzeczownik, przymiotnik, czasownik). Słowa te są rozbijane na morfemy

(najmniejsza grupa fonemów, która niesie ze sobą określone znaczenie i której nie

można podzielić na mniejsze jednostki znaczeniowe) poprzez zastosowanie

gramatyk regularnych, wykorzystanie słownika, tematu wyrazów, przedrostków i

przyrostków. Zadaniem analizatora morfologicznego jest ustalanie części mowy

połączone z zorganizowaniem znormalizowanych danych z preprocesora.

Analizator kontekstowy – ogranicza znaczenia poszczególnych słów. Ograniczenie

to odbywa się na podstawie zbadania kontekstu słów znajdujących się obok siebie.

Stasuje się tutaj metodę n-gramów, która opisuje syntaktyczne zależności

pomiędzy słowami, na zasadzie badania prawdopodobieństw w skończonych

przejściach automatu. Służą to tego modele Markova lub wielowarstwowe sieci

perceptronowe, jak również metody lokalnych niestochastycznych gramatyk.

Praser syntaktyczno-prozodyczny – jego zadaniem jest utworzenie prozodii i

intonacji dla poszczególnych sekwencji fonemów. Bada on jednocześnie pozostałe

wyrażania, które nie zostały skwalifikowane. Następnie stara się znaleźć podobne

do nich struktury tekstowe, których elementy prozodyczne będą najbardziej

podobne.

Moduł konwersji liter na dźwięk – jest odpowiedzialny za konwersję głosek na

mowę oraz za utworzenie transkrypcji fonetycznej dla istniejących słów.

Generator prozodii – ma za zadanie nadanie wypowiedzi właściwości sygnału

mowy. Można je usłyszeć w postaci zmiany głośności, długości sylab, czy

sposobie intonacji. Cechy te odgrywają bardzo ważną rolę w komunikacji

językowej. Odpowiednie zaakcentowanie sylaby zmienia bowiem znaczenie całej

wypowiedzi. Odpowiedzialny jest za precyzyjne określenie czasu trwania

poszczególnych fenomów oraz intonacji w postaci wygenerowanego sygnału.

Innym słowem można powiedzieć, iż moduł ten zapewnia naturalność głosu

syntezatora mowy.

Moduł NLP realizuje szereg procesów przekształcających tekst oraz kształtujących

wypowiedź wraz z intonacją. Kolejnym etapem jest przekształcenie tych danych na sygnał w

module DSP.

Z procesem artykulacji ludzkiej związana jest praca mięśni twarzy oraz wytwarzanie sygnału

o odpowiedniej częstotliwości. W świecie komputerów za sztuczne wygenerowanie sygnału

na kształt procesu artykulacji ludzkiej odpowiada moduł Digital Signal Processing.

Jego zadaniem jest synteza mowy z danych dostarczonych przez moduł NLP. Można

wyróżnić syntezy mowy oparte na modelach:

Formantowa – model tego syntezatora sprowadza się do zaprojektowania

odpowiednich filtrów cyfrowych generujących dźwięk o charakterystycznych dla

głosek częstotliwościach. Formantowa synteza mowy generuje najgorszą jakość

dźwięku, ponieważ ograniczają go możliwości modelu, który składa się tylko z

filtrów.

Artykulacyjna – oparta jest na generowaniu sygnału mowy za pomocą reguł. Do

modelowania głoski służy około 60 parametrów. Schemat modelu artykulacyjnego

przypomina budowę ludzkiego toru głosowego, przy czym jego odpowiednikiem nie

jest aplikacja a analog elektromagnetyczny. Z tego też powodu synteza ta ma

znaczenie symboliczne i nie jest rozpowszechniana.

31

Konkatenacyjna – jest najbardziej rozpowszechnianą obecnie metoda syntezy mowy, z

uwagi na możliwość generowania bardzo naturalnej i zrozumiałej mowy w prosty

sposób. Generuje ona mowę poprzez sklejanie ze sobą elementów akustycznych

powstałych z naturalnej mowy (fony, sylaby).

Korpusowa – jest to zmodyfikowana postać konkatenacyjnej syntezy mowy.

7. Synteza mowy w środowisku Android

7.1. Dragon Mobile SDK

Dragon Mobile Software Development Kit dostarcza usługi głosowe, dzięki którym

aplikacje mogą korzystać z rozpoznawania mowy i przetwarzania tekstu na mowę. W pracy

tej uwaga zostanie skupiona tylko na funkcjach Text-To-Speech pakietu Dragon Mobile.

Pakiet ten dostarcza obsługę TTS dla wielu języków w co najważniejsze, w tym przypadku

również dla języka Polskiego. Co więcej dla języka polskiego dostępne są dwa damskie głosy

oznaczone jako „Ewa” i „Zosia”. Dragon Mobile działa w oparciu o architekturę klient-

serwer. Pakiet ten można dołączyć do tworzonej aplikacji, i jedyne czego potrzebuje do

poprawnego działania to dostęp do Internetu, który umożliwi klientowi (API) zapytanie

serwera o przetwarzanie tekstu na mowę. Biblioteka dostarcza dostęp do komponentów

przetwarzania mowy dostępnych na serwerach firmy Nounce poprzez asynchroniczną

komunikację.

Biblioteka Speech Kit jest wysoko poziomowym API, które automatycznie zarządza

niskopoziomowym dostępem do usług głosowych.

Rys. 11. Architektura biblioteki Speech Kit.

Na poziomie aplikacyjnym są dwa główne komponenty dostępne dla dewelopera:

Recognizer – służący do przetwarzania mowy na tekst

Vocalizer – służacy do przetwarzania tekstu na mowę. Wewnątrz biblioteki znajdują się

elementy odpowiedzialne za poszczególne procesy takie jak:

Zarządzanie systemem audio, aby umożliwić odtwarzanie mowy.

Komponenty sieciowe, które zarządzają połączeniem z serwerem, zestawiają

połączenie w przypadku nowego żądania czy automatycznie wznawiają połącznie

podczas wystąpienia problemów czasu oczekiwana na odpowiedź lub zerwania

połączenia.

Komponent kodowania, kompresujący i dekompresujący zawartość strumienia audio

aby zredukować ograniczania łącza oraz zmniejszyć opóźnienia.

System po stronie serwera jest odpowiedzialny za najważniejsze funkcje w cyklu

przetwarzania tekstu. Kompletna synteza tekstu wykonywana jest właśnie na serwerze, a

32

wynikiem jej jest strumień audio pobierany przez bibliotekę. Ponadto serwer zarządza

również autentykacją aplikacji wysyłającej żądanie przetwarzania tekstu [9].

Warto zaznaczyć, iż biblioteka, którą dostarcza Nuance składa się z dwóch części,

wysokopoziomowego interfejsu deweloperskiego w formie pakietu klas Java oraz natywne

elementy w postaci bibliotek języka C, z której korzysta interfejs przeznaczony dla twórców

oprogramowania.

Klasa Vocalizer dostarcza interfejs obsługujący proces przetwarzania tekstu na mowę.

Pierwszym krokiem, jaki należy wykonać przed użyciem Text-To-Speech oferowanego przez

Nuance, jest zestawienie połącznie i autentykacja z serwerem producenta. Wykonuje się to za

pomocą metody initilize() klasy SpeechKit. Kolejnym krokiem jest zainicjowanie obiekty

klasy Vovalizer oraz ustawienie języka, z jakim będzie pracować aplikacja. Ostatnim krokiem

jest wywołanie metody speakString(), która zajmie się wysłaniem potrzebnych informacji do

serwera oraz odebraniem sygnału audio, a następnie odtworzy odebrany sygnał.

Rys. 12. Schemat działania Text-to-Speech Dragon Mobile API

Jak łatwo można zauważyć na rysunku przedstawiającym schemat działania silnika Dragon

Mobile, została w nim zaimplementowana obsługa przerwania syntezy dźwięku. W

przypadku użycia metody cancel() klasy SpeechKit działanie po stronie serwera zostanie

zakończone a rezultat zwrócony w formie kodu błędu.

Usługa Text-To-Speech Dragon Mobile, jak wspominano wcześniej, działa na zasadzie

klient-serwer. Wiąże się to z możliwością długiego oczekiwania na odpowiedź zawierającą

sygnał audio w przypadku wolnego połączenia sieciowego w szczególności w przypadku

korzystania z aplikacji w miejscu o słabym zasięgu sieci komórkowej. Jest to jednym z

minusów tego rozwiązania. Kolejnym problemem może być również sytuacja, gdy serwer

realizujący zapytania syntezy mowy jest niedostępny. Dlatego też należy mieć te informacje

na uwadze implementując rozwiązanie oparte o ten syntezator mowy, i odpowiednio

zaprojektować obsługę błędów komunikacyjnych.

33

Rys. 13. Struktura pakietu dragon mobile API.

Aby użyć przetwarzania Text-To-Speech w aplikacji na Androida, należy posłużyć się

wcześniej wspomnianymi klasami SpeechKit ora Vacalizer. Prostą implementacje

wykorzystania biblioteki przedstawia poniższy fragment kodu. Należy zacząć od metody

prepereTTS(), w której ciele znajduje się inicjalizacja usług przetwarzania tekstu. Niezbędne

jest tu wywołanie metody initialize() klasy SpeechKit oraz podanie jej argumentów

połączeniowych, takich jak adres serwera realizującego przetwarzanie danych (

SpeechKitServer), port przez który ma być realizowane połączenie (SpeechKitPort) do

serwera, identyfikator aplikacji (SpeechKitAppId) oraz klucz aplikacji

(SpeechKitApplicationKey), służące do autoryzacji aplikacji korzystającej z serwera TTS.

34

Listing 9. Realizacja usługi TTS korzystającej z Dragon Mobile API

Następnie należy wywołać funkcję connect(), aby połączyć się z serwerem TTS. Kolejnym

etapem jest stworzenie i zainicjowanie obiektu klasy Vocalizer. Na tym etapie również

wybierany jest język w jakim ma odbyć się przetwarzanie tekstu. Ustawiony zostaje przez

wpisanie odpowiedniego kodu danego języka w metodzie createVocalizerWithLanguage().W

przypadku korzystania z języka polskiego jest to kod: pl_PL. Tak przygotowany silnik

przetwarzania gotowy jest do czytania tekstu. Realizuje się to poprzez wykonanie metody

spreakString() klasy Vocalizer z argumentem w postaci tekstu który ma być przetworzony na

mowę. W wyniku wykonania tej metody odtworzony zostanie tekst podany jako argument

metody.

public class DragonMobileTTS{ private Activity activity; private Vocalizer vocalizer; private static SpeechKit speechKit; public DragonMobileTTS(Activity activity){ this.activity=activity; } public void speak(String message){ vocalizer.speakString(message, new Object()); } Vocalizer.Listener vocalizerListener = new Vocalizer.Listener() { @Override public void onSpeakingBegin(Vocalizer vocalizer, String text, Object context) { } @Override public void onSpeakingDone(Vocalizer vocalizer, String text, SpeechError error, Object context) { } }; public void prepereTTS(){ activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); speechKit = SpeechKit.initialize(activity, DragonMobileApiInfo.SpeechKitAppId, DragonMobileApiInfo.SpeechKitServer, DragonMobileApiInfo.SpeechKitPort, DragonMobileApiInfo.SpeechKitSsl, DragonMobileApiInfo.SpeechKitApplicationKey); speechKit.connect(); vocalizer = speechKit.createVocalizerWithLanguage("pl_PL", vocalizerListener, new Handler()); }

35

7.2. iSpeech API

iSpeech jest usługą przetwarzania tekstu na mowę w postaci Software as a Service (w

skrócie SaaS. Jest to jeden z modeli chmury obliczeniowej, polegający na dystrybucji

oprogramowania, w którym aplikacja jest przechowywana i udostępniana przez producenta

użytkownikom przez Internet). Dostęp do niego dla systemu Android dostarcza API

udostępniane przez iSpeech. Komunikacja pomiędzy urządzeniem a platformą iSpeech

odbywa się za pomocą protokołu http, przy użyciu standardowych mechanizmów GET i

POST. W standardowej wersji iSpeech Software Developer Kit pozwala na czytanie tekstu w

27 językach w tym w języku polskim.

Dla systemu Android API tego syntezatora dostarczone jest w formie zewnętrznej

biblioteki, którą programista musi dołączyć do swoje aplikacji. Posiada ono ubogą

dokumentację opisującą bardzo pobieżnie metody znajdujące się w pakiecie. Podobnie jak w

przypadku Dragon Mobile, cała synteza tekstu odbywa się na serwerach Ispeech. W kwestii

aplikacji należy tylko wysłanie odpowiednich instrukcji do serwera wraz z tekstem do syntezy

oraz odebranie informacji w postaci pliku dźwiękowego z wynikiem syntezy, który następnie

może być odtworzony użytkownikowi [11].

Rys. 14. Struktura pakietu iSpeech API

Najważniejsza klasą w pakiecie iSpeech jest SpeechSynthesis,która posiada metody

inicjujące i ustawiające parametry syntezy mowy. Aby uruchomić przetwarzanie tekstu na

mowę za pomocą iSpeech, należy zacząć od stworzenia obiektu klasy SpeechSyntesis.

Następnie należy posłużyć się statyczną metodą getInstance(Context context) zwracającą

instancję klasy SpeechSynthesis. Metoda ta sprawdza poprawność klucza licencyjnego

zapisanego w pliku manifestu aplikacji. W przypadku braku klucza lub jego wygaśnięcia

wynikiem jej jest wyjątek InvalidApiKeyException, który powinien być obsłużony przez

programistę. Wybór języka, w jakim ma odbywać się synteza, należy dokonać za pomocą

wywołania metody setVoiceType(String string), której argumentem jest łańcuch znaków

oznaczający kod danego języka. W przypadku języka polskiego kodem tym jest

36

eurpolishfemale. Kolejnym etapem konfiguracyjnym iSpeech jest wywołanie metody

setSpeechSynthesisEventLisener(SpeechSyntesisEvent event), przyjmującej jako argument

interfejs klasy SpeechSyntesisEvent, którego implementacja zależy od twórcy aplikacji.

Ostatnim krokiem jest wybór wyjścia strumienia audio, na jaki ma zostać skierowana

odpowiedź syntezatora mowy w postaci dźwiękowej. Dokonuje się tego za pomocą metody

setStreamType(int streamType), której parametrem jest jeden z strumieni audio dostępnych w

systemowej klasie AudioManager. Tak zaprogramowany silnik iSpeech gotowy jest do

przetwarzania tekstu. Należy tylko wywołać metodę speak(String text), podając jako

argument tekst, który ma zostać przetworzony. Metoda ta rozpocznie konwersję (otworzy

połączenie z serwerem iSpeech, wyślę zapytanie do serwera, przetworzy odpowiedź) a jej

wynik zostanie odtworzony poprzez wybrany wcześniej strumień wyjściowy. Na poniższym

listingu przedstawiony został opisany sposób korzystania z iSpeech API.

Listing 10. Przykład implementacji syntezatora mowy opartego na API iSpeech.

public class IspeechTTS { private SpeechSynthesis synthesis; private Context context;

public void prepareTTSEngine() { try { synthesis= SpeechSynthesis.getInstance(context); synthesis.setVoiceType("eurpolishfemale"); synthesis.setSpeechSynthesisEvent(new SpeechSynthesisEvent() { public void onPlaySuccessful() { Log.i(TAG, "onPlaySuccessful"); } public void onPlayStopped() { Log.i(TAG, "onPlayStopped"); } public void onPlayFailed(Exception e) { Log.e(TAG, "onPlayFailed"); } public void onPlayStart() { Log.i(TAG, "onPlayStart"); } @Override public void onPlayCanceled() { Log.i(TAG, "onPlayCanceled"); } }); } catch (InvalidApiKeyException e) { Log.e(TAG, "Invalid API key\n" + e.getStackTrace()); Toast.makeText(activity, "ERROR: Invalid API key", Toast.LENGTH_LONG).show(); } synthesis.setStreamType(AudioManager.STREAM_MUSIC); } }

37

7.3. Text To Speech API Google

Począwszy od wersji 1.6 środowiska Android, dostępny stał się silnik odpowiedzialny

za syntezę mowy oraz jego implementacja o nazwie Pico TTS. Dzięki niemu w aplikacjach

możliwe jest przetwarzanie ciągu znaków tekstowych na dźwięk – mowę z akcentem

typowym dla wybranego języka. Technologia przetwarzania tekstu na mowę umożliwia

użytkownikowi korzystanie z urządzenia, bez konieczności spoglądania na ekran. Syntezator

ten przeczyta za użytkownika sms, email ,wiadomości, bądź przypomni o wydarzeniu. Jest to

również niezastąpiona funkcja dla ludzi niedowidzących lub starszych, mających problem z

odczytaniem informacji z ekranu telefonu. Niestety poważnym minusem silnika Pico jest to,

iż nie obsługuje on języka Polskiego. Istnieje możliwość wyboru pomiędzy językami:

angielskim (Wielka Brytania), angielskim(Stany Zjednoczone), niemieckim, hiszpańskim

oraz włoskim. Od wersji 2.2 Androida uzyskaliśmy możliwość korzystania z mechanizmów

innych niż Pico. Uzyskujemy w ten sposób większe możliwości, ponieważ silnik Pico nie

nadaje się do wszystkich zastosowań. Nawet w przypadku posiadania kilku mechanizmów

TTS w urządzeniu znajduje się tylko jedna usługa przetwarzania mowy.

Wśród klas Test-To-Speech API znajdujących się w pakiecie android.speech.tts część

klas odpowiedzialna jest za funkcjonalność systemów syntezy mowy. Istnieje również kilka

klas programistycznych, które zajmują się dostarczaniem informacji o mechanizmach

przetwarzania mowy (Engine, EngineInfo), reakcjach na działanie TTS

(OnUtteranceCopletedListener, UtternaceProgressListener) oraz zarządzaniem obiektami

Text-To-Speech (OnInitListener).

Rys. 15. Struktura pakietu Android TTS .

W przypadku korzystania z dostarczonego przez Google pakietu android.speech.tts

cały mechanizm przetwarzania tekstu na mowę zarządzany jest przez system operacyjny.

Dostarcza również wszystkich metod i implementacji (wraz z plikami głosów) służących do

korzystania z możliwości dostarczanych przez system Android. Każda aplikacja korzystająca

z systemowego TTS musi się do niego podłączyć właśnie poprzez to API. Jednak, aby

wszystko funkcjonowało poprawie w systemie, musi być zainstalowany i ustawiony jak

główny silnik Google Text-To-Speech [12].

Inicjalizacja systemu syntezy mowy polega na utworzeniu instancji klasy

TestToSpeech. Należy przy tym wykorzystać domyślny konstruktor klasy

TextToSpeech(Context context, TextToSpeech.OnInitListener listener), który jak atrybuty

38

przyjmuje tzw. kontekst aplikacji oraz implementację interfejsu OnInitListener. Kontekst,

jest to abstrakcyjna klasa przechowywująca informacje dotyczące środowiska aplikacji. Jest

dostarczana jako natywny element systemu. Służy temu, aby programista w prosty sposób

mógł przechowywać i przekazywać informacje o aplikacji, takie jak zasoby, teksty, grafiki,

uprawnienia itd. Instancją takiego kontekstu w aplikacji jest aktywność. Aby przekazać

informacje o aktywności do innej klasy, należy posłużyć się przekazaniem właśnie kontekstu

a nie całej aktywności. Dlatego w tym przypadku zachodzi konieczność inicjalizacji klasy

TextToSpeech dla każdej aktywności osobno. Tylko w ten sposób zapewnia się przekazanie

odpowiedniego kontekstu dla instancji klasy TextToSpeech.

Listing 11. Przykładowy kod inicjalizujący Text-To-Speech Google API.

OnInitListener jest drugim elementem przekazywanym do konstruktora, specyficznym dla

API TTS. Klasa OnInitListener to interfejs, dlatego też jego implementacja zależy od

programisty. Istnieje tu dowolność w implementacji, jednak należy przestrzegać schematu

inicjalizacji systemu TextToSpeech zaprojektowanego przez twórców. Interfejs OnIniListener

zawiera tylko jedną metodę: onInit(int status), która zawsze musi być zaimplementowana.

Argument jaki przyjmuje to status inicjalizacji systemu TextToSpeech w postaci liczy

całkowitej odpowiadającej konkretnej fladze API. Wyróżnia się dwie flagi:

TextToSpeech.SUCCESS – wartość ta oznacza iż TTS został poprawnie zainicjowany.

TextToSpeech.ERROR – wartość ta oznacza iż wystąpił błąd podczas inicjalizacji.

W przypadku, gdy TTS zostanie poprawnie uruchomiony, wywoływane są dodatkowe

metody, konfigurujące instancje syntezatora mowy. Metoda setLanguage(Locale locale)

ustawia język dla syntezatora mowy, pośrednio określa które pliki głosowe zostaną użyte

podczas syntezy mowy. Efektem jej działania jest zwrócenie wartości w postaci liczby

całkowitej odpowiadającej flagom:

TextToSpeech.LANG_MISSING_DATA – oznacza, że system TTS nie posiada danych

do obsługi ustwionego języka.

TextToSpeech.LANG_NOT_SUPPORTED – oznacza, że system TTS nie obsługuje

ustawionego języka.

TextToSpeech.LANG_AVAILABLE – oznacza, że system TTS obsługuje język danego

kraju określony przez lokalizacje, ale nie dla kraju ani w określonym wariancie.

TextToSpeech.LANG_COUNTRY_AVAILABLE – oznacza, że system TTS obsługuje

język danego kraju określony przez lokalizacje.

TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE,- oznacza, że język określony

jest dokładnie przez lokalizację i wariant.

public void googleTTSInit() { mTts=new TextToSpeech(activity, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if(status != TextToSpeech.ERROR){ Locale locale = new Locale("pl"); mTts.setLanguage(locale); } } }); mTts.speak(message, TextToSpeech.QUEUE_FLUSH, null); }

39

W przypadku otrzymania flag innych niż LANG_MIISING_DATA i

LANG_NOT_SUPPORTED, język zostaje ustawiony i tym samym syntezator jest gotowy do

pracy, czyli przetwarzania otrzymanego tekstu na dźwięk.

Po inicjalizacji, gdy klasa TextToSpeech jest gotowa, korzystanie z systemu syntezy

mowy jest stosunkowo łatwe. Wszystkie metody syntezatora należą do klasy TextToSpeech i

na jej instancji trzeba je wywoływać. Najważniejszą metodą, a zarazem najpopularniejszą jest

metoda speak(String text,int queueMode, HashMap<String, String> params). Wywoływana

jest przez nią synteza mowy. Jako pierwszy argument metoda ta przyjmuje tekst, który będzie

zamieniony na mowę. Drugim parametrem jest liczba całkowita określająca sposób

kolejkowania wypowiedzi przez syntezator. Wartość ta przyjmuje jedną z dwóch flag

określonych w klasie TextToSpeech:

TextToSpeech.QUEUE_ADD – wartość ta spowoduje, iż tekst podany jako pierwszy

argument zostanie dodany do kolejki wypowiedzi syntezatora i zostanie przetworzony

dopiero, gdy zakończona zostanie synteza wszystkich tekstów znajdujących się w

kolejce syntezy przed dodawanym tekstem.

TextToSpeech.QUEUE_FLUSH - wartość ta ustawiona jako argument metody

spowoduje, że kolejka wypowiedzi zostanie opróżniona i tekst zadany jako pierwszy

argument metody zostanie zsyntezowany.

Ostatnim argumentem jest HashMap parametrów syntezatora. HashMap klucz wartość

pozwala na ustawienie zaawansowanych parametrów strumieni dźwięku w klasie

AudioManager.

Do kontroli wypowiedzi klasa TextToSpeech posiada oprócz wspomnianych powyżej

metod kolejkowania metody isSpeaking() i stop(). Pierwsza z nich zwraca wartość prawdę lub

fałsz w zależności czy tekst jest odtwarzany, czy nie. Natomiast metodą stop() można

zatrzymać aktualną syntezę mowy.

API TextToSpeech posiada również metody związane bezpośrednio z procesami

generowania wypowiedzi, służące do modyfikowania ustawień mechanizmu TTS oraz

pobierania informacji na temat tych mechanizmów, znajdujących się aktualnie w systemie

Android. Przykładem takich metod są metody:

setSpeechRate(float SpeechRate) – służy do określania szybkości wypowiedzi. Jako

argument przyjmuje liczbę typu float, im jest ona wyższa tym szybkość wypowiedzi

jest większa.

setPitch(float pitch) – określa wysokość tonu syntezatora. Jako parametr również

przyjmuje liczbę float, im większa jest ta liczba tym ton wypowiedzi jest wyższy.

Istotnym elementem API jest możliwość wybrania innego niż Google syntezatora mowy

zainstalowanego w systemie jako silnika mówiącego wprost z API. Należy jednak przed

wybraniem pakietu upewnić się, że jest on zainstalowany w systemie i obsługuje wybrany

przez programistę język. W tym celu przydatne są metody pobierające informacje o

dostępnych języka i sprawdzające ich dostępność:

getDefaultEngine() – zwraca informacje o domyślnym silniku TTS ustawionym w

systemie Android.

getLanguage() – zwraca informacje na temat domyślnego języka używanego przez

system syntezy mowy.

isLanguageAvailable(Locale loc) – sprawdza, czy podany jako argument język jest

dostępny na urządzaniu.

getEngines() – zwraca, w formie listy, informację o wszystkich mechanizmach TTS

zainstalowanych w systemie.

Podsumowując, systemowe API TextToSpeech charakteryzuje się największymi

możliwościami z pośród przedstawionych w tym rozdziale. Jedynym minusem jaki napotkano

40

był brak obsługi języka polskiego przez domyślny silnik. Można jednak zaniedbać ten

mankament, poprzez doinstalowanie jednego z dostępnych silników języka polskiego

współpracującego z tymże API. Choćby bardzo popularny silnik IVONA. Jednak w trakcie

tworzenia pracy Google wydało implementację silnika przetwarzania tekstu na mowę dla

języka polskiego, tym samym jedyny minus zniknął. Natomiast implementacja Google

przyniosła z sobą nową jakość przetwarzania tekstu na mowę, co zostanie przedstawione przy

okazji porównania syntezatorów mowy.

7.4 Porównanie syntezatorów mowy

Każdy z opisanych we wcześniejszych rozdziałach syntezator mowy posiada zalety i

wady z punktu widzenia implementacyjnego. Opisane zostały one przy charakterystyce

każdego z nich. Należy jednak spojrzeć również na syntezatory mowy z punktu widzenia

użytkownika końcowego, ponieważ to dla jego wygody tworzona jest aplikacja korzystająca z

tychże silników przetwarzania tekstu. Dla użytkownika najważniejsze jest zrozumienie tekstu

generowanego przez taki syntezator. Ważnym aspektem jest również forma, w jakiej

specjalne informacje są przekazywane.

Cechy, jakimi powinien charakteryzować się dobry syntezator tekstu zostały

szczegółowo omówione w rozdziale ‘Text-to-Speech’. Na podstawie tych informacji

przeprowadzono porównanie trzech syntezatorów mowy, opisywanych w tej pracy

dyplomowej. Porównanie zostało dokonane dla sześciu rodzajów grup znaków, jakie mogą

znaleźć się w tekście przetwarzanym przez silnik Text-To-Speech. A mianowicie stworzono

testy na podstawie poniższych kryteriów :

wymowa liczb,

wymowa godzin i dat,

wymowa skrótów i skrótowców,

wymowa wyjątków,

reagowanie na znaki interpunkcyjne,

wymowa znaków specjalnych.

Dla każdego z kryteriów stworzono po kilka testów, mających na celu sprawdzenie jak dany

syntezator mowy poradzi sobie z syntezą tekstu specjalnego. Wyniki testów zostały

przedstawione w formie tabel z rezultatami każdego testu dla poszczególnych syntezatorów

mowy. Następnie wyniki z poszczególnych syntezatorów porównano ze sobą w tabeli, aby

wyłonić najlepszy z syntezatorów które zostały przetestowane.

41

Tabela 4. Wyniki testu na syntezatora Dragon Mobile

Test Wynik testu Pkt. Suma Wynik

Wymowa Liczb 1857

„tysiąc osiemset pięćdziesiąt siedem”

1

4 0,6 123 „sto dwadzieścia trzy” 1

2,82 „dwa i osiemdziesiąt dwie setne”

1

2.8 „dwa i osiem dziesiątych” 1

Wymowa godzin i dat Spotkanie

odbędzie się 15.12.2014 o

15:20.

„Spotkanie odbędzie się piętnasty dwunasty dwa tysiące czternaście o godzinie piętnastej dwadzieścia”

3

6 1,2

Dnia 15-12-2014 o 15:30.

„Dnia piętnaście do dwanaście minus dwa tysiące czternaście o godzinie piętnastej trzydzieści”

3

Rozpoznawanie skrótów i skrótowców

tel. „telefon” 1

8,5 1,7

płn. 0

np. „en-pe” 0

dr „de-er” 0

mgr „em-gie-er” 0

AGD „a-gie-de” 1

NBP „en-be-pe” 1

NATO „nato” 1

ZUS „zus” 1

cos [cos 20®] „cos dwadzieścia stopni” 0,5

log 5 „log pięć” 0

km [5 km do centrum]

„pięć kilometrów do centrum” 1

kg [3 kg sera] „trzy kilogramy sera” 1

l [2l mleka] „dwa litry mleka” 1

wymowa wyjątków tarzan „tarzan” 1 2 0,6

marznąć „marznąć” 1

znaki interpunkcyjne Idź do domu „Idź do domu” 0 0 0

Idź do domu! „Idź do domu” 0

Idziesz do domu? „idziesz do domu” 0

Idziesz do domu? „idziesz do domu” 0

znaki specjalne @ „małpa” 1 2 0,1

$ „dolar” 1

%[25%] „25 procent” 1

Suma: 4,2

42

Tabela 5. Wyniki testu dla syntezatora iSpeech.

Test Wynik testu Pkt. Suma Wynik

Wymowa Liczb 1857

„tysiąc osiemset pięćdziesiąt siedem”

1

4 0,6 123 „sto dwadzieścia trzy” 1

2,82 „dwa i osiemdziesiąt dwie setne”

1

2.8 „dwa i osiem dziesiątych” 1

Wymowa godzin i dat Spotkanie odbędzie się 15.12.2014 o

15:20.

„Spotkanie odbędzie się piętnasty grudnia dwa tysiące czternastego roku o piętnastej dwadzieścia”

5

10 2

Dnia 15-12-2014 o 15:30.

„Dnia piętnasty grudnia dwa tysiące czternastego roku o piętnastej trzydzieści”

5

Rozpoznawanie skrótów i skrótowców

tel. „tel” 0

7 1,4

płn. „pe-eł-en” 0

np. „en-pe” 0

dr „de-er” 0

mgr „em-gie-er” 0

AGD „a-gie-de” 1

NBP „en-be-pe” 1

NATO „nato” 1

ZUS „zus” 1

cos [cos 20®] „cos dwadzieścia” 0

log 5 „Log pięć” 0

km [5 km do centrum]

„pięć kilometrów od „centrum

1

kg [3 kg sera] „trzy kilogramy sera” 1

l [2l mleka] „dwa litry mleka” 1

wymowa wyjątków tarzan „tażan” 0 0 0

marznąć „mażnąć” 0

znaki interpunkcyjne Idź do domu „Idź do domu” 0

0 0 Idź do domu! „Idź do domu” 0

Idziesz do domu? „idziesz do domu” 0

Idziesz do domu? „idziesz do domu” 0

znaki specjalne @

„małpa” [tylko w adresie email]

0,5

0 0 $ „dollar” 0

%[25%] „dwadzieścia pięć” 0

Suma: 4

43

Tabela 6. Wynik testu dla syntezatora Google.

Test Wynik testu Pkt. Suma Wynik

Wymowa Liczb 1857

„tysiąc osiemset pięćdziesiąt siedem”

1

4 0,6 123 „sto dwadzieścia trzy” 1

2,82 „dwa i osiemdziesiąt dwie setne”

1

2.8 „dwa i osiem dziesiątych” 1

Wymowa godzin i dat Spotkanie odbędzie się 15.12.2014 o

15:20.

„Spotkanie odbędzie się „piętnasty grudnia dwa tysiące czternastego roku o piętnastej dwadzieścia

5

10 2

Dnia 15-12-2014 o 15:30.

„Dnia piętnasty grudnia dwa tysiące czternastego roku o piętnastej trzydzieści”

5

Rozpoznawanie skrótów i skrótowców

tel. „telefon” 1

8,5 1,7

płn. „pe-eł-en” 0

np. „en-pe” 0

dr „de-er” 0

mgr „em-gie-er” 0

AGD „a-gie-de” 1

NBP „en-be-pe” 1

NATO „nato” 1

ZUS „zus” 1

cos [cos 20®] „cos dwadzieścia stopni” 0,5

log 5 „log pięć” 0

km [5 km do centrum]

„pięć kilometrów od „centrum

1

kg [3 kg sera] „trzy kilogramy sera” 1

l [2l mleka] ”dwa litry mleka” 1

wymowa wyjątków tarzan „tarzan” 1 2 0,6

marznąć „marznąć” 1

znaki interpunkcyjne Idź do domu „Idź do domu” 0

0 0 Idź do domu! „Idź do domu” 0

Idziesz do domu? „idziesz do domu” 0

Idziesz do domu? „idziesz do domu” 0

znaki specjalne @ „małpa” 1

2 0,1 $ „dolar” 1

%[25%] „25 procent” 1

Suma: 5

Tabela 7. Zestawieni wyników testu syntezatorów mowy

Dragon Mobile iSpeech Google

Test Pkt. Suma Suma*Waga Pkt. Suma Suma*Waga Pkt. Suma Suma*Waga Waga

Wymowa Liczb

1857 1

4 0,6

1

4 0,6

1

4 0,6 0,15 123 1 1 1

2,82 1 1 1

2.8 1 1 1

Wymowa godzin i dat Spotkanie odbędzie się 15.12.2014 o 15:20 3

6 1,2 5

10 2 5

10 2 0,2 Dnia 15-12-2014 o 15:30 3 5 5

Rozpoznawanie skrótów i skrótowców

tel. 1

8,5 1,7

0

7 1,4

1

8,5 1,7 0,2

płn. 0 0 0

np. 0 0 0

dr 0 0 0

mgr 0 0 0

AGD 1 1 1

NBP 1 1 1

NATO 1 1 1

ZUS 1 1 1

cos [cos 20*] 0,5 0 0,5

log 5 0 0 0

km [5 km do centrum] 1 1 1

kg [3 kg sera] 1 1 1

l [2l mleka] 1 1 1

wymowa wyjątków tarzan 1

2 0,6 0

0 0 1

2 0,6 0,3 marznąć 1 0 1

znaki specjalne

@ 1

2 0,1

0,5

0 0

1

2 0,1 0,05 $ 1 0 1

%[25%] 1 0 1

SUMA 23,5

4,2

21 4

26,5 5 1

Podsumowując przeprowadzone testy, wszystkie syntezatory najlepiej poradziły sobie z

wymową liczb a najgorzej w rozpoznawaniu znaków interpunkcyjnych. Wszystkie

syntezatory prawidłowo wymówiły cztery liczby testowe, uwzględniając pominięcie słowa

„jeden” w przypadku liczb zaczynających się o cyfry „1”. W przypadku wymowy godzin i dat

najlepsze rezultaty osiągnęły syntezatory iSpeech i Google. Oba silniki poprawnie przeczytały

datę i godzinę, do osiągnięcia maksymalnego wyniku zabrakło jednak użycia wyrażenia „o

godzinie” przed wymówieniem czasu. Gorzej poradził sobie Dragon Mobile, czytane przez

niego daty nie było zrozumiałe, a nawet pomylone z wyrażeniami matematycznymi. W

kategorii rozpoznawania skrótów i skrótowców syntezatory poradziły sobie dobrze z

skrótami miar i wag. Natomiast zupełnie nie były w stanie rozpoznać popularnych w języku

polskim skrótów. Syntezatory Dragon Mobile i Google osiągnęły w tej kategorii pierwsze

miejsce, ustępujący im iSpeech nie podołał tylko z rozwinięciem skrótu „tel.” Wymowa

wyjątków również okazała się dla iSpeech za trudna i w tej kategorii nie zdobył żadnego

punktu. Pozostałe silniki poradziły sobie z tym zadaniem w stu procentach. Podobne rezultaty

syntezatory osiągnęły w przypadku konwersji znaków specjalnych, tu znów iSpeech nie

rozwinął znaków specjalnych w słowa.

Na podstawie sumy punktów najlepszy okazał się syntezator Google osiągając 5

punktów na 7 możliwych. Za nim uplasowały się kolejno Dragon Mobile z 4,2 punktu oraz

iSpeech z 4 punktami. Różnica pomiędzy pierwszym a kolejnymi miejscami jest znacząca i

widać tu przewagę syntezatora Google nad innymi rozwiązaniami. Należy również mieć na

uwadze, iż przetwarzanie tekstu przez wbudowany syntezator Androida jest znacznie

łatwiejsze przy tworzeniu aplikacji, jak również dużo tańsze, gdyż jako jedyne dostępne jest

za darmo dla użytkowników Androida oraz dla programistów tworzących aplikację.

8. Aplikacja Notification Catcher.

Na podstawie przedstawionych we wcześniejszych rozdziałach rozważań dotyczących

powiadomień systemu Android oraz metod przetwarzania tekstu na mowę w tymże systemie,

zaproponowano autorską aplikację Notification Catcher, realizującą powiadomienia głosowe

dla użytkownika. W aplikacji zastosowano opisane w rozdziale o sposobach pobierania

powiadomień metody, by dostarczyć odbiorcy możliwość samodzielnego wypróbowania

każdej z nich oraz wybrania właściwej dla danego użytkownika. Zaimplementowano metody

przechwytywania notyfikacji za pomocą Notification Listener, usługi ułatwiania dostępu oraz

usługi telefonii wraz z usługą wiadomości tekstowych. Oczywiście warto mieć na uwadze

zalety i wady każdego z rozwiązań, dlatego też domyślnym sposobem pozyskiwania

powiadomień w aplikacji został moduł oparty o Notification Listener. Został on wybrany jak

podstawowy z uwagi na to, iż jest to sposób najbardziej bezpieczny z punktu widzenia

użytkownika a zarazem dostarcza największej liczy możliwości oraz jako jedyny umożliwia

odczytywanie usuwanie odczytanych powiadomień z paska stanu systemu Android. W

przypadku silników Text-To-Speech postąpiono podobnie jak w przypadku metod

przechwytywania notyfikacji. A mianowicie zaimplementowano trzy silniki przetwarzające

tekst na mowę (wszystkie opisane w rozdziale dotyczącym przetwarzania tekstu na mowę):

Google Text-To-Speech, Dragon Mobile oraz iSpeech. Umożliwi to użytkownikowi

dostosowanie lektora do własnych potrzeb. Z uwagi na to, iż został użyty w aplikacji

domyślny silnik Google, użytkownik ma również możliwość zainstalowanie dowolnie

wybranego mechanizmu współpracującego z systemem Android. Taki mechanizm jest

wspierany przez aplikację, co daje duże możliwości konfiguracyjne.

46

8.1. Wymagania funkcjonalne i niefunkcjonalne aplikacji

8.1.1. Wymagania funkcjonalne

Poniższa tabela zawiera opis najważniejszych wymagań funkcjonalnych aplikacji

Notifiaction Catcher:

Tabela 8. Wymagania funkcjonalne aplikacji Notification Catcher.

Lp. Nazwa wymagania

1 Użytkownik będzie mógł przeglądać historię notyfikacji z podziałem na przeczytane

przez system i nie przeczytane oraz oznaczone jako usunięte.

2 Użytkownik będzie mógł włączyć/wyłączyć czytanie notyfikacji w dowolnej chwili.

3 System po włączeniu będzie czytał notyfikacje pojawiąjące się w pasku stanu.

4 Użytkownik będzie mógł ustalić notyfikacje których aplikacji mają być odczytywane

przez system.

5 Użytkownik będzie mógł ustalić czy powiadomienia mają być usuwane z paska stanu

systemu Android po przeczytaniu ich przez system.

6 Użytkownik będzie miał możliwość wybrania jednego z mechanizmów pozyskiwania

powiadomień (usługa ułatwiania dostępu, usługa telefonii, Notification Listner )

7 Użytkownik będzie miał możliwość wybrania systemu syntezy mowy.

8 System będzie informował użytkownika o stanie aktywności poprzez informację na

pasku stanu systemu Android.

9 Użytkownik będzie mógł określić czy powiadomienia mają być czytane na głos gdy

telefon jest ustawiony w stanie cichym.

10 Aplikacja będzie posiadała ikonę wskazującym w jakim stanie aktualnie się znajduje

włączone/wyłączone czytanie notyfikacji.

47

8.1.2. Wymagania niefunkcjonalne

Poniższa tabela zawiera opis najważniejszych wymagań niefunkcjonalnych aplikacji

Notifiaction Catcher:

Tabela 9. Wymagania niefunkcjonalne aplikacji Notification Catcher.

Lp. Nazwa wymagania

1 Aplikacja zostanie napisana przy użyciu Android Software Development Kit.

2 Ustawienia aplikacji będą korzystać z menadżera ustawień aplikacji systemu Android.

3 Bazą danych użytą w aplikacji będzie SQLite.

4 Wszystkie dane o powiadomieniach będą trzymana w wewnętrznej bazie danych.

5 Żadne dane o powiadomieniach nie będą dostępne na zewnątrz systemu.

6 Syntezatory mowy będą mogły używać połącznia z Internetem w celu wymiany

informacji niezbędnych do przetworzenia teksu na mowę.

7 Opłaty na Internet będą naliczane zgodnie z taryfą operatora i nie wchodzą w dziedzinę

aplikacji.

8 Aplikacja będzie wymagała od użytkownika nadania uprawnień do notyfikacji w

zależności od ustawień

Aplikacja będzie wymagała od użytkownika nadania uprawnień do usług ułatwiania

dostępu w zależności od ustawień.

48

8.2. Model aplikacji

Poniższy schemat przedstawia ogólne działanie aplikacji.

Rys. 16. Schemat działania aplikacji Notification Catcher.

Jak łatwo zauważyć menu aplikacji składa się z trzech podmodułów: Ustawień, Ustawień

Powiadomień i Historii Powiadomień. Każdy z tych modułów posiada swoją aktywność

obsługującą widok oraz interakcje użytkownika. Ekran ‘Ustawiania’ pozwala dostosować

działanie aplikacji do preferencji użytkownika. Ustawienia te gromadzone są i zarządzanie

przez systemowy moduł ustawień aplikacji. Z kolei ekran ‘Ustawienia Powiadomień’ pozwala

określić, które powiadomienia mają być czytanie przez aplikację. Informacje te

przechowywane są w bazie danych aplikacji a następnie na ich podstawie silnik powiadomień

określa czy aktualna notyfikacja ma zostać przeczytana, czy też może być pominięta. Na

ekranie ‘Historia Powiadomień’ użytkownik może sprawdzić jakie powiadomienia

wystawione zostały przez aplikacje, zarządzać nimi jak również uruchamiać aplikacje

bezpośrednio z powiadomienia.

Gdy system Android wystawi notyfikację, jeden wybrany mechanizm gromadzenia

powiadomień przechwytuje ją. Następnie zostaje ona przekazana do silnika powiadomień,

gdzie następuje wyekstrahowanie pożądanych informacji o notyfikacji oraz sprawdzenie z

49

ustawieniami użytkownika czy dana notyfikacja ma zostać odczytana. Na tym etapie również

informacje zawarte w powiadomieniu zostają zapisywanie w bazie danych oraz w zależności

od ustawień notyfikacja jest usuwana z paska aktywności.. Jeśli notyfikacja ma zostać

przeczytana, informacja o tym przekazywanie są do silnika Text-To-Speech, który zamienia

za pomocą wybranego w ustawieniach syntezatora tekst powiadomienia na głos, który

odtwarzany jest przez urządzenie. Cały ten proces dzieje się w tle aplikacji i nie potrzebuje do

żadnego inicjatora ze strony użytkownika. Efektem końcowym dla użytkownika jest tekst

powiadomienia, podany w sposób głosowy, na aktualnie wybrany interfejs wyjściowy audio:

głośnik urządzenia, słuchawki czy zestaw głośnomówiący.

8.3. Zastosowane technologie

Aplikacja został stworzona na platformę Android. Wersją docelową systemu był

Android 4.4.2 KitKat, który w momencie tworzenia aplikacji był najnowszą odsłoną systemu.

Należy tutaj mieć na uwadze iż jedna z funkcjonalności pozyskiwania powiadomień, a

mianowicie metod oparta na Notification Listener nie będzie funkcjonować na urządzeniach

wyposażonych w system Android w wersji niższej niż 4.2 Jelly Bean (informację ta zawarta

jest również w menu ustawień aplikacji). Językiem programistycznym, w którym stworzono

aplikację jest Java. Użyto w tym przypadku dedykowanego SDK (Software Development Kit)

dla systemu Android. Bazę danych aplikacji oparto na domyślnym rozwiązaniu system

android SQLite. Zdecydowano się na to rozwiązanie dlatego że baza danych aplikacji nie

wymagała zaawansowanych rozwiązań i użycie SQLite było wystarczające.

8.4. Struktura aplikacji

Poniższy rysunek przedstawia strukturę pakietową aplikacji Notification Catcher.

Aplikacja składa się z kilkudziesięciu klas oraz zawiera w sobie dwa pakiety dodatkowe

odpowiadające za implementację syntezatorów mowy iSpeech (org.ispeech) oraz Dragon

Mobile (com.nuance.nmdp.speechkit).

50

Rys. 17. Struktura pakietu aplikacji Notification Catcher

Charakterystyka klas została przedstawiona w porządku alfabetycznym:

AccessService

Klasa ta odpowiedzialna jest za implementacje metody pozyskiwania notyfikacji za

pomocą usług ułatwiania dostępu. Rozszerza ona systemową klasę

AccessibilityService dostarczającą metody z zakresu ułatwień dostępu. Szczegóły

sposobu pobierania powiadomień za pomocą tej metody zostały opisane w rozdziale

dotyczącym Accessibility Service.

BaseActivity

Aktywność ta jest podstawową w aplikacji, wszystkie inne aktywności dziedziczą po

niej. Dostarcza ona podstawowy widok i obsługę górnego menu aplikacji.

CustomListAdapter

Adapter widoku listy służący do wyświetlania powiadomień w postaci listy.

DatabaseHandler

Wewnątrz tej klasy inicjowana jest baza danych przy pierwszym uruchomieniu

aplikacji.

51

DragonMobileTTS

Zawiera implementację uruchomieniową syntezatora Dragon Mobile.

Extractor

W ciele tej klasy znajduje się proces odpowiedzialny za ekstrahowanie informacji z

przechwyconej notyfikacji.

IspeechTTS

Zawiera implementaję uruchomieniową syntezatora iSpeech.

MainActivity

Głowna aktywność aplikacji. Obsługuje widok ukazujący się po starcie aplikacji oraz

odbiera sygnały od silnika notyfikacji a następnie inicjuje syntezę mowy.

NotHistoryActivity

Aktywność obsługuje widok historii powiadomień oraz wszystkie operacje na nim

przeprowadzane.

NotificationDAO

Klasa jest kontenerem encji w bazie danych odpowiedzialnej za powiadomienia.

NotificationDataStore

W tej klasie metody odpowiedzialne są za komunikację z bazą danych oraz zamianę

rekordów z tabel w bazie danych na obiekty.

NotificationEngine

W klasie tej zaimplementowany jest silnik przetwarzający powiadomienia.

Odpowiedzialny jest on za przetworzenia danych z notyfikacji do postaci obiektu typu

Notification oraz za przesłanie informacji do silnika Text-To-Speech.

NotificationTypeDAO

Klasa jest kontenerem encji w bazie danych odpowiedzialnej za typy powiadomień.

NotListener

W ciele tej klasy zaimplementowany został sposób pozyskiwania notyfikacji za

pomocą Notification Listener. Klasa ta dziedziczy po klasie NotificationListener

NotSettingsActivity

Aktywność ta odpowiedzialna jest za wyświetlanie i zarządzanie widokiem ustawień

powiadomień.

PhoneReciver

Klasa ta zawiera implementację metody pozyskiwania notyfikacji za pomocą usługi

telefonii.

PInfo

Klasa ta jest kontenerem informacji o aplikacji w systemie Android.

52

SettingsActivity

Klasa ta implementuje ustawienia systemowe aplikacji oraz interakcję użytkownika w

widoku tychże ustawień.

SMSReciver

W klasie tej jest zaimplementowana metoda pobierania powiadomień za pomocą

usługi SMS.

ShowNotificationDetailsActivity

Aktywność ta zarządza widokiem szczegółów powiadomienia oraz interakcjami w tej

aktywności.

SwipeListViewTouchListener

Klasa ta zawiera implementację mechanizmu przesuwania w prawo lub lewo na liście

notyfikacji elementu w celu jego zarchiwizowania.

TextToSpeechEngine

Klasa ta jest implementacją silnika przetwarzania tekstu na mowę. W jej ciele

wyzwalane są w zależności od ustawień aplikacji mechanizmy Text-To-Speech.

Mechanizmy użyte w tej klasie zostały opisane w rozdziale dotyczącym przetwarzania

tekstu na mowę.

TypeModel

Klasa ta jest modelem aplikacji systemowej w widoku ustawień notyfikacji.

Utils

Klasa ta zwiera dodatkowe metody używane do przetwarzania informacji z

powiadomień w klasie Extractor.

53

9. Interfejs użytkownika aplikacji

Interfejs użytkownika aplikacji został zaprojektowany tak, aby jego używanie było

intuicyjne i proste dla użytkownika. Przy tworzeniu starano się maksymalnie uprościć

interfejs, by nie utrudniał korzystania z aplikacji. Po uruchomieniu aplikacji wita główny

panel aplikacji, który umożliwia dostęp do wszystkich aplikacji.

Rys. 18. Ekran startowy aplikacji przy pierwszym uruchomieniu (po lewej), w trybie normalnego działania (po prawej).

Na głównym ekranie znajduje się przycisk informujący o stanie aplikacji (czytanie

powiadomień włączone/wyłączone) oraz przyciski prowadzące do trzech głównych paneli

aplikacji: ustawień, ustawień powiadomień oraz historii powiadomień. Ustawienia aplikacji

od ustawień powiadomień rozdzielono celowo, aby nie komplikować ekranu ustawień

aplikacji. Po kliknięciu w wybraną przycisk użytkownik zostaje przeniesiony do

odpowiedniego ekranu.

Klikając w przycisk Ustawienia, pokazuje się ekran z opcjami aplikacji na jakie może

mieć wpływ użytkownik.

54

Rys. 19. Ekran ustawień aplikacji.

Pierwszą opcją jest znana z panelu głównego opcją włączania działania aplikacji. Kolejnym

ustawieniem jest Czytaj w trybie cichym. Opcja ta włącza czytanie powiadomień, nawet gdy

telefon jest ustawiony w trybie wyciszonym lub wibracji. Następną opcją jest

włączanie/wyłączanie czytania powiadomień typu Toast. Są to powiadomienia pojawiające

się zwykle u dołu ekranu w postaci paska i znikające po kilku sekundach. Opcja ta działa

tylko z włączoną opcją ułatwienia dostępu w sekcji mechanizmów powiadomień. Odrębną

sekcją w panelu ustawień są mechanizmy powiadomień. Sekcja ta pozwala wybrać

mechanizm powiadomień, za pomocą którego aplikacja będzie pobierać notyfikacje z

systemu. Jest tu możliwość wybrania jednej z trzech opcji: ułatwienia dostępu, usługa

powiadomień lub tylko sms. Za pomocą wyboru jednej z tej opcji użytkownik może

przetestować jak działają powiadomienia przy wybraniu odpowiedniej z opcji, następnie

zdecydować która z nich jest najodpowiedniejsza. Należy tutaj również wspomnieć, iż opcja

usługi powiadomień dostępna jest dla systemów Android w wersji 4.2 lub wyższej.

Posiadacze starszej wersji systemu muszą zdecydować się na jedną z pozostałych opcji.

Poniżej opcji mechanizmu powiadomień znajduje się opcje dotyczące przetwarzania dźwięku

na mowę. I tak opcja TTS pozwala na wybranie silnika Text-To-Speech, który będzie

przetwarzał powiadomienia do formy głosowej. Mamy tutaj do wyboru dwa silniki

wbudowanie w aplikację: iSpeech, Dragon Mobile oraz trzecią opcję ustawiającą jak silnik

TTS systemowy syntezator androida. Daje do możliwość użytkownikowi podłączenia do

aplikacji dowolnego silnika syntezy mowy, dostępnego dla systemu Android. Opcja lektor

pozwala na wybór języka lub osoby lektora, jeśli takowa konfiguracja jest możliwa dla

55

wybranego wcześniej silnika TTS. Użytkownik ma tu możliwość wybrania płci lektora lub

języka. Ustawienia dźwięku pozwalają ustalić, w jaki sposób powiadomienie ma być

skorelowane z sygnałem pojawiającego się powiadomienia.

Ostatnią opcją jest możliwość zdefiniowania czy notyfikacja ma zniknąć z ekranu po

przeczytaniu jej przez aplikację. Usługa ta dostępna jest tylko wtedy, gdy mechanizmem

powiadomień został wybrany Notification Listener.

Należy tutaj wspomnieć, iż w przypadku wyboru mechanizmu powiadomień aplikacja

poinformuje użytkownika o zagrożeniach, jakie może spowodować ustawienie takiego

mechanizmu. Użytkownik zostanie następnie przekierowany do odpowiedniego ekranu

ustawień systemowych, umożliwiających włączenie mechanizmu. W przypadku Ułatwień

dostępu ekranem, który pojawi się dla użytkownika będą ustawienia Ułatwiania dostępu.

Rys. 20. Ekran ustawień Ułatwień dostępu z włączonymi uprawnieniami dla aplikacji Notification Catcher.

Na tym ekranie użytkownik do poprawnego działania aplikacji musi włączyć usługę

NotificatinCatcher. Dopiero po włączeniu tej usługi aplikacja zacznie pobierać przychodzące

notyfikację i czytać je za użytkownika. Z kolei w przypadku wybrania usługi notyfikacji z

mechanizmów powiadomień przeniesieni zostaniemy do dostępu powiadomień, gdzie

użytkownik musi nadać uprawnienia NotificationCacher jako aplikacji mogącej używać

usługi powiadomień.

Rys. 21. Ekran Zabezpieczenia z informacją, że jedna aplikacja ma dostęp do powiadomień.

56

Rys. 22. Ekran Dostępu do powiadomień informujący prawach dostępu aplikacji Notification Catcher do powiadomień.

Przechodząc do kolejnego modułu aplikacji jakim są ustawienia powiadomień, ekran, który

się otworzy będzie zawierał listę wszystkich aplikacji systemowych mogących wystawiać

powiadomienia.

Rys. 23. Ekran Ustawienia Powiadomień aplikacji Notifiacation Catcher.

Domyślnie wszystkie powiadomienia, które mają być odczytywanie przez aplikację są

włączone. Na tym ekranie użytkownik może wybrać według własnego uznania

57

powiadomienia, z jakich aplikacji mają być odczytywanie przez syntezator Text-To-Speech.

Dzięki temu łatwo można skonfigurować aplikację w zależności od upodobań.

Kolejnym modułem aplikacji jest historia powiadomień. W tym module możemy

sprawdzić jakie notyfikacje zostały wystawione przez system android. Sprawdzić czy są

jakieś nowe powiadomienia nie przeczytane przez aplikację, ponieważ telefon był w trybie

cichym, jak również przejść bezpośrednio z notyfikacji do aplikacji, która ją wystawiła

klikając w jej logo.

Rys. 24. Ekran Historia Powiadomień z notyfikacjami zebranymi przez aplikację.

Dla użytkownika prezentowana jest lista powiadomień wraz z informacjami zawartymi w nim

oraz godziną i datą pojawienia się aplikacji. Klikając na dowolny element z listy otworzy się

ekran z szczegółami notyfikacji. Przesuwając notyfikację w prawo następuje usunięcie jej z

listy.

58

10. Podsumowanie

W niniejszej pracy został przeanalizowany temat przetwarzania powiadomień systemu

Android na formę głosową za pomocą metod przetwarzania tekstu na mowę (Text-To-

Speech). Praca została podzielona na trzy główne części. W pierwszej części zostały

przeanalizowane sposoby z jakich można korzystać przy przechwytywaniu powiadomień

wystawianych przez różne aplikacje w środowisku Android. Zostały przeanalizowane,

zaimplementowane i przetestowane trzy ścieżki dostępu do notyfikacji: metoda oparta o

usługę ułatwiania dostępu, metoda oparta o usługę telefonii oraz metoda korzystająca z

Notification Listenera. Najlepsza z tych metoda okazała się ta bazująca na Notification

Listener, ponieważ za jej pomocą możliwe jest pobranie informacji o notyfikacjach z

największej liczby aplikacji oraz usuwanie powiadomień bezpośrednio z aplikacji.

Druga cześć pracy opisuje metody przetwarzania tekstu na mowę w środowisku

Android. W tym celu wybrano, scharakteryzowano a następnie zaimplementowano i

przetestowano dwie opcje silników przetwarzania tekstu na mowę. Były to rodziny

syntezatorów mowy działające w systemie Android (Google Text-To-Speech) oraz rodziny

syntezatorów pracujących na zasadzie systemów Software as a Service (iSpeech oraz

DragonMobile). Syntezatory te przetestowano pod kątem poprawności czytanego tekstu w

języku polskim. Wszystkie silniki syntezy mowy w testach poprawności wykazały się

podobną skutecznością analizowanego teksu. Najlepszy wynik został osiągnięty przez system

przetwarzania tekstu na mowę od firmy Google. Wynik ten nie zaskakuje, ponieważ od wielu

wersji Androida synteza mowy jest udoskonalana i z wersji na wersję osiąga co raz to lepsze

wyniki. Syntezatorów nie testowano pod względem jakości mowy, ponieważ była by to

ocena subiektywna i każdy użytkownik może wybrać odpowiedni dla siebie głos.

Finalną częścią pracy było połączenie części pierwszej o pozyskiwaniu notyfikacji oraz

części drugiej o przetwarzaniu tekstu na mowę. W tym celu stworzono aplikację prezentującą

możliwości odczytywania przez syntezator mowy treści powiadomień z aplikacji systemu

Android. Stworzona aplikacja jest czymś w rodzaju pomocnika, który odczytuje wiadomości

tekstowe, informacje z portali społecznościowych, maile itd.. Informacje te przekazywane są

dla użytkownika w sposób głosowy na wybrane wyjście audio urządzenia w momencie

wystąpienia określonego zdarzenia (powiadomienia) bez jakiejkolwiek potrzeby interakcji ze

strony użytkownika. Aplikacja ta może służyć zarówno osobom mającym problemy ze

wzrokiem, jak i sportowcom podczas codziennych treningów.

59

11. Bibliografia

[1] Dutoit T., An Introduction to Text-To-Speech Synthesis, Kluwer Academic Publishers,

2001

[2] Google Inc., Android delevopers guide, 2014, http://developer.android.com/index.html

[3] Gunasekera S. A., Android Apps Security, New York, Apress, 2012

[4] Hoog A, Android Forensics Investigation, Analysis and Mobile Security for Google

Android, Waltham, Elsevier Inc., 2011

[5] Jordan L. i Greyling J., Practical Android Projects, New York, Apress, 2011

[6] Komatineni S. i MacLean D., Pro Android 4, New York, Apress, 2012

[7] Milette G. i Stroud A., Professional Android Sensor Programming, Indianapolis, John

Wiley & Sons Inc., 2012

[8] Smith D. i Friesen J., Android Recipes A Problem-Solution Approach Second Edition,

New York, Apress, 2012

[9] Strona Dragon Mobile SDK dla programistów, 2014,

http://dragonmobile.nuancemobiledeveloper.com/

[10] Taylor P., Text-to-Speech Synthesis, Cambridge, Cambridge University Press, 2009

[11] Ispeech Developers Site, 2014, https://www.ispeech.org/developers

[12] Text-To-Speech Google API, 2014,

http://developer.android.com/reference/android/speech/tts/TextToSpeech.html

[13] Sms Reader, 2013,

https://play.google.com/store/apps/details?id=de.braunandroid.smsreader

[14] Notification Avatar, 2014,

https://play.google.com/store/apps/details?id=com.spicedroid.notifygirl.free

[15] Voice Notify, 2014, http://pilot51.com/wiki/Voice_Notify

[16] Notification Reader, 2014,

https://play.google.com/store/apps/details?id=com.parkpossesoftware.notificationread

er

[17] Speak Me, 2014, https://play.google.com/store/apps/details?id=com.flip.speakme