Czat bluetooth: Różnice pomiędzy wersjami
m (→Zaprogramowanie aplikacji: korekta) |
m (1 wersja: Import scenariuszy AppInventor) |
(Brak różnic)
|
Aktualna wersja na dzień 19:55, 11 mar 2015
Spis treści
Cele
Stworzymy aplikację, która będzie pozwalała na komunikację pomiędzy dwoma urządzeniami poprzez połączenie bluetooth. Aplikacja będzie wymagała wcześniejszego sparowania, czyli połączenia obu telefonów. W przeciwnym wypadku aplikacja nie będzie widziała punktów do podłączenia, czyli innych urządzeń. Zatem jeszcze przed rozpoczęciem pracy nad aplikacją warto włączyć w urządzeniu Bluetooth i połączyć je z innym urządzeniem, co ułatwi nam pracę na późniejszym etapie.
Czat bluetooth
Rozpoczęcie pracy
Tak, jak zawsze, wejdźmy na stronę http://appinventor.mit.edu i wybierzmy Create, by uruchomić App Inventor. Następnie przejdźmy do zakładki My Projects (1), gdzie znajdziemy wszystkie nasze projekty - wystarczy tylko zalogować się na odpowiednie konto Google. W celu rozpoczęcia pracy nad nowym projektem kliknijmy na Start new project (2), i wpiszmy w oknie jego nazwę, np. Czat_lokalny.
Nastąpi teraz automatyczne przejście do okna budowy aplikacji.
Projektowanie interfejsu
Zacznijmy oczywiście, od zaprojektowania interfejsu aplikacji. Na samym początku podzielmy okno programu na trzy poziome sekcje. Pierwsza z nich będzie zawierała przycisk z listą dostępnych urządzeń, druga będzie składała się z pola tekstowego oraz przycisku do wysyłania wiadomości, natomiast w ostatniej sekcji umieścimy okno, w którym będzie wyświetlana cała konwersacja.
Na początku ustalmy orientację naszej aplikacji na pionową, tak jak robiliśmy to w poprzednich aplikacjach. W celu zablokowania obrotu ekranu i ustawienia orientacji na pionową musimy zaznaczyć Screen1 w oknie Components, a następnie w oknie Properties ustawić ScreenOrientation na Portrait.
Teraz przejdźmy do zakładki Layout w palecie dostępnych komponentów i dodajmy, jeden pod drugim, trzy komponenty HorizontalArrangement (1).
Teraz zmodyfikujmy wszystkie trzy dodane komponenty. Dla każdego z nich we właściwościach ustawmy szerokość jako Fill Parent (1), by komponenty te wypełniły na szerokość cały ekran. W pierwszych dwóch komponentach wysokość pozostawmy jako Automatic (2).
Dopiero w ostatnim komponencie wysokość, czyli parametr Height ustawmy jako Fill Parent (1), by ten ostatni element wypełnił całe wolne miejsce, które pozostało na ekranie. Teraz do naszej pierwszej sekcji, czyli HorizontalArrangement1 dodajmy komponent ListPicker z grupy User Interface (1). Następnie zmieńmy od razu jego nazwę na Połącz (2).
Włóżmy teraz do naszego drugiego komponentu HorizontalArrangement2 element TextBox (1), w którym będziemy wpisywali nasze wiadomości. Zaraz obok dodajmy komponent Button (2), za pomocą którego wiadomości będą wysyłane.
Zmieńmy teraz jeszcze teksty wyświetlane na naszych komponentach. Dla komponentu TextBox1 w polu Hint (1) wpiszmy Wiadomość. Wartość pola Hint będzie wyświetlana w komponencie TextBox1 jako wskazówka, mówiąca użytkownikowi o przeznaczeniu tego pola.
Teraz przejdźmy do zmiany tekstu wyświetlanego na przycisku. Zaznaczmy go i w polu Text (1) wpiszmy Wyślij.
W tym momencie zajmijmy się naszym trzecim komponentem HorizontalArrangement3. Mianowicie dodajmy do niego element Label z grupy User Interface (1). We właściwościach tego elementu, czyli w oknie Properties, w polu Text ustawmy pustą wartość.
Prace nad naszym interfejsem dobiegają końca. Teraz musimy dodać komponenty, które będą bezpośrednio odpowiadały za działanie naszego czatu. Znajdziemy je w sekcji Ceonnectivity (1). Będziemy potrzebowali trzy z nich: BluetoothServer, BluetoothClient oraz ActivityStarter. Przeciągnijmy każdy z nich na ekran. Jako że są one niewidoczne, znajdziemy je pod polem z ekranem naszej aplikacji, w grupie Non-visible compoments.
Ostatnim komponentem, jakiego potrzebujemy, jest Clock, czyli zegar - znajdziemy go w grupie Sensors. Ten komponent również jest niewidzialny, jak trzy poprzednie, które dodaliśmy. Clock będzie nam niezbędny do regularnego odświeżania czasu rozmów. Ustawmy go domyślnie, jako wyłączony, czyli TimerEnabled (2), a jako interwał wpiszmy wartość 100 milisekund (3). Dla łatwiejszej pracy możemy zmienić również nazwy komponentów odpowiadających za wysyłanie i przyjmowanie wiadomości. Zmieńmy zatem nazwę BluettoothClient1 na Klient (4) oraz BluettoothSerwer1 na Serwer (5).
Kiedy zgromadziliśmy już wszystkie komponenty, zadbajmy o to, by miały one poprawne nazwy. To ułatwi nam pracę podczas układania programu, do czego za chwilę przejdziemy. Zmieńmy więc nazwy przycisków tak, jak na ilustracji obok:
- ListPicker1 zmieńmy na lista_urządzeń (1)
- TextBox1 zmieńmy na Treśc_wiadomości (2)
- Button1 zmieńmy na przycisk_wyślij (3)
- Label1 zmieńmy na treść_rozmowy (4)
Zaprogramowanie aplikacji
Teraz przejdźmy do stworzenia instrukcji programu, aby aplikacja mogła działać. Przełączmy się zatem do trybu Blocks i rozpocznijmy kolejny etap naszej pracy.
Na początek zajmijmy się utworzeniem procedury Sprawdź_bluetooth. Będzie ona sprawdzała włączenie modułu Bluetooth dla komponentu Klient, a jeżeli ten będzie wyłączony, to wyświetli okno z prośbą o włączenie Bluetooth na urządzeniu. Uruchomiona zostanie więc akcja ActivityStarter1 i przyjmie ona wartość android.bluetooth.adapter.action.REQUEST_ENABLE.
Teraz przejdźmy do instrukcji, która wywoła start stworzonej przed chwilą przez nas procedury Sprawdź_bluetooth. Chcemy, by procedura uruchamiała się waz z rozpoczęciem działania aplikacji, dlatego użyjemy do tego warunku uruchomienia aplikacji, czyli when[Screen1].Initialiaze.
W kolejnej instrukcji ustalimy, że nazwa użytkownika będzie wyświetlała się na górnej belce aplikacji oraz że będzie ona losową liczbą z przedziału 1000-9999.
Teraz dodajmy procedurę inicjalizacji serwera czatu, by informacje pomiędzy urządzeniami mogły być wymieniane. Ustawmy nasłuchiwanie (czyli poszukiwanie informacji przez inne urządzenie) oraz akceptację połączenia bez nazwy. Musimy dodać również zmienną globalną, dzięki której będziemy determinować późniejsze akcje w odbiorze i wysyłaniu wiadomości.
Następną instrukcją, jaką stworzymy, jest funkcja wypisz, która będzie nam wypisywała cały tekst rozmowy w polu konwersacji. Do funkcji dodajmy zmienną lokalną treść, dzięki której odczytamy przekazany tekst i następnie dodamy go do istniejącej już treści rozmowy, stąd funkcja typu string (ciąg znaków) do łączenia zmiennych, czyli join. Innymi słowy - na początku pola treść dodamy tekst, który otrzymaliśmy od naszego rozmówcy, zachowując przy tym stary, wcześniej otrzymany tekst.
Kolejna instrukcja to dodanie słuchacza włączeń zegara. Tak, jak ustaliliśmy wcześniej, to działanie będzie wykonywane co 100 milisekund - wpisaliśmy tę wartość w interwale w komponencie Clock1.
Nasza aplikacja, zarówno jeśli będzie działała jako serwer, jak i jako klient (mówi o tym zmienna jestem_serwerem w pierwszym warunku if (jeśli) na powyższej ilustracji), będzie stale sprawdzała co 100 milisekund, czy są nowe porcje danych do pobrania. Jeśli tak (jeśli są jakieś dane do pobrania, to jest ich więcej niż 0), to zostaną one pobrane i wypisane na ekranie przy użyciu wcześniej zdefiniowanej funkcji wypisz, przekazując do niej całej otrzymany tekst.
W aktualnej postaci nasza aplikacja potrafi tylko oczekiwać na połączenie oraz na nowe wiadomości, nie ma jednak możliwości, by połączyć się z innym urządzeniem. Potrzebujemy zatem instrukcji, która będzie realizowała nowe połączenia.
Nowe połączenia będą przyjmowane za pomocą komponentu listPicker, który nazwiemy lista_urządzeń. Po kliknięciu w ten komponent pojawi się nam lista sparowanych wcześniej urządzeń, o czym wspominaliśmy na początku. Po wybraniu opcji z listy pogram spróbuje połączyć się z wybranym telefonem czy tabletem. Najpierw, przy użyciu słuchacza BeforePicking (przed wybraniem), wypełnijmy listę dostępnymi urządzeniami.
Następnie, po wybraniu, spróbujmy połączyć się z klikniętym urządzeniem. Posłuży nam do tego słuchaczAfterPicking (po wybraniu), w którym mamy dostępną klikniętą pozycję z listy.
Teraz kilka słów wyjaśnienia na temat powyższej metody. W pierwszym warunku if na powyższej ilustracji próbujemy połączyć się z wybranym urządzeniem. Jeśli nam się powiedzie i połączenie zostanie ustanowione, to funkcja łącząca zwróci nam wartość true (prawda), dzięki czemu wejdziemy do środka. W środku natomiast, jeżeli łączymy się z jakimś urządzeniem, to na pewno nie jesteśmy serwerem, co ustawiamy na początku (set[global jestem_serwerem] to false). Dalej - jeśli nie jesteśmy serwerem, to wyłączamy nasłuchiwanie nowych połączeń, a na koniec włączamy Clock1, który będzie odświeżał nam zawartość konwersacji czatu.
Mamy również funkcję else, która oznacza “lub” dla funkcji if. Zatem jeżeli nie uda nam się połączyć, to zostanie aktywowana funkcja else, a w niej uruchomi się inicjalizacja, która na wszelki wypadek włączy ponownie nasłuchiwanie dostępnych połączeń i ustawi zmienną lokalną jestem_serwerem na fałsz.
Możemy w tym momencie przejść do zbudowania prostej metody formatowania wysyłanych wiadomości. Jak widzimy, funkcja ta polega na połączeniu nazwy użytkownika z wysyłaną wiadomością oraz dodanie kresek i znaku nowej linii \n.
Kolejną bardzo istotną instrukcją będzie moduł, służący do powiadomienia użytkowników o tym, że są ze sobą połączeni. Na początku poskładajmy metodę odpowiadającą za wysyłanie wiadomości:
Funkcja wydaje się obszerna, ale ponownie jest to spowodowane faktem, że obsługujemy jednocześnie dwa stany: aplikację jako serwer i jako klient. W pierwszym warunku sprawdzamy, czy jesteśmy serwerem, czy też nie i w zależności od wyniku (nie możemy obsłużyć zdarzenia bez sprawdzenia tego warunku) używamy funkcji serwera lub klienta do wysyłania wiadomości, którą ostatecznie wypisujemy na czacie poprzez utworzoną wcześniej metodę wypisz.
Teraz możemy dodać odpowiedni blok do when[lista_urządzeń].AfterPicking. Wróćmy więc do naszej instrukcji, którą ustawiliśmy chwilę wcześniej i dodajmy do niej brakujący blok z wiadomością, że połączenie się powiodło (1).
Klient jest już obsłużony, zatem czas teraz na informację od serwera, że połączenie zostało zaakceptowane:
Mamy zatem słuchacza serwera Bluetooth, który czeka na informację, czy jakieś urządzenie zostało podłączone. Jeśli tak, to ustawmy zgodnie z prawdą zmienną jestem_serwerem na true (prawda). Następnie wyślijmy wiadomość do klienta, że połączenie zostało zaakceptowane oraz uruchommy zegar do sprawdzania, czy nadeszły jakieś nowe wiadomości.
Na sam koniec ustawmy instrukcję, która pozwoli nam wysłać tekst. Zróbmy więc tak, że po kliknięciu przycisku przycisk_wyślij zostanie wysłany tekst wpisany w polu treść_wiadomości, a po wykonaniu tej czynności pole z treścią zostanie wyczyszczone.
Podsumowanie
Dobrnęliśmy wreszcie do końca dość skomplikowanej, trzeba przyznać, aplikacji. Wiemy już, w jaki sposób łączyć ze sobą urządzenia i jak przekazywać między nimi informacje z wykorzystaniem technologii Bluetooth. Poznaliśmy zasady pracy aplikacji jako serwer oraz jako klient, co z pewnością będzie przydatne przy budowaniu zaawansowanych aplikacji pracujących chociażby z wykorzystaniem internetu.