Nie widziałem Twojego kodu, ale wydaje mi się, że połączenie Bluetooth powinno być inicjowane w metodzie onResume() w Activity, w którym nawiązujesz połączenie. Możesz ten kod wsadzić do jakiejś oddzielnej klasy.Twój handler najlepiej stwórz w osobnym pliku. Obiekt handlera możesz tworzyć w klasie dziedziczącej po Application lub w metodzie onResume() w Activity przed nawiązaniem połączenia Bluetooth.
Handler, to pętla, która odczytuje wiadomości wysyłane gdzieś w projekcie i przechwytuje je w wątku UI.
Możesz zrobić w ten sposób:
Najpierw tworzysz interfejs:
public interface GenericActivitySignalContract {
void setMessageFromDevice(String string);
}
Tego interfejsu użyjesz w celu przekazania sygnału z Handlera do Activity.
Twoje Activity powinno implementować ten interfejs.
class MyActivity extends Activity implements GenericActivitySignalContract {
// ...
private void setMessageFromDevice(String string) {
myTextView.setText("message from bluetooth device: " + string);
}
// ...
@Override
public void onResume() {
GenericApplication.setActivityViewContract(this); // przypięcie bieżącego activity do Handlera - wyjaśnienie jest w dalszej części wypowiedzi
GenericApplication.initializeHandler(); // inicjacja handlera - metoda jest opisana w dalszej części wypowiedzi
}
}
W Twojej klasie handlera możesz stworzyć taką metodę:
public void setActivityViewContract(GenericActivitySignalContract activityForUiUpdates) {
this.activityViewContract = activityForUiUpdates;
}
Ta metoda będzie służyła do ustawiania Activity dla Handlera. Dzięki temu zabiegowi będziemy mogli ustawiać różne klasy Activity implementujące interfejs GenericActivitySignalContract dla Handlera.
Cała klasa Handlera może wyglądać następująco:
public final class MyHandler extends Handler {
private final static MESSAGE_ONE = "one";
private final static MESSAGE_TWO = "two";
public void setActivityViewContract(GenericActivitySignalContract activityForUiUpdates) {
this.activityViewContract = activityForUiUpdates;
}
@Override
public void handleMessage(Message msg) {
if(msg.what == MESSAGE_ONE) { // nie pamiętam, który dokładnie parametr powinien posiadać dane odczytywane z urządzenia
activityViewContract.setMessageFromDevice(msg.what); // możesz poeksperymentować z msg.what, msg.arg1, msg.arg2, etc.
} else if(msg.what == MESSAGE_TWO) { // IDE podpowie Ci, jakie metody są dostępne
activityViewContract.setMessageFromDevice(msg.what); // tutaj można też wywołać inną metodę z interfejsu, jeśli zostanie stworzona
}
}
}
Oczywiście zamiast tych if-ów możesz sobie zrobić instrukcję switch, a najlepiej HashMapę i obiekty dla każdego sygnału (wiadomości).
Można to bardziej elegancko napisać, ale nie bawiłem się w takie rzeczy dla celów tego przykładu, żeby nie zaciemniać obrazu.
Wartości w zmiennych statycznych są przykładowe. Nie wiem, jakie wiadomości wysyła Twoje urządzenie. Ten element trzeba dostosować do projektu.
Możesz też w ogóle zrezygnować z rozdzielania wiadomości na typy, jeśli obsługujesz tylko jeden typ lub jeśli chcesz za każdym razem robić to samo (np. odczytać jednego Stringa i przekazać go do jednego TextView).
Nadpisana metoda handleMessage() służy do przechwytywania wiadomości z urządzenia. Następnie za pomocą interfejsu, będziesz mógł przekazać tę wiadomość do Activity.
Nie wiem, dlaczego w przykładzie ze strony Google jest wywołanie metody obtainMessage(). Nie jest to metoda wbudowana w generyczną klasę Handler. Być może w tym przykładowym programie dane są przekazywane w inny sposób lub jest to rozwiązane inaczej.
Następnie w klasie dziedziczącej po Application (nazwijmy ją GenericApplication) tworzymy taką metodę:
class GenericApplication extends Application {
private MyHandler mHandler;
public initializeHandler() {
this.mHandler= new MyHandler();
}
public void setActivityViewContract(GenericActivitySignalContract activity) {
mHandler.setActivityViewContract(activity);
}
}
Teraz po odebraniu wiadomości z urządzenia Bluetooth, w Activity w wątku UI zostanie wywołana metoda void setMessageFromDevice(String string) i w niej będziesz mógł obsłużyć odebraną wiadomość. Np. wstawić ją do TextView lub zrobić cokolwiek innego w wątku graficznym.
Pisałem to na poczekaniu. Możliwe, że gdzieś w mojej wypowiedzi są jakieś drobne błędy. W każdym razie, mam nadzieję, że to pomoże, choć jeśli piszesz na Androida od niedawna, to nie wszystko może być jasne. Zawsze pozostaje Google, StackOverflow i eksperymenty. ;)