From 0c45351c5a87eee41a246d7c6385b01cba79c31d Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 16:06:35 -0500 Subject: [PATCH 1/9] Create wrapper function for unregistering baby monitor service This will eventually be called in multiple places --- src/protect/babymonitor/MonitorActivity.java | 23 ++++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/protect/babymonitor/MonitorActivity.java b/src/protect/babymonitor/MonitorActivity.java index ba41b1f..ac5a2e4 100644 --- a/src/protect/babymonitor/MonitorActivity.java +++ b/src/protect/babymonitor/MonitorActivity.java @@ -152,13 +152,7 @@ public class MonitorActivity extends Activity { Log.i(TAG, "Baby monitor stop"); - if(_registrationListener != null) - { - Log.i(TAG, "Unregistering monitoring service"); - - _nsdManager.unregisterService(_registrationListener); - _registrationListener = null; - } + unregisterService(); if(_serviceThread != null) { @@ -249,4 +243,19 @@ public class MonitorActivity extends Activity _nsdManager.registerService( serviceInfo, NsdManager.PROTOCOL_DNS_SD, _registrationListener); } + + /** + * Uhregistered the service and assigns the listener + * to null. + */ + void unregisterService() + { + if(_registrationListener != null) + { + Log.i(TAG, "Unregistering monitoring service"); + + _nsdManager.unregisterService(_registrationListener); + _registrationListener = null; + } + } } From 375242d6fb9252999ae749b419a704737b8a18bf Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 16:08:59 -0500 Subject: [PATCH 2/9] Cleanup AudioRecord if socket throws an exception Previously an IOException would prevent the AudioRecord from being cleaned up. --- src/protect/babymonitor/MonitorActivity.java | 30 ++++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/protect/babymonitor/MonitorActivity.java b/src/protect/babymonitor/MonitorActivity.java index ac5a2e4..b3cdd86 100644 --- a/src/protect/babymonitor/MonitorActivity.java +++ b/src/protect/babymonitor/MonitorActivity.java @@ -67,21 +67,27 @@ public class MonitorActivity extends Activity audioEncoding, bufferSize); byte[] buffer = new byte[bufferSize*2]; - audioRecord.startRecording(); - OutputStream out = socket.getOutputStream(); - - socket.setSendBufferSize(bufferSize); - Log.d(TAG, "Socket send buffer size: " + socket.getSendBufferSize()); - - while (socket.isConnected() && Thread.currentThread().isInterrupted() == false) + try { - int read = audioRecord.read(buffer, 0, bufferSize); - out.write(buffer, 0, read); - } + audioRecord.startRecording(); - socket.close(); - audioRecord.stop(); + OutputStream out = socket.getOutputStream(); + + socket.setSendBufferSize(bufferSize); + Log.d(TAG, "Socket send buffer size: " + socket.getSendBufferSize()); + + while (socket.isConnected() && Thread.currentThread().isInterrupted() == false) + { + int read = audioRecord.read(buffer, 0, bufferSize); + out.write(buffer, 0, read); + } + } + finally + { + audioRecord.stop(); + socket.close(); + } } @Override From c25b0fdeba6aacb584b1ead4c842b47aca448db4 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 16:12:49 -0500 Subject: [PATCH 3/9] Allow child device to establish new connection after parent disconnects Previously the monitor activity would only support one connection, after which the activity would need to be restarted. With this change, if a connection is established with a parent device but is eventually disconnected the child device will begin advertising again. Note that because the child device can only support one connection at a time currently, after the connection is established it will now stop advertising. When a connection is lost and advertising starts again, it may end up advertising as another service. E.g. ProtectBabyMonitor (2) instead of ProtectBabyMonitor --- src/protect/babymonitor/MonitorActivity.java | 95 +++++++++++--------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/src/protect/babymonitor/MonitorActivity.java b/src/protect/babymonitor/MonitorActivity.java index b3cdd86..8b2ac99 100644 --- a/src/protect/babymonitor/MonitorActivity.java +++ b/src/protect/babymonitor/MonitorActivity.java @@ -42,7 +42,6 @@ public class MonitorActivity extends Activity NsdManager.RegistrationListener _registrationListener; - ServerSocket _serverSocket; Thread _serviceThread; private void serviceConnection(Socket socket) throws IOException @@ -86,7 +85,6 @@ public class MonitorActivity extends Activity finally { audioRecord.stop(); - socket.close(); } } @@ -100,57 +98,70 @@ public class MonitorActivity extends Activity super.onCreate(savedInstanceState); setContentView(R.layout.activity_monitor); - try + _serviceThread = new Thread(new Runnable() { - // Initialize a server socket on the next available port. - _serverSocket = new ServerSocket(0); - - // Store the chosen port. - int localPort = _serverSocket.getLocalPort(); - - registerService(localPort); - - _serviceThread = new Thread(new Runnable() + @Override + public void run() { - @Override - public void run() + while(Thread.currentThread().isInterrupted() == false) { - try - { - Socket socket = _serverSocket.accept(); - serviceConnection(socket); - } - catch (IOException e) - { - Log.e(TAG, "Failed when serving connection", e); - } + ServerSocket serverSocket = null; try { - _serverSocket.close(); - } - catch (IOException e) - { + // Initialize a server socket on the next available port. + serverSocket = new ServerSocket(0); - } + // Store the chosen port. + int localPort = serverSocket.getLocalPort(); - MonitorActivity.this.runOnUiThread(new Runnable() - { - @Override - public void run() + // Register the service so that parent devices can + // locate the child device + registerService(localPort); + + // Wait for a parent to find us and connect + Socket socket = serverSocket.accept(); + Log.i(TAG, "Connection from parent device received"); + + // We now have a client connection. + // Unregister so no other clients will + // attempt to connect + serverSocket.close(); + serverSocket = null; + unregisterService(); + + try { - final TextView statusText = (TextView) findViewById(R.id.textStatus); - statusText.setText(R.string.stopped); + serviceConnection(socket); } - }); + finally + { + socket.close(); + } + } + catch(IOException e) + { + Log.e(TAG, "Connection failed", e); + } + + // If an exception was thrown before the connection + // could be closed, clean it up + if(serverSocket != null) + { + try + { + serverSocket.close(); + } + catch (IOException e) + { + Log.e(TAG, "Failed to close stray connection", e); + } + serverSocket = null; + } } - }); - _serviceThread.start(); - } - catch (IOException e) - { - Log.e(TAG, "Failed to create server socket", e); - } + } + }); + _serviceThread.start(); } @Override From 6dd26b70fe36243a9259d9f088afdf69fafd6e43 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 16:24:06 -0500 Subject: [PATCH 4/9] improve logging for service discovery --- src/protect/babymonitor/DiscoverActivity.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/protect/babymonitor/DiscoverActivity.java b/src/protect/babymonitor/DiscoverActivity.java index e4cb665..d439c7d 100644 --- a/src/protect/babymonitor/DiscoverActivity.java +++ b/src/protect/babymonitor/DiscoverActivity.java @@ -99,13 +99,13 @@ public class DiscoverActivity extends Activity public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { // Called when the resolve fails. Use the error code to debug. - Log.e(TAG, "Resolve failed" + errorCode); + Log.e(TAG, "Resolve failed: error " + errorCode + " for service: " + serviceInfo); } @Override public void onServiceResolved(final NsdServiceInfo serviceInfo) { - Log.e(TAG, "Resolve Succeeded. " + serviceInfo); + Log.i(TAG, "Resolve Succeeded: " + serviceInfo); DiscoverActivity.this.runOnUiThread(new Runnable() { @@ -159,7 +159,7 @@ public class DiscoverActivity extends Activity { // When the network service is no longer available. // Internal bookkeeping code goes here. - Log.e(TAG, "service lost" + service); + Log.e(TAG, "Service lost: " + service); } @Override @@ -171,14 +171,14 @@ public class DiscoverActivity extends Activity @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { - Log.e(TAG, "Discovery failed: Error code:" + errorCode); + Log.e(TAG, "Discovery failed: Error code: " + errorCode); nsdManager.stopServiceDiscovery(this); } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { - Log.e(TAG, "Discovery failed: Error code:" + errorCode); + Log.e(TAG, "Discovery failed: Error code: " + errorCode); nsdManager.stopServiceDiscovery(this); } }; From 0d829708c7909acdb30baa56e8ed43561ab4e2b6 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 17:11:58 -0500 Subject: [PATCH 5/9] Only post message if connection to child was lost If the connection to the child was intentionally severed, do not post a "disconnected" message, as the activity is likely closing. --- src/protect/babymonitor/ListenActivity.java | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/protect/babymonitor/ListenActivity.java b/src/protect/babymonitor/ListenActivity.java index 0e1b66e..0ad04a3 100644 --- a/src/protect/babymonitor/ListenActivity.java +++ b/src/protect/babymonitor/ListenActivity.java @@ -139,18 +139,22 @@ public class ListenActivity extends Activity Log.e(TAG, "Failed to stream audio", e); } - ListenActivity.this.runOnUiThread(new Runnable() + if(Thread.currentThread().isInterrupted() == false) { - @Override - public void run() - { - final TextView connectedText = (TextView) findViewById(R.id.connectedTo); - connectedText.setText(""); - final TextView statusText = (TextView) findViewById(R.id.textStatus); - statusText.setText(R.string.disconnected); - } - }); + ListenActivity.this.runOnUiThread(new Runnable() + { + @Override + public void run() + { + final TextView connectedText = (TextView) findViewById(R.id.connectedTo); + connectedText.setText(""); + + final TextView statusText = (TextView) findViewById(R.id.textStatus); + statusText.setText(R.string.disconnected); + } + }); + } } }); From e35126096f790d6e8a23855107f10d59cd2ef87a Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 17:13:34 -0500 Subject: [PATCH 6/9] Play audio alert if child is disconnected If the child device disconnects unexpectedly, alert the user, in case they were not expecting the disconnect. The audio file being played is originally from here: https://freesound.org/people/pan14/sounds/263655/ --- README.md | 2 ++ res/raw/upward_beep_chromatic_fifths.ogg | Bin 0 -> 6784 bytes src/protect/babymonitor/ListenActivity.java | 28 ++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 res/raw/upward_beep_chromatic_fifths.ogg diff --git a/README.md b/README.md index bc0bd9c..c5c95b5 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,5 @@ proposed changed. App icon originals from [WPZOOM](http://www.wpzoom.com/wpzoom/new-freebie-wpzoom-developer-icon-set-154-free-icons) and formatted using [Android Asset Studio](https://romannurik.github.io/AndroidAssetStudio/index.html). + +Audio file originals from [freesound](https://freesound.org). diff --git a/res/raw/upward_beep_chromatic_fifths.ogg b/res/raw/upward_beep_chromatic_fifths.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bcc41e8f1e644c5c076667133ab2bffc90e0bf14 GIT binary patch literal 6784 zcmahtdpwlS*RyM}B37ZztyL?#C|1NutXr`WmX%BEnj)cMD__x;bxD#WB&4#U+>5Ah zQn?h8a#`iBLI_1sO7HBde!utq=bg_y&vTwL=bV{2bIzGFW3z9cJwSrr#r3|i0S_!V zJjy~SB8~(d_VNqnArP$lybk~@Jp}(-iLl{u{w+LCUW>)%*FVIae*ITDDX=6)9kx38 z9rWF3b9f)_fS;EmUpUSZr=>~K(Ijc=;0QyP*?%jMCk+c9)1ZI=pTLlkr3u6`?T(&9g{+Qdrol)RReYm;(t zqEb$_Nvtd3WNRWF@EBr@k4drPjL}ML<*iOhkt$mu6ibFUKOPQa^5d4Y;&>`2I59>YzdRf^vD7-B*yDl*hUJGN9Ea%)d_K@YBeim*eD%B{Hb@E zPun9!O=8m{Ep_H)+53!-$t?AOH?~NO6f%B_Wp6WvBM>52O0k=a^JLkoWb_&~PJ53u zNCY7J8X@i)VHrlYY#De80ES{G)o@7u*?IYArShWa<<5d|eE=HLS;Xa7B)qdo!aFA^ z^Xu^Go9azv{Hn!gw*bJ_PR#s}lrW!f4*=+Fy*Q3j9LG0qBsKxfjxIm~762&Njkc-1 z!S-ac7Y=l8ML_p|Ro4`s)qHlSL(D6`z4=11ngXkZ`0D_N!IF&AtY!UCG7C!;za~;h z?$3Ce?JS;7EhQ^tSd@n*U5=|Fk7NY5JR8m+wLs`vhO<~Yq#Mbo&30b41gVsUwx+A{ zaEDqxcw|V{Luh?rXkz-=atH|)`X!|AD20$kRVeN94jwL;CyM_XtNS3Iv6A`N0N)?XsTmg-GD3Bd43cqK0PSX}k> z2+v_#U4oknQxl9w3sRpFaq7Rxcbc?(%pfm2W3o`1dFj#`@QvW3d2aPWVd0e>3_9G4xp6gUq4H%lQC5QdNF z)z(C51VsvflVY@G#HeJi7UD=Et&uz|?-fVBk>TA!CS)czl2tMg+I!3aMga;xwej-1KnE6y2F9) zEMrYiQMTS>Z7oH&UujO4rrW1j)60EcXa~G@p!dqqJ1Tr!zlQHhVfJpae$D%ZtxWjK zs0ipy{VR&jb)a`|hOIhwAq+dZk292fgyGDk@9GSPk~{3JUrW>JDfHJJKJ*l(dkDSP zk@1>KckT@D?u>Hp41b(=^Il+MQPHikf`zh;3->;bCtJ2z@dngkW=FT)RUTl^3~*g( z&XuNjq?p??p_FiUrq64x*-NH5{h|-A%ZomYqdvRtLY4sfk?{Ty1|yZpaN6rS7uCjO zGA{b`@A7e;^ICD68Wab3cN>-!uM^u|U82tD-h8jxI*r*oDrY*V8?D`TCjiRp4Pm&a zGJAc;@7X%g8M}O5&(U{%4Tpmm{2JbmrE}+?%A-3{GCk+QIg_Fn=@n6M1S4qy45x^< zqd%&(LYS_Qx3sys$l(5=kZ42b^Fs0fAgu@jQPBlxFoXhFc7~~yajaA%3+$r`s-|qH-4INA&IQQN#-{+lT|Y#VF-nR&PAPA=R{Ufj!d8mD{+#jR>~Z#scPxP zWG~pz<#M2^E-jeAsY{|BQ06$fT9GTT!3n(1RrsBA%4szJi@`J~%14~43Pn+=BseN4 zO5B7BMcGr~sJzsO9ZuB!rBKukQl~BL3~bmzB|%YvrSCh9eK+K+@FpnN%Xk+RmdlzF zmpbo|@h*J8>s+}$iF%gT`PnKM4tJKmPj@M(s_XI(sQQu~+?rqRVsBN&8&#E{bMWMY z$W}P>I$LUdVY!QIJUQlf=W*pwlz-`0*Z@WCpz2g${S$P)rn}sN4gUK}htq?nNW)$B z{yKND{;&@hC~COV8)iKM;xIg{Pd*9#9?A22loFLBbk#VPG?Jr@CJkpK$B{;GIW*F+ zJe#I9f=f=K@gUkVPEHcd|7tRgw!aYiJ(B15a@xu=!q9D%LEn5XWc|B=0Kha#7-S>m9JlKcWkuEb zqk@SWTw7xcrAQ3iN;w!B6~;#FL70|kUKNv)En5L%p{=6N!!7b`GH;*cL7e0je{-|{ zWNH5k5(M)$dSKqDE1OuVN4ct`hG0RVHCRsCVKIFXqE0+n=xTB@)RbpD3C+oAciC|< z7(=zpFYody$cVJ1Q48y2y`fEYx)hXlrf-3EE8|~4?vkhaZK!t&Zh0`5Nb@Ikx&%)> zNbU40&>888#5}$uG2xybwpD@_Erb=)+$ek(b%>TZzhlAr2cuCGhB=ZZRhC^;^q- za7ll0G}<2=T&mx6$uvutg39YbQ^gvqtftF&UKd%V$l}{C1puj9NBh&6#?7RC`ATR~ zUcL#H7)>&5#N`t0mnlUl1;;5Nuhu#4sDm3j1_jVi1)3CFO#vV#jxiKAR-qic1G8I` zJ<%50>Zlmui$Ibj4e;v;?~s(JI`cPmf+4F1PHmjj$CzMFVQPoKGK-o=BDw~jqE&hZ zP?^_g!n}h7@BlypfCfQ~ z0h5&91%*QKA!vsHh2o!jP^{#oM&7B1hd)~_DXAxCx-ix03b96`Qr_ zj%G$yviS9KJ54QY71pd%#Tt^Rdn`s~LI zwa;nTHMl<;S@ln-VRS#LX-YuU(68^wWuQGWDGP}=)b5XK<13HPQ3HM%ASymzIe;GsH+?7vstD>@zC3yzarWbEB-`NOn_`%H^yXe-wB>_;B-@Fk5C0yputhv6hsRu`6BmI^qGb5X2#{2G3 zN=d69Z$fw=dxkppKOihC@&2(!fCUt1)&qq8XJt9iJkWvNA~fs4-6jZ+?0({QltacU z(8@auXRk?lxHoXcC}2SO!yAmuvWde2JnCD5U3Ys@0SZhm*l_&uz1wcn5brz)D!({~ zi?e9l(^ep8fA^)Vb$75Q#_IR}*j7c)yc^ZLO>p)Afm|Gi*xgoqPc2D%{WX%EP2fK- z+#{|8a%YOW4eDlW_GNC2Ao|OQxcKet)_4@AcjWfIurn{j?d=Uf{B4hT#BO1%*wTcj zcXC%xDip5z6x+bWp#VeYz;WRh%+QJH$FA|eID7S21K%#SE}ym8 z=kdqxBs-2}J=v>a9#-9-ib|G~5Csl`X<(5s`8H-i0(Xw=#=eUU%Ofi0tQ=i~6rHu{ zpkjXO*tcbwb)Z|TBExwMB!&~q}Ou9q&12nu!uI?e1y{!v1w)B(2R0>{79bexU|L%1+|0( zRK3NuXINztwj^G8hu)0j*8I=|_bVP2a!RblfxNQD_tVRDq6UMR|CZ_ZxnEQ~zp;3; z?cBGsgu2#?629l%D=lS&pWY--t=ziv(6ynQ#hT-rpS`d+@%|(CQ$$0oRiMPyo%!;2 zLUgpAH{Qtk{7t{_O3^>nySm)JR7`x{A9CXT%xC%Yp9X_*cjOp;;Fo(T`@g@&% z5RmfsE>y@N1~9Bo#db#6U+dlqJvT+TIrl}zuxfD6ivo{{Huj_sUD}7Ono~h&RNs*?}jsHNyauU;qNgi>;g}3%A1Y!7qpi(B-*tb$4S^ zKa7~N$ZW)lJd^^kC}D~B5wgbZr`LE%ym)@>tqY7Sm6v4T9wCYXND6>OW3Xig-Dog^ zJcbyh>L@i9?_LAI7{Zo?RP<#bWgO=-f0{z}BR3TKf(GsEcO$@<(9vWdgb+&NU&XQJ zkcknNXixQ5_mLiI30FO(0tp%Ah0}ZHCck7og{hr3?&J#;3ym%T?Op`;%V`bU$G$%R zD2$hET-l_D9CEG6M$qm-FbY!>+*IgNUvPEWD#i5S9uchj317VH*hi~5F zD=&D=-@cIjG5b)0@0x~=P_5LU4{u0;x6(upysxm&E#4v{`f}F1yDU|B!DGz3+(=Q79*V#9Tt%gcOmZidzKds*g4KwxGdE@UPvs0cQOt@s=ev27^i-4|@^s2l08p3j8!gpk)*-CkJn^D7aeB z$M#Op{NghfE)X|$)zA@mGc%Ma0Q0#4gY!w(70zV`4A<5tWlSUmxSxOXVxoI3)~S3= z_@0*ZSj)JLp|ed^#$hZGOp-#`i&X~`_mg7|Y@Zw4vK%-(M#7+xn>t`rJNZLr$ko=( zKdudMg9_j=4Fz4+gLgy5s-?LZg->cQKrWJSZ$W>>gpmI@04glu%L<7#Pt+8ALB>g0 z7&yM~m=^XIH_{8rO+O@?ZB)pHiWY)a8O^)vj#ZN$>)nX*2M!4P!n5lrRtD9EU_d|y zJFKok00wzTyyLt=L+XHT0Xd^K;*7BtS4?`ohW5iNw3l6g?7GysX21xq0(uQBigEJ$=LF zZ{NT55ODEJ;I4VJO7m-@QJ#%mJJtFV2nZSexUvSw!+3}kLt&wEOV)CXgN{EO3)P6O zJU8`}RA1TM0LylyAp>Lst(s@OF+w$Np0*-g8k(ZnFv5RbkdP>yn{+#W& zMUjOtxJJt!QC2L8OcNxDtY2Mv{}8CDy09i?IkV`gFVes@B@A>S!2S~ecx^rC#(E%@ zw%iu<5x&ky6rXPE*7>#}>`MBOb}MOLP0T95dIsIY()J_}u+)SxE|JoDe3x9Jt|O>v z;vE>~o^R_q`L`671f(FJ{lTi2G1GQ?KO-Hlh&82o25nR6 de) Date: Mon, 28 Dec 2015 17:13:58 -0500 Subject: [PATCH 7/9] Explicitly list some methods private These methods are not needed outside of this class --- src/protect/babymonitor/MonitorActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protect/babymonitor/MonitorActivity.java b/src/protect/babymonitor/MonitorActivity.java index 8b2ac99..52895bb 100644 --- a/src/protect/babymonitor/MonitorActivity.java +++ b/src/protect/babymonitor/MonitorActivity.java @@ -201,7 +201,7 @@ public class MonitorActivity extends Activity return super.onOptionsItemSelected(item); } - public void registerService(int port) + private void registerService(int port) { NsdServiceInfo serviceInfo = new NsdServiceInfo(); serviceInfo.setServiceName("ProtectBabyMonitor"); @@ -265,7 +265,7 @@ public class MonitorActivity extends Activity * Uhregistered the service and assigns the listener * to null. */ - void unregisterService() + private void unregisterService() { if(_registrationListener != null) { From cb4c48d5fb3dc41ea8fd3e52628423d75932a663 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 17:14:05 -0500 Subject: [PATCH 8/9] Remove unused import --- src/protect/babymonitor/DiscoverActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/protect/babymonitor/DiscoverActivity.java b/src/protect/babymonitor/DiscoverActivity.java index d439c7d..e625785 100644 --- a/src/protect/babymonitor/DiscoverActivity.java +++ b/src/protect/babymonitor/DiscoverActivity.java @@ -27,7 +27,6 @@ import android.view.View; import android.widget.Button; import android.widget.TableLayout; import android.widget.TableRow; -import android.widget.TextView; public class DiscoverActivity extends Activity { From c022fa8168a708dade88569fd0612c7008140670 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Mon, 28 Dec 2015 17:14:59 -0500 Subject: [PATCH 9/9] Update README.md, removing some improvements which are complete --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c5c95b5..ad8cdad 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,8 @@ The current version of _Protect Baby Monitor_ is rudimentary at best. It is capa of successfully advertising itself on the network, allows clients to connect, and streams audio. Room for improvement includes: -1. Decent UI -2. Hook into audio controls to adjust volume -3. Robust usage of the AudioTrack API -4. Handle dropped packets gracefully +1. Robust usage of the AudioTrack API +2. Handle dropped packets gracefully At the time this project was started there was no obvious open source solution for a baby monitor for Android. There are both free and paid options available for Android,