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.