From b1c1a0cb1f9a240178b19c7d458728b372831792 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 26 May 2021 16:32:45 +0200 Subject: [PATCH] iii --- .idea/caches/build_file_checksums.ser | Bin 0 -> 605 bytes .idea/caches/gradle_models.ser | Bin 0 -> 130606 bytes .idea/codeStyles/Project.xml | 116 +++++++ .idea/compiler.xml | 8 +- .idea/gradle.xml | 4 + .idea/jarRepositories.xml | 30 ++ .idea/misc.xml | 27 +- .idea/modules.xml | 4 +- .../iconsole-android.Application.iml | 83 +++++ .../iconsole-android.android_antlib_4-14.iml | 28 ++ Application/Application.iml | 145 -------- Application/build.gradle | 2 +- Application/src/main/AndroidManifest.xml | 8 +- .../iconsole/BluetoothChatFragment.java | 174 +++++----- .../iconsole/BluetoothChatService.java | 1 + .../org/surfsite/iconsole/ChannelService.java | 2 + .../iconsole/FEChannelController.java | 316 ++++++++++++++++++ .../res/layout/fragment_bluetooth_chat.xml | 2 +- Application/src/main/res/values/strings.xml | 2 +- android_antlib_4-14/android_antlib_4-14.iml | 26 -- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- iconsole-android.iml | 7 +- 23 files changed, 716 insertions(+), 275 deletions(-) create mode 100644 .idea/caches/build_file_checksums.ser create mode 100644 .idea/caches/gradle_models.ser create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/modules/Application/iconsole-android.Application.iml create mode 100644 .idea/modules/android_antlib_4-14/iconsole-android.android_antlib_4-14.iml delete mode 100644 Application/Application.iml create mode 100644 Application/src/main/java/org/surfsite/iconsole/FEChannelController.java delete mode 100644 android_antlib_4-14/android_antlib_4-14.iml diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser new file mode 100644 index 0000000000000000000000000000000000000000..eceed3041db6c244ea46aea66f8789805afbf3b1 GIT binary patch literal 605 zcmZ4UmVvdnh`~NNKUXg?FQq6yGexf?KR>5fFEb@IQ7^qHF(oHeub?PDD>b=9F91S2 zm1gFoxMk*~I%lLNXBU^|7Q2L-Ts|(GuF1r}l-a(W(##Th_( zR`y#54~r#SWM*J;W8likPfT%3OfJbU@?_vF$tX%K&dAS6sVJ~_U;qK0atO(T9RnLk^EHEmyZ$UZYRoB8&c0^#>H8%NJlGYQ z9gPmz?xV0^2eaDL`dyR0lrRY7TQfP%UpwWuUBwYU^+>b=;-Yn&wHMLj0{$Be5tkCq*CX4t+#)VVH46w&!L)!zPxO4V*LH{BWu(VUTbvD9Fi7 jPAtjH&%@!JHk<77t(#+4_Z}*@)@b&(FJTZQ!HNn1-FDTS literal 0 HcmV?d00001 diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser new file mode 100644 index 0000000000000000000000000000000000000000..91b7e84df749168b38c493ba62727f7cd3c6a7d2 GIT binary patch literal 130606 zcmd_T3A`OenfKp!OF{?`b~hGf6D0R+eYSvxo0W?#L)V%Pa1@zpC!){oLoKPM`n#|9oEOGl$&j z>gRcC`&M<;Q&qSAN}1?c%Cz2TO=@k!>NJc=yVGg*CL4ySP0m`H(KIK!R%f57+mpS8 zwm#XOozyjbZv+3`fd87tcIWBVj$t-?iu1qGQDt;SIl8s5ey-6pwriH%&>LN?ZTD!T0y7QO>Wz~Td_+5?vA438fdZ*p%G|e?` zmO=jcgXEx-=1>NX^9)43Y~e*9a%a~<*L<$>e3rSZc%FHAb(E7=O|3nf*=buS9+q7! z?y^`KM)q6EIZHFR#Y%PZ0%Uo>NR}h`-`J?KYPWJ?YhlW%IZljA8us4KoPDuoHCTD? zRt|M*fmUmpGs%nzyG> zv%~KSc>!B^&W+3{hci8G+icrAIvrMfj|Hjb_(u z8)jQ?m|W6o_qoW%gy%=J7G_X*bK0yqW9~PbEH_q0irEj_iKaN+>&?01-J(8BQBW6; z_v`vhqkWlaxHVq=iQ-jtWu8e}#icbmlPu@Q z*Su@f;fMYB5j3*@ZRLrXi+ZNj%k0%Gt!ZRt8+InzPBJw{g9D>V# zPrs2q!8hE`+TN)9MxLbVfK<s&UTE|MBcc|1CQK^eddcqs;c>cqScd zD`zdCdbs@!uOO&-C;3(etHY*N*XGo}{G-Qz=-iv$`aQ0YDLbA22#rsmHF8b)%55O&I7Mz)2)#} zFKQ&ZfT`K;#b|XdJ;4iLg!j3uwK8@xgHeGH)sZE_oTzS?LrNAEtqKyH;IQCOf5W0e z0w~Pts!wWH8<4+C>s`irah?++ZhK$j^hl@<8|cExB;>9`kYGKrm1EW>L`3x|v5cPW zbij^D{Ik_*<3AkOlhdu%oXz_q3?5G1X`-uYV$fi0?pQ51hZWucR=9-WsW@rAi)!z- zhe_7cPP*;kwO@Jq4Xb-+HbvE6W-D2y-8F2IS7fI|IRZ_Kcd2e?v7Ki>x|XMEU7MFO zFG2Ku?t|0$-#c}y(X}@;wO)^bH!0%T=mEu`jVo%j8}_8z5l(U`(+ClA&ssG4C6?Ch z28;+q*18Q(>iK4~%L=>Qer%mLATRJ4}p&R@rf~vKu2vWr!O97VY=OG%qJ)hV*_nG|JcTtTyyP5Z&$}yzi?m`N_VxZX++eI?UFP| zX!vWgXl)h;`#i=kEMcgC=SnKz6)iGg8R2zvgh}2y&lNnH|2~fYo;b%IJRYg!{ohVu z!BZqH2(pezcKSH}FCn@lCz|a1lDappm{*>&Y~|3YZnxRc`QV)!)3@JauTAnOYiwnr zFsV*vh4tqw!TNxnq#j_^+CT&@x4=uGh*DU^RF~OLh5c07&sz3#4*NORR#@NQftr`M zASk2Ul=Eq`UhA2HZ)yO9tP@}(_Q@I|cu1US)J=UsZ<@i^9v^ru$j@M$AdrJ`c9`7` z+H`w182Pk50@+A581D&v6Np?BiSnVn$0-<=JL`BA;eRtIe}z~4uh`1T!Tc7K3Vzbq z%CX@ny`I^^=U?nqH{8u-Hk4)53Y6wr^mhE!jb?3bmh}gHABKcHp?|!K&;vS}9+wzt z2l{-JrmdX1*kfPHQK4wO21V1!19=LzTju(?HYQbUC9K_z;(Ru;{_2Fd*ieu6sQB{> zP17(9bhq(GZlVI}kB&rgjEYKSp>EcnmGA<86v%i!I$>SU*-MBlzE5~x7A)2p&mk_` z6ZrUk0s~Uc=od#6mM1M-#~giLxhJV|A9?~#Nl@j+2^e%{|5!1T!qo^9Yx-rjk`D>s zfzd4AIOj0f^lS@fga1-I=1G0TZ`ImB7;B8-6mVH?GUL+1`4)`p%ZsEEEv+4G3E-yI zUe9I<`21qD&AVfGo(*Bu~8zvmYj@j7)>_33s%R_bEiLG{FvfV zb4!WJkj&=A*nf3=8!Y9W9c%*0>hVFptvqQduk75bu~(KFo6kNV_UV0PN9+#6H<&G9 zW5fMJFrH`OB2k1{lYPw+Z6{)0|56h#ICCgSau{>2g_tZujgPbmr*62l$SLwfJ#LJM zNzp3FE1DZMoM&NXyB4`Iy&&M* z4J+JKBUo`~flb%SaNG!1I_);5_e>+u>)6U;BR08lHaHZGR&e)el%%$DVpL3Tu4OuN z)Kj)?*-E6fTc&0^$=iT>f^jg$IQUFA&9)#O>RLo7e`jk)zl_a4V8+;13Sq50f}0bI zh<$YEEhEIYuuAWl|NR(MbvIEtHi_RSvTup0^MO&D`q2AkoEv2NCEn^;Y7VIF`rhLLPk6>c2;VmrMLua)>f z2pQ4u74-TSYfa3@AH)ly#fAq<{WN$DFr2&L=x#E@qz*+1r7heJL-97FZqHffR@2rD z&BjDd<-|! zeHi-T>x%(hj5VX}bX-UP3v+Ym znAn5Ojrr)Pi^cbB36IFxql+8Ja_@OK?JX?uqB~(r|J&K>M-L0MSbKA(2*TazB2hz` z8_ta6w>)dY1B#Y*nF(t)Tb-8kZSVJTQM2O_J(-cHrZwBQ6AP2Ll@#@Yb_1&m&caNr zlT3Ug(0szZLSk%hNE$AipXk$8zYjx;a-U= zb0Y?FIH3^SNM0U?zu(=JiZCp@8pgJ6<&93F1)nXF8Np~`x-49P!5Dzleo#Pbq7gAUUGNL2O@Kd2F+&PEigmr~yIlF9b57QRW84HB-N*GA68!udAMLhRmxX8pqL1Z^l zxVj>en^O02xb^vuBT~YjPl(plEOQ1B=HDlgoDV$(>bB3-nvEWubi%zZ7NVGgNi^jb zpdUn)i_Q@Ci7h^(Y$ZGd=o7tfT@J?gEC>%NgHe37(L(Uk6wnoJ^g%%)pFN$4^4v1> zB85j#t~@uAZ(6i$xoK{!fN|lDEi5c%UbI4UzdsaK_?sU>yfwx!flxQFP{Avo=jG)B zIGjmI5nbD(A8AfhXS9apME;Rc$3lIeIoV1vG~!soE3Q@H-0An88#&xB_KUm~gOh0W z?ibff^3p^*%NF4e(te^@T-WaKNAF@Uc=m)lTMMpA&HbU7kT7_#EZ*kI1Vh8`v&XJz z5g`l}76Hp!&Q!}KR>L;MJVDs@e(^$eA*=-<9w6Ju{pi#W3*(t2nq736h(&O1^P_}^vzSR~_gL+BXZzW#GDaV~#hI2r@O(ueul4?d^2SGI!PgZZK)o-1TXPZ((n5E!$ZM2G;03kJk`XiN_dpvJ#!%y?nuH< zLzxsFf_o9YWQ4o*{qXF<{FS-WA&jdmJmZ!WC!{jm)gEAc;(`LRlhd(bpC1jbTFigX zn@I~NmB(|fj|dEtEEq8?avpw#gsUt1Z0^I)hwQ?w!IctlEF2$WKHczTzNiNtJD#_$ zD>rjF<}QD3)@*kq+Ddr_D+a<_FN2K(8T<`*yRhdq+^)kf!e<&@u$)}XtsUOr%wLfC z9l*Q&1mTGf6a}B5e_daNYTLS=P$V&20gtPfJd>UA=sV4?b+nvu7cy9*$TGwOG z16Ca&2EMaMm@%i@o15DHjukcw{=9CocP?Pkp~Xu59G-mi`DU}(*q6c3s14tZj5&`^ ztgSVjh_3s2nUxhrl1-aps?9h2-W5tEs!$CWf7JT{hHp zy&m0a3O8I{qEm3>+}33q129@RBh)-<>h)221IXgrXF``=zDFq1QEQ^aqx47Uhp_r#9HKm-!Pb) zJVv^v1;gP7?22*gper8DW#d9yYc+It?wR`%!5lPvr+IB`z<-muFN-JG^1{A@Tw}dV zoLt1LczmZ_u@6{Jz+$Bkh=@1QzQ9GZ8P3#YEe}tq`LN#^(Xi~-_p<#aZbrj?YOi?`HffCZXH!7&~4SVMsr(xYoo_HFDDZ=wQXwwJIpl0z{*qy zKt}Pf-DQ|DVrhWG`zj0#I+p3oskt@xP}Euze%3k!VTCqSdVQPlsf>c|ODMmU?GCHP z$YrM_SUHXCbbL~SJ72obx0GBk>8=8o#(~rZ6}Wk+9L3#k58sDIITB_r7=Jh^?#-^Vnrx#_g*!J>xR$q|$8m&CwH`{F;14{F8ax^5ntG zRt<|v+yWFB;W)0G9PsEW@|DT#WPywF?Hd&x*AmF@G0!8DU){z-aG&w^q%oXFnHOlB zPUqsX8l8)$0;P+A0w19`0~0jV{dm#I3bYio(eQ(V7$${ZJjbav54__1N01qzZ3T-o zH_uW(50>v{y&oU9&ay5$lqI_rbOrb#^B?n&t=K?NU)a=U@eMvM40^5jk*C>^G5Cma zx5f9d?PeRNb~n0HO*AuC61Wkn@QWn`-Lun@{gfOMGJQtDa4Ar&rj4C*b)SmI^BsK5 zk;6hE`JMwDV7wT;kzrHQO}6dREk=xXVER^gzav}bUDH_`-Y}zty94B1l5A{)0jM3f z0HzKC(QUi^3S&jUP^XmdzW>%oMcXLbgjZyEAoj9gPix<;ETfky`T zJnq&(wyA~L#(bp}|6hQ{gu&L+SbCeV;6x4>zU_8{x9zcaD&LF+&Ce(u^OD^U{_Lxq z?A?)1Ui;2BJLNUzIQfU0bm&`Uk-`tRgoJiI7O4s7w#2+6%U_l-w`1hfH=>oYM9n%m z{<+sR{u}#Cv4xB8e%{08VD^X{UjlW)Cc1SLd*BX>ScaO!yvMMu55xM7odLp&5{+0gCA!=ZtVgyIj_kcuw{_TtajV8?a#Wd1ZP!!WoE*X~D$n|54?Ga!kF z1Cglzj$c6hDa>-0m7>p_lG*+*D{hH&2i}H}^AED8=~=qyuy%=AxQvGK@IBo98tQ4e zAQdfqA#_naThh?8uif~+uOyXnVWe3!DNju)zu0u7uLuK}OVSYRj+{iZnw)PrwG6vS zU7mPVuwV7woQ54%AZ-biJC#a@v8|th2}-u6k`Td=MOCFzDSD0vwWnz0z*DyU`k%1V zX%FTZZMSn^y~pLN5Bu$x`xW1mM5ywFAp0p04OjYL zc~7Ee578Ax{qC0;vM64*6Z zQO8Jf`Hvnt;=TQf;>i+4!H4HGEo4gB6-|?3Df?=pmDdqYQDS(K<@1`PgG{COvLi-@ z8R<&Vj|!~ka;7K}>ifZN#AV%zV?2QZ`J$vS5ShCoC!7K%F9`wi|gARpOFqewU=AYo>MQ-?keBE`4wyzIsO;>gytV8BL~K&KlE|-#?4&p z<=)y8QB~pZ`n0B9R$RSPtE2 zipZ3=C!8k8QqJIrj#h+tiXOw1JxHFD)R1WeflP@J<3b5y2zmWzfnIKOv|o*s8P5rY z1Rw?}R0<9vOvBcIqlkqK*N=;QC?BLxMOEa?~WiLg`|368^N5P`=00;Z|;$&^o zVCrDU1CFGAP{a_*ZI-)O9YOs|n#Cwfl^?-Hx#FXUc(Al}vIkO^FqtD)h(QXn3?4af z-7oL>Hv5PB&DFT&t~2}P{K2Xe)3kJBKiG`&CDZNwU_s)^rkecF1WV^LIW&?Pcd<&D zNoxEu>l0j9|Mox5TR@+NzxE&-zE_Y$+m|j!s`<+d{&@y1jR4Yx8G?YNs6kJyrH+2w zK@a=_4v+W+U|19QuOt%YnHIvvk}Q4D`HDxG%##>&8p|9G>zUXIsqinllM#ci(&5vr64A zJK%n)o>6|uMTgXQ!dK{Co{h-d}SQZ3&>lo9RHGCwlbP4Ic9UG zq|wjf$>WqqjZEQ5z5;Vu0y+orNsyeKzWq^u9{7lOI{-E^M`3obDO0+hR~no+?)qWl zGnAdX&K_-W5^?{{Q#s+sLwHVM13_QUDV%~GI|P_z9`l#NF~7^_=jZnt-G&Xvc;`P& z{-0%Du=8|+$AUf1MFjltV0Y8Omru4{_>JrT@@sx9`vmvQ!ui>#3M?^~-!OIOZM^a( z%-GBHe5~3HXN2KM9?l4Z%O1uEV==*FJl~gidTfAQe8Jrj9P(s=B$<&L`Wv>HCOle! zESbd#Y*}H>yk=7eO%K3rJ8u@9QY=x6#h3z?A**Ool;@v4E$$j6Zz z^pZiz$;?=}wIDQzf+(3{@+v_{SVA3;8Ig$uFX5X^#&#|~I3f%AsWM_RXH~w}$^AH9 zY_re>XrCLLZ82`o?srAe*(r3Do7#HEz=iK|^3}Ip4dXA`wRug&R>pFZ?2zKI!(shWw?PE9tpv>8&Bj^$95yzjat!Q6Mgs8q zWG4hSv3)1t^$AbZow#`fyBqyob1XHZ-l$+f~EL{*w(9^*g}UJcx=|oPkB2xcAB$n1jySx z_H7*2+N$mASZ*kQ7#ik6Kefl^RCfgDO5mfqtqtAkxB;v{j^=tA*dP)PTqVpESMs1j z9NK!?9JZU*8?FO6f(~iz&<=19aF$6cook5{{F~R)etyvXGAv^7#sl{px#g+Fw_{`8 zG<7qXE#vqLY-dT+zZY2j~VQFk4;hDqiy&kW(SgBa?$Kw(yoe#4p2 z4Q}J%;rB54EuJtRsG|Z>{z^ZO!QOUHlRt=N@9w|~Y;D9``k|pr-pzKWuumqOu8V<* zKoGls3AyX-4PhmY?8m3f#zqh0g5VA}Y@6WQTiomuUiI8=d3(h__<%fM2s8}`#NnN5tekdk zee*wV|!$wJ7P@aK6@NIa7p=P)ThlDm0Vt_wCuBZxVs`%ia0hSc!j{!m9v@#5SB3jS(x0xzHnV5gp#oORG#dD@?C~#4*D)}lfeppHgD(T& zEXTc*(K9-`+(>*ZExqLgb2WfnT#^+Xd!YU^jm~V54-qtV7K}a0IH!YW2C51`5{-wU z3yO!Gqah-pUbuMP)^3Wn#nI@L#$V5CUclq}qXBl|=2D0FzOf7LfC_zmbdoIIsMxM% zfDxy+dBb~vD0I^a(A@6`1$Qp3{|FAE`53~Rtqu?1@Yu~ImJt|WIN8Sb$Fh+d+dhf5 z#@ZRqlrlDSFraI+S>3Uf>XOMqgm{_g(0@TWX0h}@oYQUkhiaa&_= zE#GXMJr8@A*%ap3sVI`AVmhk1e>S0O^ms0YtO(-(<{t@e_8`BuSe?19mz^vFaY~8* zrHKIdQ-#0cRIQ8Ncf&LB9TrFyQhszo%JFrHgo-WJ+3!64=4UZ6r;Ap9UAWb|*WYB= zEw5-kEdlq+P_ys8!I z1yjvc@_MOM(#mQv_%2*bun*k7#EBU>wtm^F@6?dGGc@-A5Y5u}PU1_;xn_rr&@e@| z7T1nV<^qMvUfuHDXFuyoq}_=E8OJ5dU~!*{Q6QJ`;I;=hhO+3@2c1R9T3F7p$vmzl zlh2m55{}<6OIo2=ESiOU37M6vmrFHdn^D#Bg{ofD#dqu){+4&Wm6J2&Yo7Ohr0NMF zeLB8c7R{8mtp48lEX6zU>XETmd0w!eT~lxU`%R&Yc==!%!3+!Mfmtlp%2^{MO{N8^47m$z;R7I!?-Q9|oy zY2C8n%pW`n4JhFS&WH=VT$#D?tt-M;P2P0Sxq{S)ugyu(f)X@~mSh^`LcLfhl(lR& zkIXXiYN1dyiuGEyqUZIhQPs6l)~I9>WF)t!E1v(J-N>`41Vhj-u+=s!6xgUl;-72q zeTaK~*KlfEysZ_YZEfQx4m^TkM!%P!@5IIR@jP~0Vc}ABir=#4f$C#vWOE>Os8h+Q zutM`)$fX|Tq;uHT)R z?4dtSIT@WIKX*XzVG;AD94?1P4j8ITM7~_mk+E4z3{03VjH}rotD|d8gz)YN<1UQR zkXn9F!wxYVLri>A@RMeBZ-CB4U|h4*`6<^(=R?=+w()7cDq4u1gPgWY-2 zHJt6jcZReu-5X`iU>b8F^x=RMha=$QjE(AoV^$^-3CEzw&A{kG4CgS05<7~03*1`a zeiE>7jJBK);E)l}iCo*s_@}!nxDZw+#x}gEcK!sK=Gnoj=yGK3EY41I8~*;X7&d9% zu!+6DW%)T%&$E@oLQx%LV&s9iEYi#k#s|JE1{{|z+K#=mCNb6sj5&%Wv!)i!Tmk(e zdWlN5P_5w~dELzCv}^(U`+1@Hu6+2OdGn%*mO8QtB}@=mFO^jzTgn2uM!i;0>qRY_ z&zktNpp|Rcl2*}-T(*|SA$Wlt6f8!rgbXzoHB>f7_MuUUZ>lhakT<)Aq4NJ$qF8MX zcgcH)k-UtH5YZC7z5UL#Idb*sLs4tF-^ATlX(wGNT2XB%s(78j!jSD%800M$D_9OA zecDizqOan-pS0)gP!-xU9Chr(ay_JM%qo2Qj0Zr$CnZr(>vj>0HNG`{A^6H$FV5J? zs$fii*vL6M^S3KzpCs~83V|4HsD+|xsCp%D6!C{z&6zd5XzF?u- zI}@Lk`*VdpgTUPv|LQrIjS57J;;*se+g}w$CxyQpMp=3-TUPU?UajZUvZfZ*B8FOp zf>|w8aU@}U1eng;Rv=Y^eid*pm#>*QV6JAA)GTZ&m0*loEmlp;Y8ZLFQmz}`7df&n zRrry)k;n;A08*nrO6B12qcjW^ex&l@z>iex!Efx}Z}XOFq~J%Y8V3AGrRlsR}*@AH5B+&{2M(vKHKU-^!iCySORg}wqNLG$%eRx|OriD4B6 zTSlpZxnWH;t64LbguZK18Tt8%667o7wPIE`bOTfPW(kv!no-AuZN08zg3{3SN(CG= zw6ae=HC6DDd67Q&D3ybQkJ2zy@R7=g13pr%2fi=9{r0Ox`;h`4scIPDBbBBLK3ZK8 z_@4ItKbHYMw!9KukXS3)e%;cz<7FTGef*bi!|ficqp_n9d`01iDPPoTnwrlQk|6l@R3RubLZGmo&*>GdQqE>;g{+|$%X+PpFPAm5 zptA*oidIzt=t|B*p%9QN5XpQ=ABdF7!GTC=7%C7+<--9Ysn!GHd*AxT$BVWk1w>NS zFn~xZO&5r?x+EZ0@B0S>V#poDMcZ1Ol-z=&im_%t-$S^@a5oY50pp)<=$y;EuKK(c z1?0=meC@O-R4G7KvRE)zHNB`;Fawt>=gev?S5q*M+LOiII0fk`SK z4lqfz9x$)p*H|IimJ~2aRl@)#sWe?+((00c`H$zWWy{AQ??M4gF(zbwKWpY1eK=`- z@1&1lr$!`l6p!bA@5a}NB9y`-25R_Rt>=rXnJcMqv?|srdJZ#p_^>vymYamf8&bhz zBxQn%SU4#ZYq>1Oj%B@|RdQ7sN}2}uC~x@aW@D-_By%Nw7*Z++ zhash5s4ygz4+n;%S`UWrJL>HZiLsHc+U`Q%W7lyRDBp8lIYlp)D(v4zzK-u%e9o#h zOfV)P@x~z_ktI%0F^@rOtyZoS>N%_`n>DzC=1RFrO*4v>ikgR0UO8W>Vl*4ipH#s} z=1uxwq*M+LMoPm_!AL3}4j4(b9vIiX>2GU9dy)bpscINtB$cKMMp|7G7}t#4_gR3k zwAei3(!Q#1Y9*~tX7F*1E5vwoxifUBy#e!Lck8(a&uNG>BdNp4#0xQtr zNsClrN#;`eu%uKD4ogbIP+>_b9}X-@wH_=VzDF5s4w6(g3|Nv%(}g9iE(w;u_(0($ zfaMdDV9Aci=xR9XtMFm-^l~SE;=E~;E z8s_p!^*lbVi%CFyeJVio(j*XAFXjrS4lhHaZfccUDO;^z#}M`pm8w;^BVt)bE9+Ua zmhs+96?$Y&qz^qx<>1hxGz=Abr1IfFk5ubHZ`Wa;StnYL)CiGOH4NyHO4EfNtu6_A zKfC7HY#uRm!>#yq*2N~_j^*q|=>xwbzjVvV*wGk^9);jZXB_zxQH)ZfLhMS+mCK-v zu2l-ymzS?+tMwAwyois~T0PMr=bfoQFqSp}!?IS+Ry0j7sA{2H%A3WCSy2n6N>laUC9-Vr14-nyHbM55)@Povs5%NO;|B=wQ?OJKs8${ z)(b@wp*5|p8}Qc2RqL7H%jp7;%8wxckWiTd00|Al1t6t-NC2eNdH}re^wP&f82084*tv3bM9QDLvyV8?NGwYItFsPHAHt+*Vc!dUbu3g7;>t8W#> zD1|~Z3tz;tkuT|RZz&l?vs%Y`MIl!zS2d(wO+sNhqrzC)1P}9BwNx?jm0YP8N`_uh zD{9HWr+c-I@AhJ@R9EYD17>Gp5>kaCnKS7_ky1H06e$fug(9hZI8Y?jdQklKyMH#= zDl@5S7*HgYrVB+{T@n;$ulwY~fMViq6@3nembTc0SD$a>^6Q>wV7H1NFN(o0e&i14 z1XJwymcn4s#MYE-IbXt7xN=b|)pD4Tt7MDWB6iAQbe4p{bat!wi4y!%^M$&Zt*f~* zW+$>6Y31cxs^BB@B7N{tDhCH2rD3SxBb5&ae56_r zd=I?;^KTNv2&vH^scIPDBbBBLK3ZK8_*TE;mg51wWcQi_jjm~#b(F*2MTdhQy?yHu z%)KTSKMKN4pLoZAi-ME_VX08k+1?PGVg|@)IO5F2QiX<-Vrn`zEGK##rsQ4|OPl~A zKFv#|Y9U*w$21P z8tpo}{-xjA@&8=((=%}dV!{hiG(LRfS<6LHN}&;c*J{PA<}h1Wt`)R;sjin*wOFjc z9U5NQiJph)9J82^I>E+*W|m7>+0Nl4uacn^G^2){E2V11!0|d*^RDRCtcv~D7{JD| zG*vi~xsyH|DV2l6k!A?1Sh=_h2Rx8ee-rvm{Jhbin$`T zz2OrytDCA?!VczYK`odC%-NZmnNNb?EvY~-DR}~kwX#-YJC*fvy_|(D?9}HxGY_Xh zmvX8KJk~H))xA9^!CXxhkYxU(4@gSo;DDqw3>A>1^5FoIROPC>q~&(RwT;A1>J8#EnAnzJGf9vqb^QL9v=w z4Qw>2;5_MEzNFT$-wkKosA{dMtJ!kmyy06?g`$%%fkPu-%-7f%hdA9DYbQ9`+R!mr z#0(;?X27mNT+~p819;KHq4RpWAf)nS2p}X>rT{`h!*D@JDIXFDDYYI5AD+GE(V`v6 zfsj%)6cAEMQwAZaE(wIsdB$2cUzm8*t7|zN_m4Z1ysS$Veq?T>4?jxf;P9g~3>AK)^5MXbRO`X- zqzA{JFItck{76;9fFG$eUHH-JlHm92|NPJ#M_|sIjh&PG(+q5 zUqk-T>mT?5Zi5O%jRJAz)B8K3_@sbnXzW}=2EiKcPt2Kcr~wqK@Mx*y1Zp+$CX_d) z@_`&mmq4L`vl!~dGVVXAnkC)H8?{QMfHfTK$gAUWN264R17xjSg_B_*15$z3Z5Zo_vC>EO+B@^zFp;JY)P4s9k@2{T0sj+_KKqIPCy;>Ea`_ zno}9{DkhGYt{3ZYX~x~4TB39HYY!TI$qCQ6iE{6+Rbhvj({T9;rYO}4#;AE*i>VdZ zk_o%k6$fHtuU)YwUUM&RP37`CG8@w89i?(`-ccHc$~#i|aCk?m^?0}OYXc7YNL9n& z9jP>3-qGrkc$b@c#wFlg;x=R41!!8`4*Ui?{rqGae_Ho?Y%>nVj1Kwke_(8|(_3?@ ziDiZyZhy+*ghI`%;l6B)`*7$L=HJv(;@-M+wiySLB}RNjqX@DA#g%%whE-vVIdKex zmaSFF1$?FFt7aB|RP{{ojCgn`|i1MpaCDL zY8U_{m8J_oT3r$VZ#nUmeF126^tl%9-L5zK&IQiC^Rx}@oP|KlC;(U0)*m4XPwJZ& zWUs5ZcU;B(4Bfyv*4W2U$Y*i!l3B^C*=*8^NIC!vCQAS?m#dUb701fdaqLYoTgz5) z`VDs171Wxc)#^nRJ~O47R?P%oP8EP;exwgTO6A}Hq%;f_fTZ%_0FYGc0q}kQ_^*Ez zZAj{imsB+j0Fp}61t6_134lNEeVr``tMJ^2dB!w5y4I{&@RZiIp54;giyS{V^ZKo) z*vhequSAi!|NYI!h~kt&qN-~pjJiw{7jNPu{fdFDcG*%Do+>I%&d=iN;rNZ9?>Xpi z;e;%KD|AAZ2sRdVwTg9_vdIqeujX)7pI*$uqZ=2W=k}4$097-RO zl*+*&Nog1=BuVANfh4KcgXEQa@BXN0RZ@^7RSg4@q|$UDNvlhOP&>-D^r0WPmh2e?mI4JYxPAV;e8AZI`K&Se8Zj#M=a$dO9Zg&eIe33B(GS@|U(cb1mC z_Q5;@TOGq}Ca-?{`FUUbntS{-kHvAf(_jC1@l9_jiGq{DonFMvNLn^mDC;H=hYf1^ z5^lJ|O`y0nM6V^D$Nz?d#$9sa`8m=&S?&r5+yHAOGmop@3&nCRU(jke^sto8;x71H z5ud|2kh)&fb@;%DTuXBegv^TcxksrSoO_gpp>mH@J{<0mYCZ0~mdhpX%f_rBsH~qEE#(vY#Y%Ljk5B>57H`vMw5h+T&PyhLjvqiB< zQ4b%J7~9oxou^jPtGMU`ciG`Q(@GKasa0x;dxc+@7WG7`1oYtVhbx-uc^oIGoB2Wo zAG^2@prGryV%ETVNWs9wUooE%@1@B+G9%Jw9;I?{=204k$~;o}aF|D`^_X|#C2xDD zXgpHPBUKH9d8E>GnMbQjV&2PE{pbiV&ztds&-32NW}|NE3py4%yavoJo=gT`@r3u> z1$Vzt%qabS^`q(4q5!4nhiNl2Tg~R`xLE+(g>lu92FK!D85bR8F~OF2<;eAE(+`^l zEz?C{0bAir9NthXV&fauKyYs-zIqErIgc60VyT$Nf%~<*i5Wh(*WfRw$w4wp(&r$h za&Qh(8ivY2Qu%N=NUHTXs6VasL(z<+I7q4*1_w!{>2i=(m&C#A-+Xls96Tj7_T$i7 z)Yb2s%Rl~OeA-UDj1zCS|CRfSk6iH=QB-oot5@sUYzc?4l(l?T$N5v)Y_@{EZ}6zA zV@Gh(%ErM@>cx^PJoQ}6X;{L*4JSAbux#d3J!@2Oj%p3IlgjuyeEWdS26W<(wLSpJTExnTj7YnM3Jgl2SQ1CMgX=#U!bG zIG7~WdYIh#(Nnxzzojrqsu~6+Nu}vxl2#YTq*9mzyOg4$C?gDF9sG+bDA9sA$Ns4_9FtZXfuul4qBzzWNZa%^j1gHY|h)8P7)5&m$yre6kM98aMC z@aWdUcB``=Rv0slnx$F(qoZ02J1=W=yU{0Xf6B;Ch3ja_}7e6CS7T)9-zwp2+ z7`l4hdCXpAybs!E8+N9_pxJ4fYuq7bW~$q5HgwI#-s((kuF*6yvu4}0a2PEvDCYT? z!LGuL8=d8D#$eeUg2`3kZ~B8)q&1A@9!J|AoQB(-v-cPc%TW|4R}ed~yr=Mb2JeMz z(g(E3O+3$&4V`wqF-v5^wF4@&Smm>Ny4C2~17yaIfEX`R=2?{(y~l4xwsMjv=RU1R zRHC+2vbcLaKYYzLdu~PA+-V|#7ijyn9j24Jy?$A0DNk8Sqive|&1OE-cF~@uTiqsa z2#PWqZ@Xw_Zj}l(z|}L#5v>JgTr~KY*230~F~=|yZtHjj&vrO_&bGCi3mcluuZ?Hi z>iMoR_p+1uzkPb03>uw#a0v_9y5J^jY*aZWgrsR@S!-d}LKkdWh4i64IGN30v2sQ^ z5@D9zsB5}CWf+Bp(df9=(5(XgY+j)=T)j2mlE4n~a30VMzh#m?;w(eYL)jG{U%2y*Nce3>A zPMulc`RDNZkw;Fw8>Ka3E6)fwAh+AWku>^VGz|>!+r4_nYW3FSGt846|DDWbuzpli zi)IeD0AT2f^BM|OHq_2zT_>l(g*(HL*=INStc7R%Sn=>lL9lM@3fZe;NPBpNu@!SD zsojT?&)}?d*1RV1hpiYx(WChlc=GZF|7^lNjsIVz>FGmB)4q1YR^-N`RH5@?X`-#N zGT|+5oDu2(|DCs$y+cWmi$u}>C+Aye3EEIp1;@U&vS&CtyaBJRTrw05R?k+3Q?~#> zTiHDnqjyZ&^LCe2s%5Wy=HGwy+yP*Ur63hIEE}p`$s0xdp;mJyPV_eQd>uZSIF*9K zG;x=u*6p%Ur)I}limjDWlP9z}gRqp8o)Sw*JqawmPLidhu6UZH>N~ARnx(X8*2SgG zQc`PrEG1Q?z*1Vrpe!XdNVAldEX`62d5x4NFNq2`Ify5~ZZB zc$%b8O6!qEDJ^;!C?&O~hf-2i3Mi#@42n`xgEUHM$I<$sW&o5Ha57rH zUdn1Xz8jZU;j{|uNW}g`9R~+hvu4gkY2t0N9!k{+Nk1(~Qreh7NJ>hNQ%8!Vq@Dzl z;wB-f4}4NrJWWz0rS(XYlomYo^c<#6nfig{BUyn$O8vN-=jt7$lw2wwPnP|DViJeOLRplbz5>y|dlP7{gn z^t+NgrA-=yr=;{ad!%?u>Pg_~Ly|ltb;Z*p#Zy|3G*4;K!{8~YH9ek^s#4%7tz%H0 zk{YCWN=ugJDJeS0(+^&E%*+5htzfrgP1SJcA@-_kaF#Nw*x{sNlT)QqDdshory<7* z!BectwV3z7n*FAZlj+tNmUbX=T08sV|GgwvY10PbDk(kAASterdJ?$$uq0PWUGX$Y zah291%~e|TFt|!;O^>UjsuZ|N>ll=)qy}lO(vqdQN{SA0^`B1qjWqyQHS7+p;)J-O zYUWC+sp1S?+^LQGyD$rYdn0gP1Rtj|2erQARJQwJ&0HfqOdUT|5~s99gW!~u9!HN9 zPDwp+oQ@wMiBnQnJWWzKrS(YTlomY zL?xxi=_5r{QcnU=&yXZ4sVkl)DWcMPq=`z49tKfKt?3b!RFwizX&r+SmDC_jR9dn$ zQAyE3qHels`E3Ib6_=RdG&nt{*Q%y&Vwt~)v*D_Fy{zk5TrrD7ocI8>v=~tr{q7$> zM-r>FWrJXqlpaTr6jn(+30PexiB(cpJWWzqrS(W-l@>h=tdd&O!z!sN1+3CK2E{6= zK^m*HWNECDqJvod_}?qP7yzp{9;IBsQA~zWt(59opKX}NcHxB?(6^>G6+~$bGPb#?Ar<|{6tGMSv ztrd!uO06zjrm{&O)jJ)_XtddNN$wd6`O0K=GRqE8U_iZ05~#FIg8-G39*2(p>MGph0q}KF+N~%f$sI-njfl6wS1}ZIC8mOe`AW)B3xA~4i zfU4K4B`iwedX8KrSI_6F1)LzN)vNFTsN{;cwUUoa6SqdOm3=drr7x0YDQV6?ETyE! zxg*C?N>2hyUn@Bhax5kF$g`9bJrtHwT2o{xr78`Uk~#)vDWyT4rKDtemQtdF zEWNvz{l)++HM8(HEgSiguHp_jqi9y^`I=G4mC9Aze_qAefSjd?gVSEKfwAdqS8JPz zgVQ%l0+qID5TKIMp>MGph0q}KF+N~%f$sI-nj zfl6wS1}ZIC8mOe`AW)yM;weuV0H{S1yP>k>e5qQjmWx`cmNRj&NVb?Q){Iig8=NL? zkkaRRcBjQAPb2I4ACx31ZOkAfC8fuyBSlhDPXbAAmn12vE1o7PlG1vlNlJ?z21!Y+ z>5-IFl>$j=9fOjT)F4e#TCy}rNzp-)e&M&vj~alar9w&1!Y`_Z>)&#?{IZlc;fIQ= zIP*0foA!m{X|ku(fkxM~%sS3`*_${v{gNb6X`==qDk(iqA1R`edJ>3wuOv}PUGX$Y z5tY^>O;lR+Fo;TOO^>LgsuYMy>ll=%qy}lC(vqc#N{S8=^^1p`ecb>=h1b4XF{?RD znBrn3tzN3@WmPQ}E4gd|KK;V?G@rB*rS%rtILvMVN0v6)^(J;pS&>2Nk0g;wTQvw$ zN$GL?NFkNflYrEpNg|ch6;G2CQfWQXNTo#&1F59e^pHxbN&%^~jzN)1YLG@MEm<0= zr05`0N6&ol{R1G?(DJytsi0-CfnO`!V!x8 zRg$8#A%jqqlpZIJ6h%or2^4)qlA@%pc$%arO6!rPC@p#z6eYE$M^RE$3KXSv3`$W_ zgEU2H$Wd9*tw@+rcN9!$yC~`L6}NPkMl>0sidAbQzwp>WGbmEo+c@#(t4zsN{b!_ zQ%SAqF_l!60#j)ngEE!WAk9=-vNTgk(Ltu({rhLXXb`4W^QwWpP!%(4;36s9?_AB} zgeg_6RdqF67SpGUn2YS&PoU|OWNAtoG!RWG>2dPN(Uj7YK+}vYO(|XRG|ADF)FV$* zQuI)0N@-1zrj)8QXiDlBn5L8ld76@v5fnnkC4`Jy$f5^kDbOpu|X20v^9gEl$0LFjuc8sJqak?B8gH` zS3FHpD5dpCqm&js43v^u(?cn#Dg~6%ItE24sX-d0v}9?NlA?nsz5dP*eSZLyRt$F6 zeKD(P#TquWW-A~m4wBMMT!E_Ba$;bbxC*r&m(AhUKhx-HxGk|6KcjErQc0xJRtW86p%{m7!;|b25F?ylBJPK ziVh<6(ht0S`2a{YG)=*d+?X0& zjGE|4!j!gW5SWtE zZCIU#F^Q4r-pMAeb=4R2rn%N~?$%wKo5cUQ`}8MXDG5^AmO(&DN{>TF3Z$f-1dzT) z5~QTAc$%a@O6!pZDJ^;!ASJb?2U1d13LvF*3<^?GgEUBK$`t9rez<}na8a2&r@Di!ist&V%6@@h7_=$R)SeU9A{Rc~N;8ah8} z;tolc(&h}pQc`-HJ5nqq^(3(LE=iV>y5eb)Vkxahnx(YpVX&0cnjT9@RVlEP)-fnc zNe$90r6o(VloTCg>50$%=>H7BQdQSVg@R_9rEIBy+e{4XG0m2$CG3tWVS8!KWvQAp zTiWdCTC--sb6?kbc1vr=PdS~qUlOXcU4uZClpY6=6jVt)2~d4N5~`%Gc$%c3O6!q^ zDlK{#P$jjd2USv43Q(nW3<_0JgEUlW$BMnhn^e`YwYE2KKq^cAkO6wRDqNE0Ch|-d!Axer4LR7!yG0z+TqIxlhGxoE& zLRmKf&Pq+omvDh8?uE|PYI;pvWpb95y!6DJOj{kpY=#z}mW@fGl(uFNl#W|O6rQINeZR39%+=)qKAP}QfqoBB~_(>Qd-BLC?z#Wqm-5`jZ#u{5Tzg9 zcH6fGKxwUPVi;P-70_BquU7I!Tw`ir6I8Ke=4+Lj*qDE2ACxv5`%Oc$wJ=E^D@jt? zm_bNNN{>@Viln5T1d^U4Nm5c*JWWz0rS(XYlomY5v1s-a~o^<24-&t;3%oVWk zMpMfSWZgH3a7LlX`Irchk;X4YkD{(Ri%Ja zTF0O`B{fLnl$I=wQ&Mygr~h{A5ho0S(|Wa@&6Z4~Sl04c-7u@!Y_@`Jr0_1SW1qge z`gBTYV9ME<qoN_w0(atx*PBrxp7VAc#pw??zE^p`sY$z?4b)%$~ zYFa5| zt#wJXlDgt)l0qx3M;fiP=wYCh)S4bzNmVJJmDVvRT1gGkXr(1fqm>lxqg5%);a*Us zhym(E&r+&E0yYd2^lP;`?a5he_-vY!e6eVLp$F?%rD_(uqKmWVxynjY$eC%(( zauVpyGq^8b>a-unpApojv_p;vRj4zmK(*OX#F!rn=o`L)TdK&(v6EW@gQ{Y2m1K zBZJnJLC&~oXGUfWX7zzlB{MISJUa~~X76IHIR|xpbXiL1#*Kb;3^bX>KnsPmW3J6I zAO9PP!{mt8!p^yFw`18mZOxwR?N*NULQG@52bdYgpy_tK69LM}38L9CP1^XF}lN4fWimG*o1w zTP+1>x6RqzIYuM)Kji0FsHM&*M*+PUUAAgXbC=e;>_V-@@rwqzswX`g0|{$l5Z7S>g82tXUo6<{3(&xF-83LxMFih$Lvg{>Hm`_`d>&LDe4 z=DUr-e|}CNHB2(gW26v*oj8tQhb~XQTKUN%_#fwjQy5FH!M;i-!Ć&Gv%jWA`! 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 aF?J^Y?dB=^+6kwMjEu}P*CS=m{Qm*c6DXMg literal 0 HcmV?d00001 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 7c4fca0..8144c3c 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,6 @@ - @@ -12,11 +11,6 @@ - - - - - - + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 1c53797..a020387 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,8 +1,11 @@ + diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..bc2751c --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 5bae4e2..65c58fe 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,26 +5,47 @@ - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 14a85c1..0188d1c 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,9 +2,9 @@ - - + + \ No newline at end of file diff --git a/.idea/modules/Application/iconsole-android.Application.iml b/.idea/modules/Application/iconsole-android.Application.iml new file mode 100644 index 0000000..9c836b4 --- /dev/null +++ b/.idea/modules/Application/iconsole-android.Application.iml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/android_antlib_4-14/iconsole-android.android_antlib_4-14.iml b/.idea/modules/android_antlib_4-14/iconsole-android.android_antlib_4-14.iml new file mode 100644 index 0000000..41848b4 --- /dev/null +++ b/.idea/modules/android_antlib_4-14/iconsole-android.android_antlib_4-14.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Application/Application.iml b/Application/Application.iml deleted file mode 100644 index 153210c..0000000 --- a/Application/Application.iml +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Application/build.gradle b/Application/build.gradle index ebcfc8a..bda7faf 100644 --- a/Application/build.gradle +++ b/Application/build.gradle @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:4.1.3' } } diff --git a/Application/src/main/AndroidManifest.xml b/Application/src/main/AndroidManifest.xml index 2b01c64..33e4dda 100644 --- a/Application/src/main/AndroidManifest.xml +++ b/Application/src/main/AndroidManifest.xml @@ -34,14 +34,16 @@ > - - + + + + diff --git a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java index 8087e1f..b7dc91b 100644 --- a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java +++ b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java @@ -44,10 +44,104 @@ import android.widget.NumberPicker; import android.widget.TextView; import android.widget.Toast; +import java.lang.ref.WeakReference; + /** * This fragment controls Bluetooth to communicate with other devices. */ public class BluetoothChatFragment extends Fragment { + static class MyInnerHandler extends Handler{ + WeakReference mFrag; + + MyInnerHandler(BluetoothChatFragment aFragment) { + mFrag = new WeakReference(aFragment); + } + + @Override + public void handleMessage(Message msg) { + BluetoothChatFragment theFrag = mFrag.get(); + if (theFrag == null) { + return; + } + FragmentActivity activity = theFrag.getActivity(); + + switch (msg.what) { + case Constants.MESSAGE_STATE_CHANGE: + switch (msg.arg1) { + case BluetoothChatService.STATE_CONNECTED: + theFrag.setStatus(theFrag.getString(R.string.title_connected_to, theFrag.mConnectedDeviceName)); + //mConversationArrayAdapter.clear(); + theFrag.mStartButton.setEnabled(true); + theFrag.mStopButton.setEnabled(true); + theFrag.mDisconnectButton.setEnabled(true); + theFrag.mLevel.setEnabled(true); + theFrag.mLevel.setValue(1); + break; + case BluetoothChatService.STATE_CONNECTING: + theFrag.setStatus(R.string.title_connecting); + theFrag.mStartButton.setEnabled(false); + theFrag.mStopButton.setEnabled(false); + theFrag.mDisconnectButton.setEnabled(false); + theFrag.mLevel.setEnabled(false); + break; + case BluetoothChatService.STATE_LISTEN: + case BluetoothChatService.STATE_NONE: + theFrag.setStatus(R.string.title_not_connected); + theFrag.mStartButton.setEnabled(false); + theFrag.mStopButton.setEnabled(false); + theFrag.mDisconnectButton.setEnabled(false); + theFrag.mLevel.setEnabled(false); + break; + } + break; + case Constants.MESSAGE_DATA: + if (!(msg.obj instanceof IConsole.Data)) + return; + IConsole.Data data = (IConsole.Data) msg.obj; + theFrag.mChannelService.setSpeed(data.mSpeed10 / 10.0); + theFrag.mChannelService.setPower(data.mPower10 * 9 / 100); + theFrag.mChannelService.setCadence(data.mRPM); + + theFrag.mSpeedText.setText(String.format("% 3.1f", data.mSpeed10 / 10.0)); + theFrag.mPowerText.setText(String.format("% 3.1f", data.mPower10 / 10.0)); + theFrag.mRPMText.setText(String.format("%d", data.mRPM)); + theFrag.mDistanceText.setText(String.format("% 3.1f", data.mDistance10 / 10.0)); + theFrag.mCaloriesText.setText(String.format("% 3d", data.mCalories)); + theFrag.mHFText.setText(String.format("%d", data.mHF)); + theFrag.mTimeText.setText(String.format("%s", data.getTimeStr())); + //mLevel.setValue(data.mLevel); + break; + case Constants.MESSAGE_WRITE: + //byte[] writeBuf = (byte[]) msg.obj; + // construct a string from the buffer + //String writeMessage = new String(writeBuf); + //mConversationArrayAdapter.add("Me: " + writeMessage); + break; + case Constants.MESSAGE_READ: + //byte[] readBuf = (byte[]) msg.obj; + // construct a string from the valid bytes in the buffer + //String readMessage = new String(readBuf, 0, msg.arg1); + //mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage); + break; + case Constants.MESSAGE_DEVICE_NAME: + // save the connected device's name + theFrag.mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME); + if (null != activity) { + Toast.makeText(activity, "Connected to " + + theFrag.mConnectedDeviceName, Toast.LENGTH_SHORT).show(); + } + break; + case Constants.MESSAGE_TOAST: + if (null != activity) { + Toast.makeText(activity, msg.getData().getString(Constants.TOAST), + Toast.LENGTH_SHORT).show(); + } + break; + } + } + } + + private final Handler mHandler = new MyInnerHandler(this); private static final String TAG = "BluetoothChatFragment"; @@ -92,86 +186,6 @@ public class BluetoothChatFragment extends Fragment { /** * The Handler that gets information back from the BluetoothChatService */ - private final Handler mHandler = new Handler() { - @SuppressLint("DefaultLocale") - @Override - public void handleMessage(Message msg) { - FragmentActivity activity = getActivity(); - switch (msg.what) { - case Constants.MESSAGE_STATE_CHANGE: - switch (msg.arg1) { - case BluetoothChatService.STATE_CONNECTED: - setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); - //mConversationArrayAdapter.clear(); - mStartButton.setEnabled(true); - mStopButton.setEnabled(true); - mDisconnectButton.setEnabled(true); - mLevel.setEnabled(true); - mLevel.setValue(1); - break; - case BluetoothChatService.STATE_CONNECTING: - setStatus(R.string.title_connecting); - mStartButton.setEnabled(false); - mStopButton.setEnabled(false); - mDisconnectButton.setEnabled(false); - mLevel.setEnabled(false); - break; - case BluetoothChatService.STATE_LISTEN: - case BluetoothChatService.STATE_NONE: - setStatus(R.string.title_not_connected); - mStartButton.setEnabled(false); - mStopButton.setEnabled(false); - mDisconnectButton.setEnabled(false); - mLevel.setEnabled(false); - break; - } - break; - case Constants.MESSAGE_DATA: - if (!(msg.obj instanceof IConsole.Data)) - return; - IConsole.Data data = (IConsole.Data) msg.obj; - mChannelService.setSpeed(data.mSpeed10 / 10.0); - mChannelService.setPower(data.mPower10 / 10); - mChannelService.setCadence(data.mRPM); - - mSpeedText.setText(String.format("% 3.1f", data.mSpeed10 / 10.0)); - mPowerText.setText(String.format("% 3.1f", data.mPower10 / 10.0)); - mRPMText.setText(String.format("%d", data.mRPM)); - mDistanceText.setText(String.format("% 3.1f", data.mDistance10 / 10.0)); - mCaloriesText.setText(String.format("% 3d", data.mCalories)); - mHFText.setText(String.format("%d", data.mHF)); - mTimeText.setText(String.format("%s", data.getTimeStr())); - //mLevel.setValue(data.mLevel); - break; - case Constants.MESSAGE_WRITE: - //byte[] writeBuf = (byte[]) msg.obj; - // construct a string from the buffer - //String writeMessage = new String(writeBuf); - //mConversationArrayAdapter.add("Me: " + writeMessage); - break; - case Constants.MESSAGE_READ: - //byte[] readBuf = (byte[]) msg.obj; - // construct a string from the valid bytes in the buffer - //String readMessage = new String(readBuf, 0, msg.arg1); - //mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage); - break; - case Constants.MESSAGE_DEVICE_NAME: - // save the connected device's name - mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME); - if (null != activity) { - Toast.makeText(activity, "Connected to " - + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); - } - break; - case Constants.MESSAGE_TOAST: - if (null != activity) { - Toast.makeText(activity, msg.getData().getString(Constants.TOAST), - Toast.LENGTH_SHORT).show(); - } - break; - } - } - }; private boolean mChannelServiceBound = false; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { diff --git a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java index 1085fc7..0303cd3 100644 --- a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java +++ b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java @@ -141,6 +141,7 @@ public class BluetoothChatService extends Service { mNewState = mState; // Give the new state to the Handler so the UI Activity can update + if (mHandler != null) mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, mNewState, -1).sendToTarget(); } diff --git a/Application/src/main/java/org/surfsite/iconsole/ChannelService.java b/Application/src/main/java/org/surfsite/iconsole/ChannelService.java index 3377fb5..26ba4cc 100644 --- a/Application/src/main/java/org/surfsite/iconsole/ChannelService.java +++ b/Application/src/main/java/org/surfsite/iconsole/ChannelService.java @@ -127,7 +127,9 @@ public class ChannelService extends Service { } private void closeAllChannels() { + if (powerChannelController != null) powerChannelController.close(); + if (speedChannelController != null) speedChannelController.close(); powerChannelController = null; speedChannelController = null; diff --git a/Application/src/main/java/org/surfsite/iconsole/FEChannelController.java b/Application/src/main/java/org/surfsite/iconsole/FEChannelController.java new file mode 100644 index 0000000..a4330dd --- /dev/null +++ b/Application/src/main/java/org/surfsite/iconsole/FEChannelController.java @@ -0,0 +1,316 @@ +/* + * Copyright 2012 Dynastream Innovations Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.surfsite.iconsole; + +import android.os.RemoteException; +import android.util.Log; + +import com.dsi.ant.channel.AntChannel; +import com.dsi.ant.channel.AntCommandFailedException; +import com.dsi.ant.channel.Capabilities; +import com.dsi.ant.channel.IAntChannelEventHandler; +import com.dsi.ant.message.ChannelId; +import com.dsi.ant.message.ChannelType; +import com.dsi.ant.message.EventCode; +import com.dsi.ant.message.fromant.AcknowledgedDataMessage; +import com.dsi.ant.message.fromant.ChannelEventMessage; +import com.dsi.ant.message.fromant.MessageFromAntType; +import com.dsi.ant.message.ipc.AntMessageParcel; + +import java.util.Random; + +public class FEChannelController { + public static final int FE_SENSOR_ID = 0x9e3d4b67; + // The device type and transmission type to be part of the channel ID message + private static final int CHANNEL_FE_DEVICE_TYPE = 0x11; + private static final int CHANNEL_FE_TRANSMISSION_TYPE = 5; + // The period and frequency values the channel will be configured to + private static final int CHANNEL_POWER_PERIOD = 8182; // 1 Hz + private static final int CHANNEL_POWER_FREQUENCY = 57; + private static final String TAG = FEChannelController.class.getSimpleName(); + private static Random randGen = new Random(); + int power = 0; + int cadence = 0; + private AntChannel mAntChannel; + private ChannelEventCallback mChannelEventCallback = new ChannelEventCallback(); + private boolean mIsOpen; + + public FEChannelController(AntChannel antChannel) { + mAntChannel = antChannel; + openChannel(); + } + + boolean openChannel() { + if (null != mAntChannel) { + if (mIsOpen) { + Log.w(TAG, "Channel was already open"); + } else { + // Channel ID message contains device number, type and transmission type. In + // order for master (TX) channels and slave (RX) channels to connect, they + // must have the same channel ID, or wildcard (0) is used. + ChannelId channelId = new ChannelId(FE_SENSOR_ID & 0xFFFF, + CHANNEL_FE_DEVICE_TYPE, CHANNEL_FE_TRANSMISSION_TYPE); + + try { + // Setting the channel event handler so that we can receive messages from ANT + mAntChannel.setChannelEventHandler(mChannelEventCallback); + + // Performs channel assignment by assigning the type to the channel. Additional + // features (such as, background scanning and frequency agility) can be enabled + // by passing an ExtendedAssignment object to assign(ChannelType, ExtendedAssignment). + mAntChannel.assign(ChannelType.BIDIRECTIONAL_MASTER); + + /* + * Configures the channel ID, messaging period and rf frequency after assigning, + * then opening the channel. + * + * For any additional ANT features such as proximity search or background scanning, refer to + * the ANT Protocol Doc found at: + * http://www.thisisant.com/resources/ant-message-protocol-and-usage/ + */ + mAntChannel.setChannelId(channelId); + mAntChannel.setPeriod(CHANNEL_POWER_PERIOD); + mAntChannel.setRfFrequency(CHANNEL_POWER_FREQUENCY); + mAntChannel.open(); + mIsOpen = true; + + Log.d(TAG, "Opened channel with device number: " + FE_SENSOR_ID); + } catch (RemoteException e) { + channelError(e); + } catch (AntCommandFailedException e) { + // This will release, and therefore unassign if required + channelError("Open failed", e); + } + } + } else { + Log.w(TAG, "No channel available"); + } + + return mIsOpen; + } + + + void channelError(RemoteException e) { + String logString = "Remote service communication failed."; + + Log.e(TAG, logString); + + } + + void channelError(String error, AntCommandFailedException e) { + StringBuilder logString; + + if (e.getResponseMessage() != null) { + String initiatingMessageId = "0x" + Integer.toHexString( + e.getResponseMessage().getInitiatingMessageId()); + String rawResponseCode = "0x" + Integer.toHexString( + e.getResponseMessage().getRawResponseCode()); + + logString = new StringBuilder(error) + .append(". Command ") + .append(initiatingMessageId) + .append(" failed with code ") + .append(rawResponseCode); + } else { + String attemptedMessageId = "0x" + Integer.toHexString( + e.getAttemptedMessageType().getMessageId()); + String failureReason = e.getFailureReason().toString(); + + logString = new StringBuilder(error) + .append(". Command ") + .append(attemptedMessageId) + .append(" failed with reason ") + .append(failureReason); + } + + Log.e(TAG, logString.toString()); + + mAntChannel.release(); + } + + public void close() { + // TODO kill all our resources + if (null != mAntChannel) { + mIsOpen = false; + + // Releasing the channel to make it available for others. + // After releasing, the AntChannel instance cannot be reused. + mAntChannel.release(); + mAntChannel = null; + } + + Log.e(TAG, "Channel Closed"); + } + + /** + * Implements the Channel Event Handler Interface so that messages can be + * received and channel death events can be handled. + */ + public class ChannelEventCallback implements IAntChannelEventHandler { + + int cnt = 0; + int eventCount = 0; + int cumulativePower = 0; + + @Override + public void onChannelDeath() { + // Display channel death message when channel dies + Log.e(TAG, "Channel Death"); + } + + @Override + public void onReceiveMessage(MessageFromAntType messageType, AntMessageParcel antParcel) { + Log.d(TAG, "Rx: " + antParcel); + Log.d(TAG, "Message Type: " + messageType); + byte[] payload = new byte[8]; + + byte fe_state = 0; // RESERVED + fe_state = 1; // ASLEEP + fe_state = 2; // READY + fe_state = 3; // IN_USE + fe_state = 4; // FINISHED / PAUSE + + // Switching on message type to handle different types of messages + switch (messageType) { + // If data message, construct from parcel and update channel data + case BROADCAST_DATA: + // Rx Data + //updateData(new BroadcastDataMessage(antParcel).getPayload()); + break; + case ACKNOWLEDGED_DATA: + // Rx Data + //updateData(new AcknowledgedDataMessage(antParcel).getPayload()); + payload = new AcknowledgedDataMessage(antParcel).getPayload(); + Log.d(TAG, "AcknowledgedDataMessage: " + payload); + + if ((payload[0] == 0) && (payload[1] == 1) && (payload[2] == (byte)0xAA)) { + payload[0] = (byte) 0x01; + payload[1] = (byte) 0xAC; + payload[2] = (byte) 0xFF; + payload[3] = (byte) 0xFF; + payload[4] = (byte) 0xFF; + payload[5] = (byte) 0xFF; + payload[6] = (byte) 0x00; + payload[7] = (byte) 0x00; + try { + // Setting the data to be broadcast on the next channel period + mAntChannel.setBroadcastData(payload); + } catch (RemoteException e) { + channelError(e); + } + } + break; + case CHANNEL_EVENT: + // Constructing channel event message from parcel + ChannelEventMessage eventMessage = new ChannelEventMessage(antParcel); + EventCode code = eventMessage.getEventCode(); + Log.d(TAG, "Event Code: " + code); + + // Switching on event code to handle the different types of channel events + switch (code) { + case TX: + cnt += 1; + + if (cnt % 66 == 64) { + payload[0] = (byte) 0x50; + payload[1] = (byte) 0xFF; + payload[2] = (byte) 0xFF; + payload[3] = (byte) 0x01; + payload[4] = (byte) 0xFF; + payload[5] = (byte) 0x00; + payload[6] = (byte) 0x01; + payload[7] = (byte) 0x00; + } else if (cnt % 66 == 65) { + payload[0] = (byte) 0x51; + payload[1] = (byte) 0xFF; + payload[2] = (byte) 0xFF; + payload[3] = (byte) 0x01; + payload[4] = (byte) ((FE_SENSOR_ID) & 0xFF); + payload[5] = (byte) ((FE_SENSOR_ID >> 8) & 0xFF); + payload[6] = (byte) ((FE_SENSOR_ID >> 16) & 0xFF); + payload[7] = (byte) ((FE_SENSOR_ID >> 24) & 0xFF); + } else if (cnt % 2 == 0) { + // PAGE 16 + payload[0] = (byte) 0x10; + payload[1] = (byte) 25; // Equipment Type: 25 == Trainer / Stationary Bike + payload[2] = (byte) elapsedTime_in_0_25_seconds; + payload[3] = (byte) 0; // Distance traveled + payload[4] = (byte) 0xFF; // Speed LSB + payload[5] = (byte) 0xFF; // Speed MSB + payload[6] = (byte) 0xFF; // heart rate + payload[7] = (byte) (fe_state >> 4); // Capabilities 0:3 ; FE State Bit Field 4:7 + } else { + // PAGE 25 + eventCount = (eventCount + 1) & 0xFF; + cumulativePower = (cumulativePower + power) & 0xFFFF; + byte flags_bit_field; + flags_bit_field = 1; // too slow to achieve target power + flags_bit_field = 2; // too fast to achieve target power + flags_bit_field = 0; // operating at target power + + payload[0] = (byte) 0x19; + payload[1] = (byte) eventCount; + payload[2] = (byte) cadence; + payload[3] = (byte) ((cumulativePower) & 0xFF); + payload[4] = (byte) ((cumulativePower >> 8) & 0xFF); + payload[5] = (byte) ((power) & 0xFF); + payload[6] = (byte) (((power >> 8) & 0xFF) | (trainerStatusBits >> 4)); + payload[7] = (byte) ((flags_bit_field & 0xF) | ((fe_state >> 4) & 0xF0)); // Capabilities 0:3 ; FE State Bit Field 4:7 + } + } + + if (mIsOpen) { + try { + // Setting the data to be broadcast on the next channel period + mAntChannel.setBroadcastData(payload); + } catch (RemoteException e) { + channelError(e); + } + } + break; + case CHANNEL_COLLISION: + cnt += 1; + break; + case RX_SEARCH_TIMEOUT: + // TODO May want to keep searching + Log.e(TAG, "No Device Found"); + break; + case CHANNEL_CLOSED: + case RX_FAIL: + case RX_FAIL_GO_TO_SEARCH: + case TRANSFER_RX_FAILED: + case TRANSFER_TX_COMPLETED: + case TRANSFER_TX_FAILED: + case TRANSFER_TX_START: + case UNKNOWN: + // TODO More complex communication will need to handle these events + break; + } + break; + case ANT_VERSION: + case BURST_TRANSFER_DATA: + case CAPABILITIES: + case CHANNEL_ID: + case CHANNEL_RESPONSE: + case CHANNEL_STATUS: + case SERIAL_NUMBER: + case OTHER: + // TODO More complex communication will need to handle these message types + break; + } + } + } +} diff --git a/Application/src/main/res/layout/fragment_bluetooth_chat.xml b/Application/src/main/res/layout/fragment_bluetooth_chat.xml index 95338db..f47b525 100644 --- a/Application/src/main/res/layout/fragment_bluetooth_chat.xml +++ b/Application/src/main/res/layout/fragment_bluetooth_chat.xml @@ -101,7 +101,7 @@ android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="16dp" - android:text="Power" + android:text="Power corr" app:layout_constraintBottom_toTopOf="@+id/Power" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/guidelineleft" diff --git a/Application/src/main/res/values/strings.xml b/Application/src/main/res/values/strings.xml index 4b9e87c..8b6a118 100644 --- a/Application/src/main/res/values/strings.xml +++ b/Application/src/main/res/values/strings.xml @@ -46,7 +46,7 @@ 0.0 Level OpeniConsole Bluetooth active - OpeniConsole + OpeniConsole - TEST Connect to iConsole diff --git a/android_antlib_4-14/android_antlib_4-14.iml b/android_antlib_4-14/android_antlib_4-14.iml deleted file mode 100644 index 47b5059..0000000 --- a/android_antlib_4-14/android_antlib_4-14.iml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7487467..cf780a6 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:4.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17ebf47..e4259d6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun May 12 14:24:25 CEST 2019 +#Mon Apr 12 12:52:47 CEST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/iconsole-android.iml b/iconsole-android.iml index 24c2e1d..74be301 100644 --- a/iconsole-android.iml +++ b/iconsole-android.iml @@ -1,5 +1,5 @@ - + @@ -8,11 +8,12 @@ - + + - + \ No newline at end of file