0% found this document useful (0 votes)
42 views

PressureSensor Tutorial

The document discusses how to create an Android app that uses the pressure sensor on the Sony Xperia active smartphone. It provides code examples to access the pressure sensor and log pressure data to a content provider. It also describes using an AlarmManager to trigger data collection periodically in the background.

Uploaded by

Sfrj Caffe
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views

PressureSensor Tutorial

The document discusses how to create an Android app that uses the pressure sensor on the Sony Xperia active smartphone. It provides code examples to access the pressure sensor and log pressure data to a content provider. It also describes using an AlarmManager to trigger data collection periodically in the background.

Uploaded by

Sfrj Caffe
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

GetyourappstoworkwiththeXperiaactivepressuresensor

Acoupleofweeksago,SonyEricssonannouncedthenewXperiaactiveacompactAndroid smartphonedesignedforconsumerswithanactivelifestyle.AtrulyuniquefeatureoftheXperia activeliesinitspressuresensorforbarometricmeasuring.Developerscanusethissensorinapps,by accessingitthroughtheAndroidsensorAPI. Thistutorialprovidessometipsandcodeexamplestogetyourapptoworkwiththepressuresensor. Thepressuresensorcanbeusedtogeneratedatainputforappssuchasweatherlogs,barometric appsorsimilar.Inthistutorial,youwilllearnhowanappcanmakeuseofthepressuresensor.Thisis easilydoneinyourAndroiddevelopmentenvironment. Learningthebasics Inthefollowingsection,wewilldescribehowtocreateasimpleappthatisreadingdatafromthe pressuresensoranddisplayingitinasimpletextview.Youcanobviouslycreatemuchmorecomplex UIsyourselftodisplaythisinformation. Firstofall,youmusthaveanactivity,tohavesomethingtodisplay.
public class PressureSensorDemo extends Activity implements SensorEventListener{

:
Asaconvenience,theactivityimplementsthesensorlistenerinterface.Yourappwillconnecttothe sensoritselfusingthenormalsensorinterface.ThiscanbedonebytheonCreate()method.
/** Called when the activity is first created. */

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); outView = (TextView) findViewById(R.id.output); // Real sensor manager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); pressureDataList = new ArrayList<PressuredataObject>();

Afterthis,yourappneedstoregisteritselfasaSensorEventListener.Inthiscase,wewilldoitby overwritingtheonResumemethod.
protected void onResume() { super.onResume(); Log.d(TAG, "onResume"); sensorManager.registerListener(this, pressureSensor, SensorManager.SENSOR_DELAY_NORMAL); }

