ruby, sl4a, bluetooth és a hangerő

 ( andrasf | 2013. június 27., csütörtök - 21:59 )

Néha szeretek zenére elaludni, vagy legalábbis ha elalszok miközben szól a zene, akkor nem kelni föl hogy kikapcsoljam.

A hétköznapokban az első probléma az, hogy mindig nyugtalan vagyok az ébresztőórát illetően. Ha egész éjjel szól a zene akkor vajon fölébredek rá? A válasz valószínűleg igen, mert a zene nagyon halkan szól, de azért jobb a biztonság :)

A következő probléma az, hogy ha elindítok valamilyen rádiót (pl. stereomood), és olyan szám jön ami nagyon nem tetszik, akkor kapcsolgatni szeretném. Ha túl halk/hangos, akkor pedig állítani a hangerőt. Ez laptopon kényelmetlen, de mobilon egész jó.

Hangszórónak ideiglenesen egy Nokia Play 360 van, ez egy Lumiához járt ingyen, egész jól szól. Bluetooth-on csatlakozik a telefonhoz, ami azt eredményezi, hogy az ébresztőóra is ezen szól.

Ez viszont már nagyon nem jó, mert így tényleg le lehet halkítani az ébresztőórát. Ráadásul a jó minőségben megszólaló ébresztőóra-dallamok tapasztalataim szerint altató hatásúak. A lényeg, hogy az éjszaka folyamán automatikusan ki kellene kapcsolni a zenét és a bluetooth-ot.

Nézegettem a Taskert és társait, de véletlenül ráakadtam a Taskbomb-ra, amihez van egy sl4a script indító, amivel különféle nyelveken írhatunk scripteket Androidra (vótmá), és kapunk hozzá egy kisebb API-t.

Gondoltam ez jópofa, szóval kipróbálom. Annyi volt a célom, hogy:
- ha be van kapcsolva a bluetooth, kapcsoljuk ki
- ha fut a stereomood, lőjük ki

Az első problémára megoldás a BluetoothFacade.checkBluetoothState illetve BluetoothFacade.toggleBluetoothState.
A másodikra pedig - úgy hittem - megoldás az ApplicationManagerFacade.getRunningPackages illetve az ApplicationManagerFacade.forceStopPackage.

Az "úgy hittem" azt jelenti, hogy a getRunningPackages működik, a forceStopPackage viszont nem csinál semmit. Illetve lehet hogy csinál, és az a normális, hogy fut tovább az app, erre még nem jöttem rá.

Oké, akkor halkítsuk le 0-ra a hangerőt. A SettingsFacade.setMediaVolume működik, viszont értelemszerűen ha bluetooth-on szól a zene, akkor a bluetooth hangerejét fogja csökkenteni, aztán a bluetooth kikapcsolása után üvölteni fog a telefonból.

Meg kéne várni, amíg a telefon hangszórója bekapcsol.

Több lehetőség van:
- várok x másodpercet aztán lehalkítom a hangerőt, de a telefon hangszóró bekapcsolása és a lehalkítás között ilyenkor megszólal a zene
- x másodpercen át sűrűn 0-ra állítom a hangerőt, aztán csak összejön
- nézek valami event-et amire várhatok

Az utolsóra szavaztam, szóval elkezdtem nézegetni. Az EventFacade.eventRegisterForBroadcast lehetőséget ad hogy feliratkozzunk broadcast-olt Intent-ekre, aztán az eventWait megvárja egy opcionális timeout-tal. Több lehetőségünk is van, mint az bluetooth-nál és az audio output-nál olvasható.

Esetünkben például:
- android.media.AUDIO_BECOMING_NOISY - mindjárt meg fog szólalni a telefon hangszórója
- android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED - a bluetooth Advanced Audio Distribution Profile kapcsolati állapota megváltozik
- android.bluetooth.adapter.action.STATE_CHANGED - a bluetooth adapter állapota megváltozik

Kipróbáltam őket, nekem az android.bluetooth.adapter.action.STATE_CHANGED jött meg utoljára, abból is a második, a STATE_TURNING_OFF (13) utáni STATE_OFF (10). Megjegyzem egy kicsit bugosnak tűnik ez a rész, az eventWait által visszaadott érték egy hash, aminek a result kulcsa tartalmaz egy másik hash-t, amiben van egy data kulcs, ami egy JSON string, és ebben lenne benne az új állapot vagy mi. Nem tudom hogy ez szándékos-e, de én inkább csak úgy vártam kettőt.

Sajnos így sem koronázta siker az erőfeszítéseimet, mivel még ez után is esetleges, hogy a bluetooth kimenetet vagy a speakert fogom-e lehalkítani. Szóval tettem bele egy sleep-et is:

require 'android'
def time
  Time.now.strftime('%H:%M:%S')
end
android = Android.new
bluetooth = android.checkBluetoothState
if bluetooth['result'] == true
  android.notify 'Bluetooth OFF', "Turned off @#{time}"
  android.eventRegisterForBroadcast 'android.bluetooth.adapter.action.STATE_CHANGED'
  android.toggleBluetoothState false, false
  2.times do
    ev = android.eventWait
  end
  sleep 0.1
end
volume = android.getMediaVolume
if volume['result'] > 0
  android.notify 'Volume OFF', "Muted @#{time}"
  android.setMediaVolume 0
end

Azt hiszem hamarosan jön az Android SDK telepítése. Vérbosszút esküdtem a stereomood ellen. Így vagy úgy, az a process meg lesz ölve.

(De az se lenne rossz, ha megmondhatnám hogy melyik kimenetet akarom lehalkítani, vagy legalább ellenőrizhetném, hogy be van-e kapcsolva a speaker.)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Ez ugyan egészen más irányból közelíti a dolgot, de esetleg nézz rá a Modus Operandi (*) -ra, kismillió pluginje van, lehet hogy megoldható vele a problémád (nem tudom, csak tegnap véletlenül épp szembejött, és kicsit deja vu érzésem volt, amikor elkezdtem olvasni a bejegyzésedet.)

(*) https://play.google.com/store/apps/details?id=org.azasoft.mo

A Tasker-t szokták dícsérni: https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm

De így érdekesebb ahogy én csináltam :)

Közben megnéztem ezt a MO-t, sajnos a te problémádra nem ad megoldást.

Szerintem ez a llama-val is megoldhato. Hangerot profilhoz tudsz kotni, es ezen keresztul allitani. BT kihangositasra most nem emlekszem (nekem nincs, cegnel teszteltem csak ilyesmit), de valoszinuleg lehet rajta keresztul triggerelni.
Idozites is van termeszetesen.

--
The programmers of tomorrow are the wizards of the future. You know, you're going to look like you have magic powers compared to everybody else. -Gabe Newell