poniedziałek, kwietnia 11, 2011

Zinwigiluj się sam ;-)

Nie jesteście czasem ciekawi gdzie wykonujecie najwięcej połączeń telefonicznych? ;-)
Ja bywam tego ciekaw.
Dlatego piszę sobie narzędzie do samoinwigilacji ;-) To też przykład tego jak prosto pisać w Androidzie ;-)

Założenie wstępne jest taki, że chcę mieć narzędzi, które w momencie otrzymania połączenia lub gdy sam je nawiązuje pobierze moją lokalizacje i wszystko zapisze do pliku :-)

Przykładowa linia w pliku wygląda tak:
Mon Apr 11 16:58:16 GMT+00:00 2011,outgoing,111222333,37.422005,-122.084095,1416.0,network,"Mountain View, California, United States"

Mamy więc datę, informacje o kierunku, numer telefonu, szerokość i długość geograficzną, dokładności pozycji, rodzaj providera z którego pobrano informacje i na końcu "adres" tego miejsca.

Pierwszym problemem było dobranie się do informacji o przychodzących i wychodzących połączeniach.... w Androidzie to kilka dodatkowych linijek w manifeście i 2 klasy (choć można by pewnie i 1 klasą to zająć ;-)).
Informacje o tym jak to zrobić i część kodu podprowadziłem stąd.
Nasz kod musi słuchać broadcastów dla android.intent.action.PHONE_STATE i android.intent.action.NEW_OUTGOING_CALL.

Gdy już mamy informacje o numerze telefonu i kierunku to przekazujemy te dane do serwisu.
W serwisie zaś rejestrujemy 2 listenery dla pozycji, jeden dla sieci drugi dla GPSa.
Gdy któryś z listenerów dostaje informacje o pozycji wykonuje się taki kod:
lat = location.getLatitude();
lon = location.getLongitude();
hasLocation = true;

try {
String line = new Date()+","+action+","+number+","+lat+","+lon+","+location.getAccuracy()+","+location.getProvider();
List<Address> addresses = new Geocoder(LoggerService.this).getFromLocation(lat, lon, 1);
if (addresses.size()>0) {
String locality = addresses.get(0).getLocality();
String area = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
List elems = new ArrayList();
elems.add(locality); elems.add(area); elems.add(country);
String loc = "";
for (String l:elems) {
if (l!=null) {
loc+=l+", ";
}
}
if (!"".equals(loc)) {
loc = loc.substring(0,loc.length()-2);
}
if (loc==null) {
loc = "("+lat+" "+lon+")";
}
line+=",\""+loc+"\"";
}

FileWriter fw = new FileWriter(new File(Environment.getExternalStorageDirectory().toString()+File.separator+"callerLog.txt"), true);
fw.write(line+"\n");
fw.close();
} catch (Exception e) {
e.printStackTrace();
}

stopObtainingOfLocation();


Czyli składamy nieładnie linię do zapisania w logu, po czym próbujemy pobrać przy pomocy goekodera adres w którym się znajdujemy.
W końcu wszystko ląduje w pliku.
A jakby co się nie udało to łapiemy wyjątek i rzucamy stack trace'a (w produkcyjnym kodzie tak się nie powinno robić bo szkoda loga).
Na koniec wołana jest moja funkcja do zatrzymania zbierania lokalizacji :-)

Kto ciekaw to tutaj źródeła, a tutaj wspaniała aplikacja ;-)

Łączny czas wykonania około 90 minut, z czego większość czasu spędzone na oczekiwaniu na uruchomienie emulatora ;-)


Podobne postybeta
Sztuczki tropiciela błędów, part 2 ;-)
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Niecne wykorzystanie refleksji... czyli jak poszukać tekstu w drzewie obiektów? ;-)
Czy ustalanie pozycji w Androidzie może kosztować?
SleepAdvisor - komórka pomaga w wyspaniu się ;-)