Finally,yourapplicationwillneedtoimplementtheSensorEventListenerinterfacemethods.
@Override public void onAccuracyChanged(Sensor sensor, int arg1) { // TODO Auto-generated method stub if (sensor.equals(pressureSensor)){ Log.d(LOG_TAG,"Accuracy changed on Pressure Sensor"); } else{ Log.d(LOG_TAG,"Accuracy changed on Other Sensor, odd beahaviour"); } } @Override public void onSensorChanged(SensorEvent sensEvent) { // TODO Auto-generated method stub float [] values = sensEvent.values; StringBuilder sb = new StringBuilder("Received Values are: \n"); for (int i = 0; i < values.length; i++) { sb.append(values [i] + "\n"); } String s1 = sb.toString(); Log.d(LOG_TAG,s1); outView.setText(s1); }

Somethingalittlebitmorethenthebasics Another,andperhapsmoreusefulapproach,couldbetoletaservicelogthedatafromthepressure

sensortoacontentprovider.Youshouldprobablyconsidertakingafew(betweenfiveorten) samples,andselectthemedianvaluetominimiseimpactoftransientvalues.Transientvaluescan occursuddenly,withtemporarypeakvaluesbeingvisibleduringverysmalltimeframes,forexample whenadoorclosingwhileapressurevalueisconnected.Anotherexamplecouldbeapuffofair hittingthedetector. Asanextstep,wewillbuildasmallloggersystemwhereaservicecollectingairpressuredatais running.Theserviceistriggeredtorunfromthestartingactivityfirst,anditisthenrestartedat certainintervalsusingtheAlarmManager. Buildingaloggersystem Tostartwith,wewillimplementtheactualdatacollectionasasimpleclass,whichstartsaseparate threadbyimplementingtheRunnableinterface.Thisisdoneinordertobeabletoreceiveanumber ofcallbackstotheSensorListener. Thedatacollectingclassisinitializedandrunfromaservice.Ittakesfivesamples,insertsthemina list,andselectsthemedianvaluetobestoredinacontentprovider.Thecontentprovideriscalled fromautilityclasswhichwewillnotdescribefurtherhere,sincetherearetonsofexamplesonthe Internetonhowtocreateacontentprovider. However,whenthedatacollectingclasshaswrittentothecontentprovidersuccessfully,theAlarm Managerisnotifiedinordertosendabroadcastintentintenminutes.Itwillthenwakeupthedevice tomakesureasampleisloggedeverytenminutes.ThebroadcastintentisreceivedinaBroadcast receiver(findadescriptionofitbelow).TheserviceisstoppedusingstopSelfwhenthedata collectionisdone.Thisiswhatitlookslike:
private class DataCollector implements SensorEventListener, Runnable{ private static final String LOG_TAG = "DataCollectorthread"; private Sensor pressureSensor; private Thread thr; private ArrayList<PressuredataObject> pressureDataList = null; private int numReads; private DataCollector() { thr = new Thread(this); } public void collectData(){ thr.start(); } @Override public void run() { // TODO Auto-generated method stub SensorManager sensorManager = SensorManager)getSystemService(SENSOR_SERVICE); pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); pressureDataList = newArrayList<PressuredataObject>(); sensorManager.registerListener(this, pressureSensor, SensorManager.SENSOR_DELAY_NORMAL); while (numReads < PressureUtilities.MAXLENGTHOFLIST){ try { Thread.sleep(1000); } catch (InterruptedException e) {

System.out.println("Timeout " + numReads); } sensorManager.unregisterListener(this); PressuredataObject pdo = PressureUtilities.selectMedianValue(pressureDataList); if (PressureUtilities.insertPressureObjectToDB(PressureSensorService.this,pdo) != -1){ //If database is not full set a new time next time to take sample. AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); Intent it = new Intent("com.sonyericsson.examples.pressuresensor.sendbroadcast"); PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 5, it, PendingIntent.FLAG_CANCEL_CURRENT ); long now = System.currentTimeMillis(); long alarmTime = now + (1000 * 60 * 10); //Delay alarm 5 seconds, 10 minutes alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi); //Repeat once every minute } else{ Log.v(LOG_TAG, "Database is full"); } wake_lock.release(); stopSelf(); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } } @Override public void onSensorChanged(SensorEvent sensEvent) { // TODO Auto-generated method stub float [] values = sensEvent.values; PressureUtilities.insertPressureObjectToList(new PressuredataObject(values[0], DateFormat.getTimeFormat(getApplicationContext()).format( Calendar.getInstance().getTime())),pressureDataList ); Log.d(LOG_TAG,"Received and stored event" + numReads); numReads++; } }

Nowyouhavetomakeyourserviceinitiateandrunthedatacollection.Thisisdonebyinitiatinga newinstanceofDataCollectorclassandorderingittocollectdataatreceptionofthe onStartCommandmethod.

public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wake_lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PressureData"); wake_lock.acquire(); DataCollector dataCollector = new DataCollector(); dataCollector.collectData(); return startId; }

Asyoucansee,theserviceacquiresapartialwakelockwhenitisstarted.Thewakelockisreleased whentheservicetaskisfinished.Ifyouhaveaservicehandlingmorethanonetask,taskbranching shouldbeconsidered.Inthisexample,theBroadcastreceiverdoesnotplayaverybigrole.Basically itonlystartstheservice.


public class PressureSensorBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context ctxt, Intent intent) { // TODO Auto-generated method stub PowerManager pm = (PowerManager) ctxt.getSystemService(Context.POWER_SERVICE); WakeLock wake_lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PressureData"); wake_lock.acquire(); Intent serviceIntent = new Intent(ctxt, PressureSensorService.class); ctxt.startService(serviceIntent); wake_lock.release(); } }

Pleasenotethatthebroadcastreceiverisrunningwithinawakelock.Whatyouneedtodo,istoset upthemanifestfiletohandletheservice,broadcastreceiver,contentprovider.Also,dontforgetthe permissions! Example:


<manifest xmlns:android="http://schemas.android.com/apk/res/android" <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

<application android:icon="@drawable/icon" android:label="@string/app_name"> : <provider android:name=".db.PressureSensorDataProvider" android:authorities="com.sonyericsson.developerworld.example.pressuresensor .db" /> <receiver android:name=".PressureSensorBroadcastReceiver"> <intent-filter> <action android:name="com.sonyericsson.examples.pressuresensor.sendbroadcast" /> </intent-filter> </receiver> <service android:name ="PressureSensorService"> <intent-filter> <action android:name = ".PressureSensorService"/> </intent-filter> </service> </application> </manifest>

IfyouwanttolearnmoreabouttheAlarmManager,checkoutAndroidsAlarmManagerreferences. YoucanalsofindthisAlarmManagertutorialandotherresourcesontheInternet. Nowyouneedtofindawaytodisplayyourdata.However,weleavethisuptoyousincethereareso manywaystodothis.Butwedidsometesttodrawthevaluestothecanvasofaview,withsome adjustmentstomakeagraphdisplayvalueswithinafairvaluerange.Onethingtokeepinmindwhile doingthis,isthatnormalairpressuremostoftenlieswithin980~1030mBarorsoonsealevel(1 mBaris1hPa). Verifyingyourpressuresensorapplication Now,havingcreatedanappthatmakesuseofthepressuresensor,youareobviouslyinterestedin verifyingitall.ThebestwaytoverifyyourapplicationisofcoursetouseanXperiaactivedevice. Butasyoumightknow,Xperiaactiveisstillnotavailableinstores.Butuntilthen,thereisawayto dosomeverificationanyhowwithabitoftweakinginyourcode! Normallyyourtypicalappconsistsofatleasttwoparts.Onepartthatcollectsdata,andonelogical partthatdisplaysthedata.Inthiscase,itistrickytoverifythecollectionofdata,butyoucanverify howthedataisdisplayed.Whatyoucando,istofeedthedatausinganothersensor,perhapsthe accelerometer,andadjustthevaluestotheappropriateairpressure.Youcanthenusethisdataas input.Sincetheaccelerometertendstogivevaluesbetween+10to10,itisroughlyamatterof adding1013tothesensorvaluetogetappropriatevalues. Whatappscanyoucreateusingthepressuresensor? Wethinkitisgoingtobereallyinterestingtoseewhatkindofappsthatwillmakeuseofthissensor. Whenbrainstorming,wecouldforexampleimagineacrowdsourceweatherdatacollectionservice, whereuserssendinbarometricdatatoacentralserver(usingtextmessages,emailetc)within certaintimeintervals.

Anothercoolideaistousethepressuresensortocalculatealtitude,forexample,changesinpressure relativetothealtitude.Belowisaknownformuladescribinghowtocalculatethealtitude.

PressuretoAltitudeConversion(Troposphere) 1976USStandardAtmosphereisbasedontheassumptions: ZeroaltitudepressureP0=101325[Pa](=1013.25mbar) ZeroaltitudetemperatureT0=288.15K TemperaturegradientTgradient=6.5/1000[K/m]inthetroposphere Temperatureinthestratosphere=56.46C RisthespecificgasconstantR=R*/M0R=287.052[J/(K*kg)] 100Pa=1mbar

Analtitudechangeof8metreswillroughlygivea1mBardifference.Athigheraltitudes,thepressure willbelower.Thiscouldforexamplebereallyinterestinginworkoutsessions.Incombinationwith theGPS,someinterestingservicescanprobablybecreatedthisisonlylimitedbyyourcreativity! Ifyouwanttomoreaboutpressure,checkoutthemathematicsanddatainWikipediasAtmospheric pressurearticle.

You might also like