Czujniki/Sensory Kontynuacja projektu "Stan urz�dzenia" Dla u�atwienia kod do odczytywania stanu urz�dzenia mo�na zamkn�� w komentarze //region STAN URZ�DZENIA ... //endregion i zwin��. 1. SensorManager - zarejestrujemy nasluchiwacz (klasa aktywno�ci b�dzie go implementowa�), kt�rego metoda onSensorChanged b�dzie wywo�ywana gdy zmieni si� stan czujnika. Nie b�dziemy jednak od razu wy�wietla� wyniku, a zapiszemy go do p�l, kt�re co 2 sekundy b�dzi odczytywany i zapisywany do struktur wy�wietlanych w li�cie. a. Dodajemy do klasy StanActivity informacj� o implementowaniu SensorEventListener. Interfejs ten rz�dza zdefiniowania dw�ch metod onAccuracyChanged (b�dzie pusta) i onSensorChanged (zrobimy to p�niej) public class StanActivity extends Activity implements SensorEventListener { ... b. Definiujemy prywatne pola: //zarzadca czujnikow private SensorManager sensorManager = null; Sensor akcelerometr = null; Sensor magnetometr = null; //Sensor orientacja = null; //pola, w ktorych zapisywane beda przyspieszenie, pole mg i orientacja static float ax = 0; //m/s^2 static float ay = 0; static float az = 0; static float a = 0; static float mx = 0; //mT static float my = 0; static float mz = 0; static float m = 0; /* static float oz_azymut = 0; //stopnie static float ox_pochylenie = 0; static float oy_nachylenie = 0; */ c. Pierwsza grupe p�l inicjujemy w metodzie StanActivity.onResume @Override protected void onResume() { super.onResume(); //czujniki if(sensorManager==null) { //Toast.makeText(getApplicationContext(), "Rozpoczynam odczyty czujnik�w", Toast.LENGTH_LONG).show(); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); akcelerometr = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); magnetometr = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); //orientacja = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); sensorManager.registerListener(this,akcelerometr,SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(this,magnetometr,SensorManager.SENSOR_DELAY_NORMAL); //sensorManager.registerListener(this,orientacja,SensorManager.SENSOR_DELAY_NORMAL); } } d. Wyrejestrowujemy w onPause: @Override protected void onPause() { super.onPause(); if(batteryReceiver!=null) this.getApplicationContext().unregisterReceiver(batteryReceiver); if(sensorManager!=null) sensorManager.unregisterListener(this); //czujniki } e. Definiujemy metody interfejsu SensorEventListener (mo�e to za nas zrobi� Eclipse): //metody SensorEventListener public void onAccuracyChanged(Sensor sensor, int accuracy) { // } public void onSensorChanged(SensorEvent event) { switch(event.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: ax = event.values[0]; ay = event.values[1]; az = event.values[2]; a = (float)Math.sqrt(ax*ax+ay*ay+az*az); //FloatMath jest deprecated break; case Sensor.TYPE_MAGNETIC_FIELD: mx = event.values[0]; my = event.values[1]; mz = event.values[2]; m = (float)Math.sqrt(mx*mx+my*my+mz*mz); break; /* case Sensor.TYPE_ORIENTATION: oz_azymut = event.values[0]; ox_pochylenie = event.values[1]; oy_nachylenie = event.values[2]; break; */ } } f. Zapisane w tych metodach pola odczytujemy w metodach odczyta.. static private UrzadzenieInfo odczytajAkcelerometr(Activity activity) { UrzadzenieInfo akcelerometrInfo = new UrzadzenieInfo(); akcelerometrInfo.typInformacji = TypInformacji.Czujnik; akcelerometrInfo.nazwa="Akcelerometr"; akcelerometrInfo.opis = "ax=" + ax + "\nay=" + ay + "\naz=" + az + "\na=" + a + " [m/s^2]"; akcelerometrInfo.polozeniePaska = (a>100)?100:(int)a; return akcelerometrInfo; } static private UrzadzenieInfo odczytajMagnetometr(Activity activity) { UrzadzenieInfo magnetometrInfo = new UrzadzenieInfo(); magnetometrInfo.typInformacji = TypInformacji.Czujnik; magnetometrInfo.nazwa="Magnetometr"; magnetometrInfo.opis = "Bx=" + mx + "\nBy=" + my + "\nBz=" + mz + "\nB=" + m + " [mT]"; magnetometrInfo.polozeniePaska = (m>100)?100:(int)m; return magnetometrInfo; } /* static private UrzadzenieInfo odczytajOrientacje(Activity activity) { UrzadzenieInfo orientacjaInfo = new UrzadzenieInfo(); orientacjaInfo.typInformacji = TypInformacji.Czujnik; orientacjaInfo.nazwa="Orientacja"; orientacjaInfo.opis = "azymut=" + oz_azymut + "\npochylenie=" + ox_pochylenie + "\nnachylenie=" + oy_nachylenie + " [stopnie]"; orientacjaInfo.polozeniePaska = -1; return orientacjaInfo; } */ g. Wywolania tych metod dodajemy do metody odswiezListe: listaUrzadzen.add(odczytajAkcelerometr(this)); listaUrzadzen.add(odczytajMagnetometr(this)); //listaUrzadzen.add(odczytajOrientacje(this)); 2. LocationManager - lokacja (nie myli� z lokalizacj�) - schemat identyczny jak wy�ej a. Zaczynamy od uprawnie�, jakie musi zadeklarowa� aplikacja, aby korzysta� z lokalizacji (zgrubnej i dok�adnej). Dodajemy poni�sze znaczniki do pliku manifestu (za uses-sdk): <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> b. Definiujemy pole LocationManager i pole Location, w kt�rym b�dziemy zapisywa� po�o�enie odczytane w metodzie zwi�zanej z kolejnym interfejsem - LocationListener (trzeba go doda�!!) public class StanActivity extends Activity implements SensorEventListener, LocationListener { ... private LocationManager locationManager = null; static Location lokacja; c. Inicjujemy pierwsze z nich w onResume i zwalniamy w onPause: @Override protected void onResume() { super.onResume(); //Toast.makeText(getApplicationContext(), "Rozpoczynam odczyty czujnik�w", Toast.LENGTH_LONG).show(); //czujniki if(sensorManager==null) { sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); akcelerometr = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); magnetometr = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); orientacja = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); sensorManager.registerListener(this,akcelerometr,SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(this,magnetometr,SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(this,orientacja,SensorManager.SENSOR_DELAY_NORMAL); } //lokacja - wymaga dodatkowych uprawnien!!! if(locationManager==null) locationManager=(LocationManager) getSystemService(LOCATION_SERVICE); String dostawca = locationManager.getBestProvider(new Criteria(), true); try { lokacja = locationManager.getLastKnownLocation(dostawca); locationManager.requestLocationUpdates(dostawca, 60000, 1, this); } catch(SecurityException exc) //alternatywnie checkPermissions() { Toast.makeText(getApplicationContext(), "Brak uprawnie� do odczytania po�o�enia", Toast.LENGTH_LONG).show(); } } @Override protected void onPause() { super.onPause(); if(batteryReceiver!=null) this.getApplicationContext().unregisterReceiver(batteryReceiver); if(sensorManager!=null) sensorManager.unregisterListener(this); //czujniki if(locationManager!=null) locationManager.removeUpdates(this); //lokacja } d. Definiujemy metody interfejsu, ale tylko jednej u�ywamy: //metody LocationListener public void onLocationChanged(Location location) { StanActivity.lokacja=location; } public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } e. Definiujemy metod� odczytuj�c� zdobyte w onLocationChanged static private UrzadzenieInfo odczytajPolozenie(Activity activity) { double lDlugoscGeograficzna=0; double lSzerokosc=0; double lWysokosc=0; double lSzybkosc=0; double lNamiar=0; long lCzas=0; String lDostawca=""; if(lokacja!=null) { lDlugoscGeograficzna=lokacja.getLongitude(); lSzerokosc=lokacja.getLatitude(); lWysokosc=lokacja.getAltitude(); lSzybkosc=lokacja.getSpeed(); lNamiar=lokacja.getBearing(); lCzas=lokacja.getTime(); lDostawca=lokacja.getProvider(); } UrzadzenieInfo polozenieInfo = new UrzadzenieInfo(); polozenieInfo.typInformacji = TypInformacji.Czujnik; polozenieInfo.nazwa="Po�o�enie"; polozenieInfo.opis = "czas: " + lCzas + "\nd�ugo�� geograficzna: " + lDlugoscGeograficzna + "\nszeroko�� geograficzna: " + lSzerokosc + "\nwysoko��: " + lWysokosc; polozenieInfo.opis += "\nnamiar (kierunek): " + lNamiar + "\nszybko��: " + lSzybkosc + "\ndostawca: " + lDostawca; polozenieInfo.polozeniePaska = (lSzybkosc>100)?100:(int)lSzybkosc; return polozenieInfo; } f. Wywo�ujemy j� w metodzie odswiezListe. [DALEJ NIE ZWERYFIKOWANE W ANDROID STUDIO] 3. W emulatorze nie ma emulacji wynik�w GPS i innych czujnik�w - mo�na do tego u�y� SensorSimulator (u mnie nie zadzia�a�, testowa�em na rzeczywistych urz�dzeniach) WWW: http://code.google.com/p/openintents/wiki/SensorSimulator The Android emulator doesn't support it itself but OpenIntents' SensorSimulator fills the void. Download and unpack the zip file, then start the standalone jar file: $ java -jar bin/sensorsimulator.jar Next, install SensorSimulatorSettings on the emulator using the adb tool which comes with the SDK: $ adb -s <emulator device> install bin/SensorSimulatorSettings.apk (run adb devices to find the emulator device name). Finally, run the installed SensorSimulatorSettings app in the emulator and enter the IP address 10.0.2.2 (despite what the SensorSimulator application might suggest. This is an alias to the loopback device of the development host so should always be valid.