From 43d2856431214fb89e6af8fbbfc584f30418828e Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Thu, 20 Aug 2015 15:39:18 +0800 Subject: [PATCH 01/21] Fix floater drag where dragging on the untouchable area of GotoButton makes the floater not receive the move action. --- .../java/yuku/alkitab/base/widget/GotoButton.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/GotoButton.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/GotoButton.java index b5dcd409e..70a7dd270 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/GotoButton.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/GotoButton.java @@ -49,12 +49,14 @@ public boolean onTouchEvent(final MotionEvent event) { float x = event.getX(); float y = event.getY(); - if (untouchableSideWidth == Integer.MIN_VALUE) { - untouchableSideWidth = getResources().getDimensionPixelSize(R.dimen.nav_prevnext_width) - getResources().getDimensionPixelSize(R.dimen.nav_goto_side_margin); - } + if (action == MotionEvent.ACTION_DOWN) { + if (untouchableSideWidth == Integer.MIN_VALUE) { + untouchableSideWidth = getResources().getDimensionPixelSize(R.dimen.nav_prevnext_width) - getResources().getDimensionPixelSize(R.dimen.nav_goto_side_margin); + } - if (x >= 0 && x < untouchableSideWidth || x < getWidth() && x >= getWidth() - untouchableSideWidth) { - return false; + if (x >= 0 && x < untouchableSideWidth || x < getWidth() && x >= getWidth() - untouchableSideWidth) { + return false; + } } getLocationOnScreen(screenLocation); From 0d3e9abc2e82b0425fb2a78d2f29406070d3dac5 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Mon, 24 Aug 2015 16:35:50 +0800 Subject: [PATCH 02/21] Make partial highlight textbox larger --- Alkitab/src/main/res/layout/dialog_edit_highlight.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Alkitab/src/main/res/layout/dialog_edit_highlight.xml b/Alkitab/src/main/res/layout/dialog_edit_highlight.xml index 936a39a24..b33afa9e7 100644 --- a/Alkitab/src/main/res/layout/dialog_edit_highlight.xml +++ b/Alkitab/src/main/res/layout/dialog_edit_highlight.xml @@ -10,9 +10,10 @@ android:id="@+id/tVerseText" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="none" - android:maxLines="4" android:layout_marginBottom="@dimen/padding_small" + android:inputType="none" + android:maxLines="6" + android:textAppearance="?android:textAppearanceMedium" android:textIsSelectable="true" /> From 485f46e9b37bb723360f19bd951f38df2e6a9c84 Mon Sep 17 00:00:00 2001 From: jaya hendrick Date: Mon, 24 Aug 2015 18:14:44 +0800 Subject: [PATCH 03/21] update ic_attr_has_maps.png style --- .../res/drawable-hdpi/ic_attr_has_maps.png | Bin 695 -> 1547 bytes .../res/drawable-mdpi/ic_attr_has_maps.png | Bin 437 -> 948 bytes .../res/drawable-xhdpi/ic_attr_has_maps.png | Bin 906 -> 2349 bytes .../res/drawable-xxhdpi/ic_attr_has_maps.png | Bin 1494 -> 3943 bytes .../res/drawable-xxxhdpi/ic_attr_has_maps.png | Bin 2215 -> 6029 bytes 5 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Alkitab/src/main/res/drawable-hdpi/ic_attr_has_maps.png mode change 100644 => 100755 Alkitab/src/main/res/drawable-mdpi/ic_attr_has_maps.png mode change 100644 => 100755 Alkitab/src/main/res/drawable-xhdpi/ic_attr_has_maps.png mode change 100644 => 100755 Alkitab/src/main/res/drawable-xxhdpi/ic_attr_has_maps.png mode change 100644 => 100755 Alkitab/src/main/res/drawable-xxxhdpi/ic_attr_has_maps.png diff --git a/Alkitab/src/main/res/drawable-hdpi/ic_attr_has_maps.png b/Alkitab/src/main/res/drawable-hdpi/ic_attr_has_maps.png old mode 100644 new mode 100755 index 956699775dcc8ca96beaac1a5f6fece5743cf49b..a6f91fd4e6a0f0a43fd5f2df6eaacb61faeabb26 GIT binary patch delta 1530 zcmV8iNEozDHs+`u zw4gxL&hkre9af2>OMsXnTH03uYv#xT!bWCUt8__2Gll*TTEMc_=n7)YjM9w&((wlf ztjK`ipj|GZrXvb1$e;-?d4Iig@BQ5GJNMjk4gzw+2jPay(0?ZM|Mk~4m3C{Tv$C>; zSS&UQY+_(wz$B4Ka^K{J*2F!|oH--EaNz@S$DPWfryWf569tf*#rV1 ziAW^w3J3^5`G5NQLMRk!o@;Jy4w{&lfQE*KtX*AQe;SR(roO(uA4nup7oX3!t^|I? z&}1^%4~xa-(rC0V_wV1o9fQF*wZ6q-f%JO)h)Sip+S}XvjZUW2$M>c3{55#KfOjEY|zLRa7d~s7NF_ zpj0Z2%L(8#^vRPaFZ22Q0)Kyh$Ye6jm6VjQWHQ;0jte9uB@yv>d;y6>`WTDFVh{)f z!hdWwk9Br-0)H=8sZ<8X7)__s=^PH{r-+CMujkL7Lof{2R#sM?ST2q`1x+TCx2L70 z>6uJsFo?V5<>mL<+uLI`8qK5~Iwd6~_3+`t-%_d60B>*a|A;j`Jq@+BwT;T<^0QK@ z^r{^yAtB+dsHiAqVPRpcmzNhLm&*smVt?^IjYiYAl-f=~A3Ai1%H?uZ;o;#P{r&xr zKp;3>S6BC)ed2=$4@PBVWGLx$`gR23^;4?V>M@Z>bVQ+0wA;rr7>u;@=g-&e-n|>y z)6-*vVK_x5lhv;pn#E#qU>Ftx*Jy5T9;>XZjL~Q`kHExyJ|AhZSgvuo+zfE2mVbJH z;ukMoRBE-_Blqv${|DH{#>T#vot>?x)9E{bixd|Z3#+TE&#nmi*s){6prD{IFxc1E z_gyxd9SVM7O-)U=OeXutU@-gzzEP>vchb|-4e9CW;P5T`C=`m}D_5?3a{Kme(?T5I zLZi_P1qB6B;DA?ERsAtMJp4QOHh(xc*pJ8KzgiqoUi&W#3kw?s0zuMZic6O+-D_=a z-Di&m6bdDh%jNzO9UZ-OSz-u+9zJ|HD-Z}`9bM$yxpTL8JYM|b@nvOY;NZq=2xu6F z3hUP(3Fn=W=mzvHM)(0D2)|(lQu~9Uz`wzkYq7p`qcm36s@o4e;>r zK)iVIVtCyWCIG%THLb0!{jH^?<%FSqPr(8cY63v=HqtSS4 z-I_IvlN-<$L!;3jfOn&}#a@|>Zgx#yA&XNrqBF_8qm5fO)m`1BtM+T6w5t%V+HXR; gs@O{H-BRg)0fdGEYP}?wD*ylh07*qoM6N<$f~gAe&Hw-a delta 672 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 KMNUMnLSTZ`;-F3d diff --git a/Alkitab/src/main/res/drawable-xxhdpi/ic_attr_has_maps.png b/Alkitab/src/main/res/drawable-xxhdpi/ic_attr_has_maps.png old mode 100644 new mode 100755 index 783bb881096352a948583ffea309f69dda1ab314..6179f15ef17f2bc03a836c7d0cd35ca8ccf9333b GIT binary patch literal 3943 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 Bv^xL* delta 1477 zcmV;$1v>iY9@YzxBYy>*NklbYT3<-HK=79%-|Yp=b}S%Mc60!vJ^xDp(+kr6m(2W>>aNR3;xgMT(6V5G(^+Cdu;FjC_d z?Vyba7^!iKcF=POJP~1XfDx-fYNpAe9rU1EonP5O=d&6l>7WPU%dhO9^H~j&bkKwF zbywCTy%Dfk_`4pkWkk>Wz*oR$z(?WlKMndcsL6#Cb*L{}0lNU(0jo_ovY&vrfLDR{ zCTyd6wS@qB1%F_7U>{)J$|L+5cm{Y8__K1`Ma|7O=v{$BfVGNxT`v4R@Cfj7dDS{K z<_q*Xz{x#+x6bJ1wjzIi3-C=V1+jML1N6?o3BXF$gAMwA2W|&mv(#@1TDlGe_Rk!k zeCh|`_X!|>`y(JwD!Ngt2fw}vutoUE=jW6sfrkK-2!F*2^m4&f$S0@D$H4Qzo4~Ir z;j!y01KR_80-I*kmCu$d`8z{)kcb6n={N;QL6+4%0K7YBME_OZ1~?3mwf7alzPYt! zTY%PJ``pDJz=ObZ4F;?6?G=Ep*h5=xM15#hT7%ZacScX|zXYxZzGybWnT9t2&IQ)* z(Q`w~34gLBXoYa75V#Wfr7`4D^Q!>o1Di+mX_A#uGztA$g1)>bP8Q_L0J#mz zBKL7o4{XKR7q;k7E6|$wPK|U}?&3T{OCIlrEc>b+H*yp3N^RIJKr4>DHL|Rh1)pu; zlT)1Jv#$lZCP*#UPpX|8X#rX>>~WEi-VHpPqJJ=UeQjVTU~6DQVAXK_XW;XYp?e+p zwy@p3fny?d?hLVfVUuz3+Mv~*764sYIK|1b=G>K-0Ba?=BcKIOU(tf&jS!-Jmq|x` zl~s4e*;<9ls;iaSpk;NJMtXNi!D2)?>EkEJhbVHmBjloUAZbx^aYRu6ua?iQ4O&*9 z+<)?T(X#rSoRI_j0!L)Z#>DOip3ZFJn#gipIc&`}RZ30JYU|#}&WPN}OBp?uC7+%l zmm_jxre*II@-X9VYNzI?0$11Dr<$NQ2CnPSrYzi%83`i!WWlMGK9w6e4M_QHC8F*F zy0U&}0iWjF)s#$4(8?(s+oABC9=|FmK4eH!QUx_`sHNfY%E}a|Egk4gKPJgjl zfR?4Ec1rF6)+iZef$R^!(Fu7?h_d{Wvfw};n6XtPAHICaC<|o&0_21HidLSF7qltS zsRXS-rk2@-9F~eN8qn@KV4|1qeKMSRSem)|_v#O(IPi3|-b%}qCt8XhyTU^RJ)buy3o2**C;rx-T`)f%2B0k$AYpOF+5fw+Qc2 zeen;YqzE;*u6(wC>ZbwNSd)6v{Nq)Iz-O!S&#@VSchC+xO<*BJ9qC@qNVrAkk{T%I zpa%lXt?r<6NiAl%Y4XuieLkNYw9)Nz&<@&&fRP%vXa{XXz(|c-w1YMxV5G(^+Cdu; fFjC_dZ3OyX1zbvMqGxkw00000NkvXXu0mjfi8te= diff --git a/Alkitab/src/main/res/drawable-xxxhdpi/ic_attr_has_maps.png b/Alkitab/src/main/res/drawable-xxxhdpi/ic_attr_has_maps.png old mode 100644 new mode 100755 index 5b7a858f3c04356cf61407a89bb19ab1c698681d..348dee2058310b1d35f45ef37aebf1ea68c19eb2 GIT binary patch literal 6029 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 XYCJ0kRfhq`>>zDTJ&hVQhnW8Zm8@Hp delta 2204 zcmV;N2xIq+FQ*ZZBYy~PNkl|4khH-v7Mu3RL9$eJx7gd%I! z?AiD1S+kQRgk)bM3dxq6r5i%`+J)>}mcGoJ*ZccD&&)jgGrx2GeBYVpnRC8#X67t& zo=F%bErCf%b7#z904F{P3}6E|aS0^Oo@uZFoVWxMXU{a)0Dn$g0*SL{8f*Y3E`h|^ zGYvL?6PG~Z?3o4|z==yBarR7u4dC8O;9d_0JNBN#90n$W1{=UB&tSj+Hh|NWfGyEr zdvMR^w=K~<2hcZs1K1~_p8szE_Z-0C;m-xE2uuc+1r`IQdH8!3_!5`}%mm&8eoaLt zDIBsE1*QUP0)JD0MM{G6H82Bs4VVsmRq}bQcJC{|a|0Uz>jSF*v(+TUKY_P_=YeN| zUut?!ZIA66zyfwlU^8H;+N3i6gFgkH1Rm=X(0u`TPGARMD`269fgOF_x4@&oeZX%m zkH!1?J^;KbuqUvxmz!oAyaU_{yw&V$3`65G4N7Mr#jnq3E=I4J%HIG82%i10C*1gKB8Yp(*=MHfbD=KLOQrMe*m`u z_eb=pt!Y;PmgZ{D4Fy*Y2l<#~lWOU$leA>Z_EuO?c6bO0WbMhVYjPI=)}DJr#IpPp zpi`?{icOMSqPqf{2EJ6w^(AfZ$!!Cy)3RoI$bW(AX9w&y-KIs4-02c!C z1$T+$3zv2-7ci)Yfg1waRo(BJ&I$lo9! zuzze^f$Q@vYgs~dsvnKHx01t$g2WEem4SbpO$0gtkd;Ao=yri9@Jz!xoLnE)7{G>1lhS) z#!7db_DbDZ16bYVXDtqB&lG7-|H9>Ay?+6`UXfjWaDbhBbCX`KCIOcAUgXKdkcaA! zlEPlvd7d^I0@OEO1o+d=GxmwEanAp8hFtFPc*z<#swpjQ65uU>13bdJ9k{2UfaOx$ z*_mFUF3-_d$;J2xaCZq8=uW`y9v-d%9xupeRJSGp*2#IboY5(8AiJ`NZ&@C(<9~n^ zqPWj){JuLh74bl6qRBg#7od34ov14sZuVoE0$59zW^G>f<8>}OB9>{{)Cw^wwp%4B zhOE$Ek(3tTNYAKYDclnr31=?!4KCQskQ3ub_!*2p$ zT_=&*lXv6bGT@oW(eDjx8`-C5^9O;OB0Fyk9G25Z;ZB)VwO*5H0$}Ztaye#^4pmyd zW72G73SAnJAP|YonC3cN9}dKrPzr%+Vk>HvMRIW#+2e!xX#!y1fkRFPoqw=nNFF13 zj+!KS*5qM}A^D!=Y{{ac2g~3wGy$+qi?V^UNWNM5XhTU$y_WQWS1Pn$*>-Y_#7VwcZ` zB+}F#Jb0yDABAMEj|ybF0G{{-aDg0J!a=tMRZO%GWF;JiP_iN{4Nlpn_uv6*p=Fdl z1WvLtO2ubHTL5dsp@q-{vg}GLgjN9OHUW+;Wq3}9_GBw%7=Jj~tQcvapo%tYQ-cR% zE>ccdm(^l!Lll+Ia6c<2TtbRnE(k8)vfQjz5WEDy>e|(k{u)eCK;rC~1{=VMOCWLfOoI*J#3hh8d#1q#aN-h3oITTE12}OBB+i~`umPO71QKV@ eG&pg9{}l$lR?>){#|Cr&0000 Date: Tue, 25 Aug 2015 13:24:37 +0800 Subject: [PATCH 04/21] Add example extension app --- extensions/example-imagesharer/.gitignore | 7 + extensions/example-imagesharer/.idea/.name | 1 + .../example-imagesharer/.idea/compiler.xml | 22 ++ .../example-imagesharer/.idea/gradle.xml | 18 ++ .../inspectionProfiles/Project_Default.xml | 16 + .../inspectionProfiles/profiles_settings.xml | 7 + extensions/example-imagesharer/.idea/misc.xml | 294 ++++++++++++++++++ .../example-imagesharer/.idea/modules.xml | 9 + .../.idea/runConfigurations.xml | 12 + extensions/example-imagesharer/.idea/vcs.xml | 6 + extensions/example-imagesharer/app/.gitignore | 1 + .../example-imagesharer/app/build.gradle | 25 ++ .../app/proguard-rules.pro | 17 + .../yuku/shareverseimage/ApplicationTest.java | 13 + .../app/src/main/AndroidManifest.xml | 45 +++ .../alkitab.imagesharer/MainActivity.java | 37 +++ .../ShareVerseActivity.java | 93 ++++++ .../app/src/main/res/layout/activity_main.xml | 16 + .../main/res/layout/activity_share_verse.xml | 16 + .../app/src/main/res/menu/menu_main.xml | 3 + .../src/main/res/menu/menu_share_verse.xml | 3 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../app/src/main/res/values-w820dp/dimens.xml | 6 + .../app/src/main/res/values/dimens.xml | 5 + .../app/src/main/res/values/strings.xml | 5 + .../app/src/main/res/values/styles.xml | 8 + extensions/example-imagesharer/build.gradle | 19 ++ .../example-imagesharer/gradle.properties | 18 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + extensions/example-imagesharer/gradlew | 164 ++++++++++ extensions/example-imagesharer/gradlew.bat | 90 ++++++ .../example-imagesharer/settings.gradle | 1 + 36 files changed, 983 insertions(+) create mode 100644 extensions/example-imagesharer/.gitignore create mode 100644 extensions/example-imagesharer/.idea/.name create mode 100644 extensions/example-imagesharer/.idea/compiler.xml create mode 100644 extensions/example-imagesharer/.idea/gradle.xml create mode 100644 extensions/example-imagesharer/.idea/inspectionProfiles/Project_Default.xml create mode 100644 extensions/example-imagesharer/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 extensions/example-imagesharer/.idea/misc.xml create mode 100644 extensions/example-imagesharer/.idea/modules.xml create mode 100644 extensions/example-imagesharer/.idea/runConfigurations.xml create mode 100644 extensions/example-imagesharer/.idea/vcs.xml create mode 100644 extensions/example-imagesharer/app/.gitignore create mode 100644 extensions/example-imagesharer/app/build.gradle create mode 100644 extensions/example-imagesharer/app/proguard-rules.pro create mode 100644 extensions/example-imagesharer/app/src/androidTest/java/yuku/shareverseimage/ApplicationTest.java create mode 100644 extensions/example-imagesharer/app/src/main/AndroidManifest.xml create mode 100644 extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/MainActivity.java create mode 100644 extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java create mode 100644 extensions/example-imagesharer/app/src/main/res/layout/activity_main.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/layout/activity_share_verse.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/menu/menu_main.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/menu/menu_share_verse.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 extensions/example-imagesharer/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 extensions/example-imagesharer/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 extensions/example-imagesharer/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 extensions/example-imagesharer/app/src/main/res/values-w820dp/dimens.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/values/dimens.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/values/strings.xml create mode 100644 extensions/example-imagesharer/app/src/main/res/values/styles.xml create mode 100644 extensions/example-imagesharer/build.gradle create mode 100644 extensions/example-imagesharer/gradle.properties create mode 100644 extensions/example-imagesharer/gradle/wrapper/gradle-wrapper.jar create mode 100644 extensions/example-imagesharer/gradle/wrapper/gradle-wrapper.properties create mode 100644 extensions/example-imagesharer/gradlew create mode 100644 extensions/example-imagesharer/gradlew.bat create mode 100644 extensions/example-imagesharer/settings.gradle diff --git a/extensions/example-imagesharer/.gitignore b/extensions/example-imagesharer/.gitignore new file mode 100644 index 000000000..9c4de5825 --- /dev/null +++ b/extensions/example-imagesharer/.gitignore @@ -0,0 +1,7 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/extensions/example-imagesharer/.idea/.name b/extensions/example-imagesharer/.idea/.name new file mode 100644 index 000000000..1c956b3fd --- /dev/null +++ b/extensions/example-imagesharer/.idea/.name @@ -0,0 +1 @@ +Share Verse Image \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/compiler.xml b/extensions/example-imagesharer/.idea/compiler.xml new file mode 100644 index 000000000..9a8b7e5c4 --- /dev/null +++ b/extensions/example-imagesharer/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/gradle.xml b/extensions/example-imagesharer/.idea/gradle.xml new file mode 100644 index 000000000..8d2df476e --- /dev/null +++ b/extensions/example-imagesharer/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/inspectionProfiles/Project_Default.xml b/extensions/example-imagesharer/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..c525bddc9 --- /dev/null +++ b/extensions/example-imagesharer/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/inspectionProfiles/profiles_settings.xml b/extensions/example-imagesharer/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..3b312839b --- /dev/null +++ b/extensions/example-imagesharer/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/misc.xml b/extensions/example-imagesharer/.idea/misc.xml new file mode 100644 index 000000000..0efc70650 --- /dev/null +++ b/extensions/example-imagesharer/.idea/misc.xml @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + Abstraction issues + + + Android + + + Android Lint + + + Annotations verifyingGroovy + + + Assignment issues + + + Assignment issuesGroovy + + + Bitwise operation issues + + + Class metrics + + + Class structure + + + Cloning issues + + + Code maturity issues + + + Code style issues + + + Compiler issues + + + Concurrency annotation issues + + + Control FlowGroovy + + + Control flow issues + + + Data flow issues + + + Data flow issuesGroovy + + + Declaration redundancy + + + Declaration redundancyGroovy + + + DeclarationGroovy + + + Dependency issues + + + Encapsulation issues + + + Error handling + + + Error handlingGroovy + + + Finalization issues + + + GPath inspectionsGroovy + + + General + + + Google Cloud Endpoints + + + Gradle + + + Groovy + + + HTML + + + Imports + + + Inheritance issues + + + Initialization issues + + + Internationalization issues + + + J2ME issues + + + JUnit issues + + + Java language level issues + + + Java language level migration aids + + + JavaBeans issues + + + Javadoc issues + + + Logging issues + + + Manifest + + + Maven + + + Memory issues + + + Method MetricsGroovy + + + Method metrics + + + Modularization issues + + + Naming ConventionsGroovy + + + Naming conventions + + + Numeric issues + + + Packaging issues + + + Performance issues + + + Portability issues + + + Potentially confusing code constructsGroovy + + + Probable bugs + + + Probable bugsGradle + + + Probable bugsGroovy + + + Properties Files + + + RELAX NG + + + Resource management issues + + + Security issues + + + Serialization issues + + + Spelling + + + StyleGroovy + + + Threading issues + + + Threading issuesGroovy + + + Validity issuesGroovy + + + Visibility issues + + + XML + + + toString() issues + + + + + Convert2Lambda + + + + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/modules.xml b/extensions/example-imagesharer/.idea/modules.xml new file mode 100644 index 000000000..e1b8b3058 --- /dev/null +++ b/extensions/example-imagesharer/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/runConfigurations.xml b/extensions/example-imagesharer/.idea/runConfigurations.xml new file mode 100644 index 000000000..7f68460d8 --- /dev/null +++ b/extensions/example-imagesharer/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/.idea/vcs.xml b/extensions/example-imagesharer/.idea/vcs.xml new file mode 100644 index 000000000..6564d52db --- /dev/null +++ b/extensions/example-imagesharer/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/extensions/example-imagesharer/app/.gitignore b/extensions/example-imagesharer/app/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/extensions/example-imagesharer/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/extensions/example-imagesharer/app/build.gradle b/extensions/example-imagesharer/app/build.gradle new file mode 100644 index 000000000..11e5570da --- /dev/null +++ b/extensions/example-imagesharer/app/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.0" + + defaultConfig { + applicationId "yuku.alkitab.imagesharer" + minSdkVersion 14 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:23.0.0' +} diff --git a/extensions/example-imagesharer/app/proguard-rules.pro b/extensions/example-imagesharer/app/proguard-rules.pro new file mode 100644 index 000000000..f665b348c --- /dev/null +++ b/extensions/example-imagesharer/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Developer/android-sdk-macosx/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/extensions/example-imagesharer/app/src/androidTest/java/yuku/shareverseimage/ApplicationTest.java b/extensions/example-imagesharer/app/src/androidTest/java/yuku/shareverseimage/ApplicationTest.java new file mode 100644 index 000000000..f586e3671 --- /dev/null +++ b/extensions/example-imagesharer/app/src/androidTest/java/yuku/shareverseimage/ApplicationTest.java @@ -0,0 +1,13 @@ +package yuku.shareverseimage; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/extensions/example-imagesharer/app/src/main/AndroidManifest.xml b/extensions/example-imagesharer/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..c3ac189da --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/MainActivity.java b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/MainActivity.java new file mode 100644 index 000000000..c95eccd5e --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/MainActivity.java @@ -0,0 +1,37 @@ +package yuku.alkitab.imagesharer; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.Menu; +import android.view.MenuItem; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java new file mode 100644 index 000000000..39effdb1f --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java @@ -0,0 +1,93 @@ +package yuku.alkitab.imagesharer; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.ShareCompat; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class ShareVerseActivity extends AppCompatActivity { + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // get the selected verse and its text + Intent intent = getIntent(); + int[] aris = intent.getIntArrayExtra("aris"); + String[] verseTexts = intent.getStringArrayExtra("verseTexts"); + + // safety check + if (aris == null || aris.length < 1 || verseTexts == null || verseTexts.length < 1) { + finish(); + return; + } + + // this example does not support multiple verses + // so use the first one only + int book = (aris[0] & 0xff0000) >> 16; + int chapter = (aris[0] & 0xff00) >> 8; + int verse = aris[0] & 0xff; + + // get the name of book + String bookName = "unknown"; + if (book < 66) { + bookName = new String[] {"Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"}[book]; + } + + // construct a reference string: Bookname chapter:verse + String reference = bookName + " " + chapter + ":" + verse; + + // draw on a bitmap + Bitmap b = Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(b); + Paint p = new Paint(); + p.setColor(0xff0000ff); // blue + + c.drawText(reference, 40, 200, p); + c.drawText(verseTexts[0], 40, 400, p); + + // save as image and share + try { + FileOutputStream f = new FileOutputStream("/sdcard/tmp.png"); + b.compress(Bitmap.CompressFormat.PNG, 100, f); + f.close(); + + ShareCompat.IntentBuilder.from(this) + .addStream(Uri.fromFile(new File("/sdcard/tmp.png"))) + .startChooser(); + } catch (IOException e) { + Log.e("Error", "error saving image", e); // do something + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_share_verse, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/extensions/example-imagesharer/app/src/main/res/layout/activity_main.xml b/extensions/example-imagesharer/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..6a00c98f1 --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/extensions/example-imagesharer/app/src/main/res/layout/activity_share_verse.xml b/extensions/example-imagesharer/app/src/main/res/layout/activity_share_verse.xml new file mode 100644 index 000000000..1f4de010d --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/layout/activity_share_verse.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/extensions/example-imagesharer/app/src/main/res/menu/menu_main.xml b/extensions/example-imagesharer/app/src/main/res/menu/menu_main.xml new file mode 100644 index 000000000..9d7f9ce7f --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,3 @@ + + + diff --git a/extensions/example-imagesharer/app/src/main/res/menu/menu_share_verse.xml b/extensions/example-imagesharer/app/src/main/res/menu/menu_share_verse.xml new file mode 100644 index 000000000..6b6ed421c --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/menu/menu_share_verse.xml @@ -0,0 +1,3 @@ + + + diff --git a/extensions/example-imagesharer/app/src/main/res/mipmap-hdpi/ic_launcher.png b/extensions/example-imagesharer/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cde69bcccec65160d92116f20ffce4fce0b5245c GIT binary patch literal 3418 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 literal 0 HcmV?d00001 diff --git a/extensions/example-imagesharer/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/extensions/example-imagesharer/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..bfa42f0e7b91d006d22352c9ff2f134e504e3c1d GIT binary patch literal 4842 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 literal 0 HcmV?d00001 diff --git a/extensions/example-imagesharer/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/extensions/example-imagesharer/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..324e72cdd7480cb983fa1bcc7ce686e51ef87fe7 GIT binary patch literal 7718 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 literal 0 HcmV?d00001 diff --git a/extensions/example-imagesharer/app/src/main/res/values-w820dp/dimens.xml b/extensions/example-imagesharer/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 000000000..63fc81644 --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/extensions/example-imagesharer/app/src/main/res/values/dimens.xml b/extensions/example-imagesharer/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000..7e8d6053e --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/extensions/example-imagesharer/app/src/main/res/values/strings.xml b/extensions/example-imagesharer/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..0a7873226 --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + Share Verse Image + + Settings + diff --git a/extensions/example-imagesharer/app/src/main/res/values/styles.xml b/extensions/example-imagesharer/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..abb36af11 --- /dev/null +++ b/extensions/example-imagesharer/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/extensions/example-imagesharer/build.gradle b/extensions/example-imagesharer/build.gradle new file mode 100644 index 000000000..9405f3fd1 --- /dev/null +++ b/extensions/example-imagesharer/build.gradle @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.2.3' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/extensions/example-imagesharer/gradle.properties b/extensions/example-imagesharer/gradle.properties new file mode 100644 index 000000000..1d3591c8a --- /dev/null +++ b/extensions/example-imagesharer/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true \ No newline at end of file diff --git a/extensions/example-imagesharer/gradle/wrapper/gradle-wrapper.jar b/extensions/example-imagesharer/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..8c0fb64a8698b08ecc4158d828ca593c4928e9dd GIT binary patch literal 49896 zcmagFb986H(k`5d^NVfUwr$(C?M#x1ZQHiZiEVpg+jrjgoQrerx!>1o_ul)D>ebz~ zs=Mmxr&>W81QY-S1PKWQ%N-;H^tS;2*XwVA`dej1RRn1z<;3VgfE4~kaG`A%QSPsR z#ovnZe+tS9%1MfeDyz`RirvdjPRK~p(#^q2(^5@O&NM19EHdvN-A&StN>0g6QA^VN z0Gx%Gq#PD$QMRFzmK+utjS^Y1F0e8&u&^=w5K<;4Rz|i3A=o|IKLY+g`iK6vfr9?+ z-`>gmU&i?FGSL5&F?TXFu`&Js6h;15QFkXp2M1H9|Eq~bpov-GU(uz%mH0n55wUl- zv#~ccAz`F5wlQ>e_KlJS3@{)B?^v*EQM=IxLa&76^y51a((wq|2-`qON>+4dLc{Oo z51}}o^Zen(oAjxDK7b++9_Yg`67p$bPo3~BCpGM7uAWmvIhWc5Gi+gQZ|Pwa-Gll@<1xmcPy z|NZmu6m)g5Ftu~BG&Xdxclw7Cij{xbBMBn-LMII#Slp`AElb&2^Hw+w>(3crLH!;I zN+Vk$D+wP1#^!MDCiad@vM>H#6+`Ct#~6VHL4lzmy;lSdk>`z6)=>Wh15Q2)dQtGqvn0vJU@+(B5{MUc*qs4!T+V=q=wy)<6$~ z!G>e_4dN@lGeF_$q9`Ju6Ncb*x?O7=l{anm7Eahuj_6lA{*#Gv*TaJclevPVbbVYu z(NY?5q+xxbO6%g1xF0r@Ix8fJ~u)VRUp`S%&rN$&e!Od`~s+64J z5*)*WSi*i{k%JjMSIN#X;jC{HG$-^iX+5f5BGOIHWAl*%15Z#!xntpk($-EGKCzKa zT7{siZ9;4TICsWQ$pu&wKZQTCvpI$Xvzwxoi+XkkpeE&&kFb!B?h2hi%^YlXt|-@5 zHJ~%AN!g_^tmn1?HSm^|gCE#!GRtK2(L{9pL#hp0xh zME}|DB>(5)`iE7CM)&_+S}-Bslc#@B5W4_+k4Cp$l>iVyg$KP>CN?SVGZ(&02>iZK zB<^HP$g$Lq*L$BWd?2(F?-MUbNWTJVQdW7$#8a|k_30#vHAD1Z{c#p;bETk0VnU5A zBgLe2HFJ3032$G<`m*OB!KM$*sdM20jm)It5OSru@tXpK5LT>#8)N!*skNu1$TpIw zufjjdp#lyH5bZ%|Iuo|iu9vG1HrIVWLH>278xo>aVBkPN3V$~!=KnlXQ4eDqS7%E% zQ!z^$Q$b^6Q)g#cLpwur(|<0gWHo6A6jc;n`t(V9T;LzTAU{IAu*uEQ%Ort1k+Kn+f_N`9|bxYC+~Z1 zCC1UCWv*Orx$_@ydv9mIe(liLfOr7mhbV@tKw{6)q^1DH1nmvZ0cj215R<~&I<4S| zgnr;9Cdjqpz#o8i0CQjtl`}{c*P)aSdH|abxGdrR)-3z+02-eX(k*B)Uqv6~^nh** z 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/extensions/example-imagesharer/gradlew.bat b/extensions/example-imagesharer/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/extensions/example-imagesharer/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/extensions/example-imagesharer/settings.gradle b/extensions/example-imagesharer/settings.gradle new file mode 100644 index 000000000..e7b4def49 --- /dev/null +++ b/extensions/example-imagesharer/settings.gradle @@ -0,0 +1 @@ +include ':app' From 23fdff2168c7ae469d05f9dab1a11cca4699886e Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 13:57:30 +0800 Subject: [PATCH 05/21] Remove unused yuku.afw.rpc --- .../main/java/yuku/afw/rpc/AsyncRequest.java | 244 ------------------ Afw/src/main/java/yuku/afw/rpc/BaseData.java | 8 - Afw/src/main/java/yuku/afw/rpc/Headers.java | 39 --- .../main/java/yuku/afw/rpc/HttpPerformer.java | 140 ---------- Afw/src/main/java/yuku/afw/rpc/ImageData.java | 63 ----- .../afw/rpc/JsonResponseDataProcessor.java | 7 - Afw/src/main/java/yuku/afw/rpc/NullOk.java | 12 - Afw/src/main/java/yuku/afw/rpc/Params.java | 132 ---------- .../afw/rpc/RawResponseDataProcessor.java | 6 - Afw/src/main/java/yuku/afw/rpc/Request.java | 53 ---- Afw/src/main/java/yuku/afw/rpc/Response.java | 46 ---- .../java/yuku/afw/rpc/ResponseProcessor.java | 8 - Afw/src/main/java/yuku/afw/rpc/UrlLoader.java | 77 ------ 13 files changed, 835 deletions(-) delete mode 100644 Afw/src/main/java/yuku/afw/rpc/AsyncRequest.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/BaseData.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/Headers.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/HttpPerformer.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/ImageData.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/JsonResponseDataProcessor.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/NullOk.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/Params.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/RawResponseDataProcessor.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/Request.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/Response.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/ResponseProcessor.java delete mode 100644 Afw/src/main/java/yuku/afw/rpc/UrlLoader.java diff --git a/Afw/src/main/java/yuku/afw/rpc/AsyncRequest.java b/Afw/src/main/java/yuku/afw/rpc/AsyncRequest.java deleted file mode 100644 index 815ced69d..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/AsyncRequest.java +++ /dev/null @@ -1,244 +0,0 @@ -package yuku.afw.rpc; - -import android.content.Context; -import android.os.AsyncTask; -import android.os.SystemClock; -import android.util.Log; -import android.util.SparseArray; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import yuku.afw.App; -import yuku.afw.D; -import yuku.afw.rpc.Response.Validity; - -/** - * Listener tree: - * - OnResponse - * - OnSuccess - * - OnFailed - * - OnApiError - * - * When a listener returns false, the parent listener will be called. Otherwise no more listeners will be called. - */ -public class AsyncRequest { - public static final String TAG = AsyncRequest.class.getSimpleName(); - - protected static List onLoadingStatusChangedListeners = new ArrayList(16); - protected static AtomicInteger activeCount = new AtomicInteger(0); - protected static AtomicInteger serialNumber = new AtomicInteger(0); - - private static Object onLoadingStatusChangedListeners_lock = new Object(); - - public enum LoadingStatus { - Start, - Stop, - } - - public interface OnLoadingStatusChangedListener { - void onLoadingStatusChanged(LoadingStatus status, int activeCount); - } - - protected void onSuccess(Response response, Z data) { - } - - protected void onFailed(Response response, Z data) { - } - - protected void onResponse(Response response, Z data) { - } - - protected void onApiError(Response response, Z data) { - } - - private final Request request; - private Z data; - private Task task; - private SparseArray tags; - private boolean finished = false; - private int id; - private boolean consumed; - - public AsyncRequest(Request request, Z data) { - this.request = request; - this.data = data; - this.task = new Task(); - this.id = serialNumber.incrementAndGet(); - } - - public void cancel() { - task.cancel(false); - finished = true; - } - - public synchronized void setTag(Object tag) { - setTag(0, tag); - } - - public synchronized void setTag(int id, Object tag) { - if (tags == null) { - tags = new SparseArray(2); - } - tags.put(id, tag); - } - - public synchronized T getTag() { - return this.getTag(0); - } - - @SuppressWarnings("unchecked") - public synchronized T getTag(int id) { - return (T) tags.get(id); - } - - public class Task extends AsyncTask { - final Z return_data; // should be never null - Response return_response; - Request request; - - public Task() { - return_data = AsyncRequest.this.data; - } - - @Override protected Void doInBackground(Request... params) { - request = params[0]; - - HttpPerformer httpPerformer = new HttpPerformer(this, request); - if (D.EBUG) Log.d(TAG, "async start [" + id + "] (" + getActiveCount() + " active, total " + Thread.activeCount() + " threads) " + request.toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - return_response = httpPerformer.perform(); - - if (return_data.isSuccessResponse(return_response)) { - ResponseProcessor rp = return_data.getResponseProcessor(return_response); - try { - rp.process(return_response.data); - } catch (Exception e) { - return_response.validity = Validity.ProcessError; - Log.w(TAG, "Error during ResponseProcessor#process", e); - } - } - - return null; - } - - @Override protected void onCancelled() { - return_response = new Response(request, Validity.Cancelled, "cancelled from asynctask#onCancelled"); - onPostExecute(null); //$NON-NLS-1$ - } - - @Override protected void onPostExecute(Void result) { - if (D.EBUG) Log.d(TAG, "async stop [" + id + "] response: " + return_response.toString()); //$NON-NLS-1$//$NON-NLS-2$ - - try { - onReceiveResponse(return_response, return_data); - } finally { - trackStop(); - } - } - } - - public static void trackStop() { - int activeCount = AsyncRequest.activeCount.decrementAndGet(); - synchronized (onLoadingStatusChangedListeners) { - for (int i = 0, len = onLoadingStatusChangedListeners.size(); i < len; i++) { - onLoadingStatusChangedListeners.get(i).onLoadingStatusChanged(LoadingStatus.Stop, activeCount); - } - } - } - - protected void onReceiveResponse(Response response, Z data) { - if (data.isSuccessResponse(response)) { - onSuccess(response, data); - } else { - if (response.validity == Validity.IoError) { - showErrorToastIfNoRecentErrorToast(App.context, "Network error"); - } else if (response.validity == Validity.JsonError) { - showErrorToastIfNoRecentErrorToast(App.context, "Response from network error"); - } - - if (response.validity == Validity.Ok) { - onApiError(response, data); - } - - if (! consumed) { - onFailed(response, data); - } - } - - if (! consumed) { - onResponse(response, data); - } - - this.finished = true; - } - - private static long lastErrorToastTime = -1; - - private static void showErrorToastIfNoRecentErrorToast(Context context, String msg) { - long now = SystemClock.uptimeMillis(); - - if (lastErrorToastTime == -1 || now - lastErrorToastTime > 2000L) { - Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); - lastErrorToastTime = now; - } - } - - public static void setLastErrorToastTime(long lastErrorToastTime) { - AsyncRequest.lastErrorToastTime = lastErrorToastTime; - } - - public AsyncRequest start() { - trackStart(); - task.execute(request); - return this; - } - - public static void trackStart() { - int activeCount = AsyncRequest.activeCount.incrementAndGet(); - synchronized (onLoadingStatusChangedListeners_lock) { - for (int i = 0, len = onLoadingStatusChangedListeners.size(); i < len; i++) { - onLoadingStatusChangedListeners.get(i).onLoadingStatusChanged(LoadingStatus.Start, activeCount); - } - } - } - - public Request getRequest() { - return request; - } - - public static void addOnLoadingStatusChangedListener(OnLoadingStatusChangedListener onLoadingStatusChangedListener) { - synchronized (onLoadingStatusChangedListeners_lock) { - onLoadingStatusChangedListeners.add(onLoadingStatusChangedListener); - } - } - - public static void removeOnLoadingStatusChangedListener(OnLoadingStatusChangedListener onLoadingStatusChangedListener) { - synchronized (onLoadingStatusChangedListeners_lock) { - onLoadingStatusChangedListeners.remove(onLoadingStatusChangedListener); - } - } - - public static int getActiveCount() { - return activeCount.get(); - } - - /** - * Used to determine if this request has no more effect and hence safe to do additional requests whose response - * may conflict with the currently executing request's response. - * @return true if this task has been returned with a response OR {@link #cancel()} has been called. - */ - public boolean isFinished() { - return finished; - } - - public boolean isCancelled() { - return task.isCancelled(); - } - - protected void consume() { - consumed = true; - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/BaseData.java b/Afw/src/main/java/yuku/afw/rpc/BaseData.java deleted file mode 100644 index eb3eb19cc..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/BaseData.java +++ /dev/null @@ -1,8 +0,0 @@ -package yuku.afw.rpc; - -public abstract class BaseData { - public static final String TAG = BaseData.class.getSimpleName(); - - public abstract boolean isSuccessResponse(Response response); - public abstract ResponseProcessor getResponseProcessor(Response response); -} diff --git a/Afw/src/main/java/yuku/afw/rpc/Headers.java b/Afw/src/main/java/yuku/afw/rpc/Headers.java deleted file mode 100644 index d2bcbd6e4..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/Headers.java +++ /dev/null @@ -1,39 +0,0 @@ -package yuku.afw.rpc; - -import java.util.LinkedHashMap; -import java.util.Map.Entry; - -import org.apache.http.client.methods.HttpRequestBase; - -public class Headers { - public static final String TAG = Headers.class.getSimpleName(); - - LinkedHashMap map = new LinkedHashMap(); - - public void put(String key, String value) { - map.put(key, value); - } - - public void put(String key, long value) { - map.put(key, String.valueOf(value)); - } - - public boolean has(String key) { - return map.containsKey(key); - } - - public void addTo(HttpRequestBase httpRequestBase) { - for (Entry entry: map.entrySet()) { - httpRequestBase.addHeader(entry.getKey(), entry.getValue()); - } - } - - public void addDebugString(StringBuilder sb) { - for (String key: map.keySet()) { - String value = map.get(key); - if (value.length() > 80) value = "(len=" + value.length() + ")" + value.substring(0, 78) + "..."; //$NON-NLS-1$ - sb.append(' '); - sb.append(key).append('=').append(value); - } - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/HttpPerformer.java b/Afw/src/main/java/yuku/afw/rpc/HttpPerformer.java deleted file mode 100644 index d2668d7d6..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/HttpPerformer.java +++ /dev/null @@ -1,140 +0,0 @@ -package yuku.afw.rpc; - -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.zip.GZIPInputStream; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -import yuku.afw.rpc.Request.Method; -import yuku.afw.rpc.Request.OptionsKey; -import yuku.afw.rpc.Response.Validity; - -public class HttpPerformer { - public static final String TAG = HttpPerformer.class.getSimpleName(); - private final Request request; - private final AsyncRequest.Task task; - - /** - * @param task can be null if cancel is not supported - */ - public HttpPerformer(@NullOk AsyncRequest.Task task, Request request) { - this.task = task; - this.request = request; - } - - public Response perform() { - String url = request.url; - - DefaultHttpClient client = new DefaultHttpClient(); - HttpParams httpParams = client.getParams(); - - if (request.options != null && request.options.get(OptionsKey.connectionTimeout) != null) { - HttpConnectionParams.setConnectionTimeout(httpParams, (Integer) request.options.get(OptionsKey.connectionTimeout)); - } else { - HttpConnectionParams.setConnectionTimeout(httpParams, 30000); // 30 seconds for connection timeout - } - - if (request.options != null && request.options.get(OptionsKey.soTimeout) != null) { - HttpConnectionParams.setSoTimeout(httpParams, (Integer) request.options.get(OptionsKey.soTimeout)); - } else { - HttpConnectionParams.setSoTimeout(httpParams, 15000); // 15 seconds for waiting for data - } - - ByteArrayOutputStream os = new ByteArrayOutputStream(256); // TODO make it more efficient by not buffering byte[] - int httpResponseCode = 0; - - try { - HttpRequestBase base = null; - - if (request.method == Method.GET || request.method == Method.GET_RAW) { - url += request.params.toUrlEncodedStringWithOptionalQuestionMark(); - - base = new HttpGet(url); - } else if (request.method == Method.GET_DIGEST) { - client.getCredentialsProvider().setCredentials(new AuthScope(null, -1), new UsernamePasswordCredentials(request.params.getAndRemove("email"), request.params.getAndRemove("passwd"))); //$NON-NLS-1$//$NON-NLS-2$ - - url += request.params.toUrlEncodedStringWithOptionalQuestionMark(); - - base = new HttpGet(url); - } else if (request.method == Method.POST) { - HttpPost method = new HttpPost(url); - - // use params as usual - ArrayList list = new ArrayList(); - request.params.addAllTo(list); - method.setEntity(new UrlEncodedFormEntity(list, "utf-8")); //$NON-NLS-1$ - - base = method; - } else if (request.method == Method.DELETE) { - url += request.params.toUrlEncodedStringWithOptionalQuestionMark(); - - base = new HttpDelete(url); - } else { - throw new RuntimeException("http method " + request.method + " not supported yet"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - request.headers.addTo(base); - base.addHeader("Cache-Control", "no-cache"); //$NON-NLS-1$//$NON-NLS-2$ - base.addHeader("Accept-Encoding", "gzip"); //$NON-NLS-1$ //$NON-NLS-2$ - - HttpResponse response = client.execute(base); - httpResponseCode = response.getStatusLine().getStatusCode(); - - if (task != null && task.isCancelled()) { - base.abort(); - } else { - Header encodingHeader = response.getFirstHeader("Content-Encoding"); //$NON-NLS-1$ - HttpEntity entity = response.getEntity(); - InputStream content = entity.getContent(); - - try { - if (encodingHeader != null && encodingHeader.getValue().equalsIgnoreCase("gzip")) { //$NON-NLS-1$ - content = new GZIPInputStream(content); - } - - byte[] buf = new byte[4096 * 4]; - while (true) { - int read = content.read(buf); - if (read <= 0) break; - - os.write(buf, 0, read); - - if (task != null && task.isCancelled()) { - base.abort(); - break; - } - } - } finally { - if (content != null) content.close(); - } - } - } catch (IOException e) { - Log.d(TAG, "IoError: " + e.getClass().getSimpleName() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ - return new Response(this.request, Validity.IoError, e.getClass().getName() + ": " + e.getMessage()); //$NON-NLS-1$ - } - - if (task != null && task.isCancelled()) { - return new Response(this.request, Validity.Cancelled, "cancelled"); //$NON-NLS-1$ - } - - return new Response(this.request, os.toByteArray(), httpResponseCode); - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/ImageData.java b/Afw/src/main/java/yuku/afw/rpc/ImageData.java deleted file mode 100644 index 0b106e2fd..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/ImageData.java +++ /dev/null @@ -1,63 +0,0 @@ -package yuku.afw.rpc; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.BitmapFactory.Options; -import android.util.Log; - -import yuku.afw.D; - -public abstract class ImageData extends BaseData { - public static final String TAG = ImageData.class.getSimpleName(); - - public Bitmap bitmap; - public Options opts; - - public class ImageProcessor implements ResponseProcessor { - private int maxPixels = 0; - - public void setMaxPixels(int maxPixels) { - this.maxPixels = maxPixels; - } - - @Override public void process(byte[] raw) throws Exception { - opts = new Options(); - - if (maxPixels != 0) { - opts.inJustDecodeBounds = true; - BitmapFactory.decodeByteArray(raw, 0, raw.length, opts); - - if (opts.outHeight == -1 || opts.outWidth == -1) { - return; - } - - int pixels = opts.outHeight * opts.outWidth; - int downscale = 1; - while (true) { - if (D.EBUG) Log.d(TAG, "maxpixels: " + maxPixels + " pixels: " + pixels + " downscale: " + downscale + " pixels/downscale/downscale: " + (pixels / downscale / downscale)); - if (pixels / downscale / downscale > maxPixels) { - downscale++; - } else { - break; - } - if (downscale >= 10) { - break; - } - } - - opts.inJustDecodeBounds = false; - opts.inSampleSize = downscale; - opts.outHeight = -1; - opts.outWidth = -1; - - bitmap = BitmapFactory.decodeByteArray(raw, 0, raw.length, opts); - } else { - bitmap = BitmapFactory.decodeByteArray(raw, 0, raw.length, opts); - } - } - } - - @Override public ResponseProcessor getResponseProcessor(Response response) { - return new ImageProcessor(); - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/JsonResponseDataProcessor.java b/Afw/src/main/java/yuku/afw/rpc/JsonResponseDataProcessor.java deleted file mode 100644 index cbda547e9..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/JsonResponseDataProcessor.java +++ /dev/null @@ -1,7 +0,0 @@ -package yuku.afw.rpc; - -import org.json.JSONObject; - -public interface JsonResponseDataProcessor { - void processJsonResponse(JSONObject json); -} diff --git a/Afw/src/main/java/yuku/afw/rpc/NullOk.java b/Afw/src/main/java/yuku/afw/rpc/NullOk.java deleted file mode 100644 index 95ed656d2..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/NullOk.java +++ /dev/null @@ -1,12 +0,0 @@ -package yuku.afw.rpc; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Just to document that the parameter may be null */ -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.PARAMETER) -public @interface NullOk { -} diff --git a/Afw/src/main/java/yuku/afw/rpc/Params.java b/Afw/src/main/java/yuku/afw/rpc/Params.java deleted file mode 100644 index d29ced255..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/Params.java +++ /dev/null @@ -1,132 +0,0 @@ -package yuku.afw.rpc; - -import android.net.Uri; -import android.util.Log; - -import java.util.List; - -import org.apache.http.NameValuePair; -import org.apache.http.message.BasicNameValuePair; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public class Params { - public static final String TAG = Params.class.getSimpleName(); - - private JSONObject map = new JSONObject(); - - public void put(String key, String value) { - try { - map.put(key, value); - } catch (JSONException e) { - Log.e(TAG, "json exception", e); //$NON-NLS-1$ - } - } - - public void put(String key, double value) { - put(key, String.valueOf(value)); - } - - public void put(String key, long value) { - put(key, String.valueOf(value)); - } - - public void put(String key, int value) { - put(key, String.valueOf(value)); - } - - public void put(String key, List value) { - JSONArray jsonArray = new JSONArray(value); - try { - map.put(key, jsonArray); - } catch (JSONException e) { - Log.e(TAG, "json exception", e); //$NON-NLS-1$ - } - } - - public void put(String key, JSONArray value) { - try { - map.put(key, value); - } catch (JSONException e) { - Log.e(TAG, "json exception", e); //$NON-NLS-1$ - } - } - - public String toJsonString() { - return map.toString(); - } - - public void addDebugString(StringBuilder sb) { - JSONArray names = map.names(); - if (names == null) return; - - for (int i = 0, len = names.length(); i < len; i++) { - String key = names.optString(i); - String value = map.optString(key); - if (value.length() > 80) value = "(len=" + value.length() + ")" + value.substring(0, 78) + "..."; //$NON-NLS-1$ - sb.append(' '); - sb.append(key).append('=').append(value); - } - } - - public String toUrlEncodedString() { - StringBuilder sb = new StringBuilder(256); - addUrlEncodedParamsTo(sb); - return sb.toString(); - } - - public String toUrlEncodedStringWithOptionalQuestionMark() { - if (map.length() == 0) { - return ""; //$NON-NLS-1$ - } - StringBuilder sb = new StringBuilder(256); - sb.append('?'); - addUrlEncodedParamsTo(sb); - return sb.toString(); - } - - private void addUrlEncodedParamsTo(StringBuilder sb) { - JSONArray names = map.names(); - for (int i = 0, len = names.length(); i < len; i++) { - String key = names.optString(i); - String value = map.optString(key); - if (sb.length() > 1) { // not (empty or contains only '?') - sb.append('&'); - } - sb.append(key).append('=').append(Uri.encode(value)); - } - } - - public String getAndRemove(String key) { - if (map.has(key)) { - String value = map.optString(key); - map.remove(key); - return value; - } - return null; - } - - public String get(String key) { - if (map.has(key)) { - return map.optString(key); - } - return null; - } - - public JSONArray getJsonArray(String key) { - if (map.has(key)) { - return map.optJSONArray(key); - } - return null; - } - - public void addAllTo(List list) { - JSONArray names = map.names(); - for (int i = 0, len = names.length(); i < len; i++) { - String key = names.optString(i); - String value = map.optString(key); - list.add(new BasicNameValuePair(key, value)); - } - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/RawResponseDataProcessor.java b/Afw/src/main/java/yuku/afw/rpc/RawResponseDataProcessor.java deleted file mode 100644 index 28276e72b..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/RawResponseDataProcessor.java +++ /dev/null @@ -1,6 +0,0 @@ -package yuku.afw.rpc; - - -public interface RawResponseDataProcessor { - void processRawResponse(byte[] raw); -} diff --git a/Afw/src/main/java/yuku/afw/rpc/Request.java b/Afw/src/main/java/yuku/afw/rpc/Request.java deleted file mode 100644 index 3ff175e11..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/Request.java +++ /dev/null @@ -1,53 +0,0 @@ -package yuku.afw.rpc; - -import java.util.EnumMap; - -public class Request { - public static final String TAG = Request.class.getSimpleName(); - - public enum Method { - GET, - GET_DIGEST, - GET_RAW, - POST, - DELETE, - // no PUT because it can be replaced with POST - } - - public enum OptionsKey { - /** int, default 10000 (10 sec timeout) */ - connectionTimeout, - /** int, default 5000 (5 sec timeout) */ - soTimeout, - /** bool, default true (encapsulate in params) */ - encapsulateParams, - } - - public static class Options extends EnumMap { - public Options() { - super(OptionsKey.class); - } - } - - public Method method; - public String url; - public Headers headers = new Headers(); - public Params params = new Params(); - public Options options; - - public Request(Method method, String path) { - this.method = method; - this.url = path; - } - - @Override - public String toString() { - StringBuilder debugInfo = new StringBuilder(100); - debugInfo.append(method.name()); - debugInfo.append(' ').append(url).append(" params:"); //$NON-NLS-1$ - params.addDebugString(debugInfo); - debugInfo.append(" headers:"); //$NON-NLS-1$ - headers.addDebugString(debugInfo); - return debugInfo.toString(); - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/Response.java b/Afw/src/main/java/yuku/afw/rpc/Response.java deleted file mode 100644 index b3e3157e1..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/Response.java +++ /dev/null @@ -1,46 +0,0 @@ -package yuku.afw.rpc; - -import yuku.afw.rpc.Request.Method; - -public class Response { - public static final String TAG = Response.class.getSimpleName(); - - public enum Validity { - Ok, - Cancelled, - JsonError, - IoError, - ProcessError, - } - - public Validity validity; - public final int code; - public final Request request; - public final String message; - public final byte[] data; - - public Response(Request request, Validity validity, String message) { - this.request = request; - this.validity = validity; - this.code = 0; - this.message = message; - this.data = null; - } - - /** for {@link yuku.afw.rpc.Request.Method#GET_RAW} */ - public Response(Request request, byte[] raw, int code) { - this.request = request; - this.validity = Validity.Ok; - this.code = 0; - this.message = null; - this.data = raw; - } - - @SuppressWarnings("unchecked") public T getData() { - return (T) data; - } - - @Override public String toString() { - return "Response{" + validity + " " + code + " message=" + message + " data=" + (data == null? "null": "len " + data.length) + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } -} diff --git a/Afw/src/main/java/yuku/afw/rpc/ResponseProcessor.java b/Afw/src/main/java/yuku/afw/rpc/ResponseProcessor.java deleted file mode 100644 index 9266a9768..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/ResponseProcessor.java +++ /dev/null @@ -1,8 +0,0 @@ -package yuku.afw.rpc; - - -public interface ResponseProcessor { - public static final String TAG = ResponseProcessor.class.getSimpleName(); - - void process(byte[] raw) throws Exception; -} diff --git a/Afw/src/main/java/yuku/afw/rpc/UrlLoader.java b/Afw/src/main/java/yuku/afw/rpc/UrlLoader.java deleted file mode 100644 index b156507a3..000000000 --- a/Afw/src/main/java/yuku/afw/rpc/UrlLoader.java +++ /dev/null @@ -1,77 +0,0 @@ -package yuku.afw.rpc; - -import android.content.Context; -import android.os.SystemClock; -import android.util.Log; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import yuku.afw.D; - -public class UrlLoader { - public static final String TAG = UrlLoader.class.getSimpleName(); - - static class Data { - List listeners; - long startTime; - } - - Map running = new LinkedHashMap(); - - public interface Listener { - void onResponse(String url, Response response, BaseData data, boolean firstTime); - } - - /** must call this from main thread */ - public synchronized boolean load(Context context, final String url, ImageData imageData, Listener listener) { - Data data = running.get(url); - if (data == null) { - // not running, create new - final Data newData = new Data(); - newData.startTime = SystemClock.uptimeMillis(); - newData.listeners = new ArrayList(4); - newData.listeners.add(listener); - // save - running.put(url, newData); - - if (D.EBUG) Log.d(TAG, "Loading url: " + url + " creates a new request with 1 listener"); - - new AsyncRequest(new UrlImage(url), imageData) { - @Override protected void onResponse(Response response, ImageData imageData) { - long responseTime = SystemClock.uptimeMillis(); - // call all listeners and remove from map - try { - boolean firstTime = true; - for (int i = 0, len = newData.listeners.size(); i < len; i++) { - newData.listeners.get(i).onResponse(url, response, imageData, firstTime); - firstTime = false; - } - } finally { - running.remove(url); - - long endTime = SystemClock.uptimeMillis(); - if (D.EBUG) Log.d(UrlLoader.TAG, "Loading url: " + url + " finished. Loaded in " + (responseTime - newData.startTime) + " ms, callback in " + (endTime - responseTime) + " ms"); - } - }; - }.start(); - - return true; - } else { - // just add listeners - data.listeners.add(listener); - - if (D.EBUG) Log.d(TAG, "Loading url: " + url + " uses existing request, now it has " + data.listeners.size() + " listeners"); - - return false; - } - } - - private static class UrlImage extends Request { - public UrlImage(String url) { - super(Method.GET_RAW, url); - } - } -} From 9a9e24f4b46b0eaed6124ba6df763b29ceb9d6e2 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 14:52:32 +0800 Subject: [PATCH 06/21] Use rootProject trick to specify sdk and build tool versions --- ATree/build.gradle | 8 ++++---- Afw/build.gradle | 10 ++++------ Alkitab/build.gradle | 8 ++++---- AlkitabFeedback/build.gradle | 10 +++++----- AlkitabIntegration/build.gradle | 8 ++++---- AlkitabIo/build.gradle | 8 ++++---- AlkitabModel/build.gradle | 8 ++++---- AlkitabYes2/build.gradle | 8 ++++---- AmbilWarna/build.gradle | 8 ++++---- BiblePlus/build.gradle | 8 ++++---- BintexReader/build.gradle | 8 ++++---- BintexWriter/build.gradle | 8 ++++---- DragSortListView/build.gradle | 8 ++++---- FileChooser/build.gradle | 8 ++++---- FlowLayout/build.gradle | 8 ++++---- ImportedDesktopVerseUtil/build.gradle | 8 ++++---- KpriModel/build.gradle | 8 ++++---- Snappy/build.gradle | 8 ++++---- build.gradle | 7 +++++++ 19 files changed, 80 insertions(+), 75 deletions(-) diff --git a/ATree/build.gradle b/ATree/build.gradle index 2259e5018..eddcde55b 100644 --- a/ATree/build.gradle +++ b/ATree/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/Afw/build.gradle b/Afw/build.gradle index 09c88fa13..007472ddd 100644 --- a/Afw/build.gradle +++ b/Afw/build.gradle @@ -1,14 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 - versionCode 1 - versionName "1.0" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/Alkitab/build.gradle b/Alkitab/build.gradle index e5f78e367..ce69c682e 100644 --- a/Alkitab/build.gradle +++ b/Alkitab/build.gradle @@ -11,12 +11,12 @@ android { storePassword System.getenv("SIGN_PASSWORD") } } - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { applicationId 'yuku.alkitab.debug' - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion versionCode 14000242 versionName '4.3-beta2' } diff --git a/AlkitabFeedback/build.gradle b/AlkitabFeedback/build.gradle index 39c5bb357..9d7004ddb 100644 --- a/AlkitabFeedback/build.gradle +++ b/AlkitabFeedback/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { @@ -29,7 +29,7 @@ repositories { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-v4:22.2.1' + compile 'com.android.support:support-v4:23.0.0' compile 'com.squareup.okhttp:okhttp:2.5.0-SNAPSHOT' compile 'com.afollestad:material-dialogs:0.7.6.0' compile project(':Afw') diff --git a/AlkitabIntegration/build.gradle b/AlkitabIntegration/build.gradle index 2259e5018..eddcde55b 100644 --- a/AlkitabIntegration/build.gradle +++ b/AlkitabIntegration/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/AlkitabIo/build.gradle b/AlkitabIo/build.gradle index fe242bf5d..6a695ecdb 100644 --- a/AlkitabIo/build.gradle +++ b/AlkitabIo/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/AlkitabModel/build.gradle b/AlkitabModel/build.gradle index 2259e5018..eddcde55b 100644 --- a/AlkitabModel/build.gradle +++ b/AlkitabModel/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/AlkitabYes2/build.gradle b/AlkitabYes2/build.gradle index bbfa8ec92..57e610213 100644 --- a/AlkitabYes2/build.gradle +++ b/AlkitabYes2/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/AmbilWarna/build.gradle b/AmbilWarna/build.gradle index f8bce9d79..00c8737db 100644 --- a/AmbilWarna/build.gradle +++ b/AmbilWarna/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'com.android.library' apply plugin: 'me.tatarka.retrolambda' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/BiblePlus/build.gradle b/BiblePlus/build.gradle index 2259e5018..eddcde55b 100644 --- a/BiblePlus/build.gradle +++ b/BiblePlus/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/BintexReader/build.gradle b/BintexReader/build.gradle index 2259e5018..eddcde55b 100644 --- a/BintexReader/build.gradle +++ b/BintexReader/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/BintexWriter/build.gradle b/BintexWriter/build.gradle index 2259e5018..eddcde55b 100644 --- a/BintexWriter/build.gradle +++ b/BintexWriter/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/DragSortListView/build.gradle b/DragSortListView/build.gradle index 3eebd1d65..ddd36c0cb 100644 --- a/DragSortListView/build.gradle +++ b/DragSortListView/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion versionCode 3 versionName "0.5.0" } diff --git a/FileChooser/build.gradle b/FileChooser/build.gradle index 37609d3c8..1bc88e82f 100644 --- a/FileChooser/build.gradle +++ b/FileChooser/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/FlowLayout/build.gradle b/FlowLayout/build.gradle index 2259e5018..eddcde55b 100644 --- a/FlowLayout/build.gradle +++ b/FlowLayout/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/ImportedDesktopVerseUtil/build.gradle b/ImportedDesktopVerseUtil/build.gradle index 009f89838..4b2eb0053 100644 --- a/ImportedDesktopVerseUtil/build.gradle +++ b/ImportedDesktopVerseUtil/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } buildTypes { release { diff --git a/KpriModel/build.gradle b/KpriModel/build.gradle index 2259e5018..eddcde55b 100644 --- a/KpriModel/build.gradle +++ b/KpriModel/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/Snappy/build.gradle b/Snappy/build.gradle index 2259e5018..eddcde55b 100644 --- a/Snappy/build.gradle +++ b/Snappy/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion '22.0.1' + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 22 + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion } compileOptions { diff --git a/build.gradle b/build.gradle index 61b5a3e18..cb134677e 100644 --- a/build.gradle +++ b/build.gradle @@ -24,3 +24,10 @@ allprojects { jcenter() } } + +ext { + compileSdkVersion = 23 + buildToolsVersion = "23.0.0" + minSdkVersion = 14 + targetSdkVersion = 22 +} From f93c0f85d365bec0fb964f685300aef92441abec Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 14:53:11 +0800 Subject: [PATCH 07/21] Android support 22.2.1 -> 23.0.0 --- Alkitab/build.gradle | 7 ++++--- DragSortListView/build.gradle | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Alkitab/build.gradle b/Alkitab/build.gradle index ce69c682e..124e1a022 100644 --- a/Alkitab/build.gradle +++ b/Alkitab/build.gradle @@ -23,6 +23,7 @@ android { buildTypes { release { minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } @@ -67,7 +68,7 @@ dependencies { compile project(':AmbilWarna') compile project(':FileChooser') compile project(':ImportedDesktopVerseUtil') - compile 'com.android.support:support-v4:22.2.1' + compile 'com.android.support:support-v4:23.0.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.okhttp:okhttp:2.5.0-SNAPSHOT' compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0-SNAPSHOT' @@ -75,9 +76,9 @@ dependencies { compile 'com.google.code.gson:gson:2.3.1' compile 'com.google.android.gms:play-services-analytics:7.8.0' compile 'com.google.android.gms:play-services-gcm:7.8.0' - compile 'com.android.support:appcompat-v7:22.2.1' + compile 'com.android.support:appcompat-v7:23.0.0' compile 'com.android.support:multidex:1.0.1' compile 'com.afollestad:material-dialogs:0.7.6.0' - compile 'com.android.support:design:22.2.1' + compile 'com.android.support:design:23.0.0' testCompile 'junit:junit:4.12' } diff --git a/DragSortListView/build.gradle b/DragSortListView/build.gradle index ddd36c0cb..21642f92d 100644 --- a/DragSortListView/build.gradle +++ b/DragSortListView/build.gradle @@ -25,5 +25,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-v4:22.2.1' + compile 'com.android.support:support-v4:23.0.0' } From fa9676066b7e38d94bcb5b8a8af5c7b412fef923 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 14:53:46 +0800 Subject: [PATCH 08/21] Make compatible with sdk 23 --- Alkitab/proguard-rules.pro | 4 ++ .../yuku/alkitab/base/widget/Floater.java | 7 ++- .../java/yuku/kirimfidbek/CrashReporter.java | 48 +++++++++---------- .../widget/AmbilWarnaPrefWidgetView.java | 5 +- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/Alkitab/proguard-rules.pro b/Alkitab/proguard-rules.pro index a5e0f1532..0a9a39fa0 100644 --- a/Alkitab/proguard-rules.pro +++ b/Alkitab/proguard-rules.pro @@ -54,3 +54,7 @@ # retrolambda -dontwarn java.lang.invoke.** + + +# gms analytics still referencing apache http +-dontwarn com.google.android.gms.** diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/Floater.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/Floater.java index 3ee8cf6ca..8c585fb43 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/Floater.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/Floater.java @@ -5,7 +5,6 @@ import android.graphics.Paint; import android.graphics.Typeface; import android.util.AttributeSet; -import android.util.FloatMath; import android.view.HapticFeedbackConstants; import android.view.View; import yuku.alkitab.debug.R; @@ -134,7 +133,7 @@ protected void onDraw(final Canvas canvas) { grid_rows = 33; } else { grid_columns = 3; - grid_rows = (int) FloatMath.ceil((float) book_count / grid_columns); + grid_rows = (int) Math.ceil((float) book_count / grid_columns); } initFontSizes(h); @@ -185,7 +184,7 @@ protected void onDraw(final Canvas canvas) { grid_rows = 33; } else { grid_columns = 4; - grid_rows = (int) FloatMath.ceil((float) chapter_count / grid_columns); + grid_rows = (int) Math.ceil((float) chapter_count / grid_columns); } initFontSizes(h); @@ -229,7 +228,7 @@ protected void onDraw(final Canvas canvas) { grid_rows = 33; } else { grid_columns = 4; - grid_rows = (int) FloatMath.ceil((float) verse_count / grid_columns); + grid_rows = (int) Math.ceil((float) verse_count / grid_columns); } initFontSizes(h); diff --git a/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java b/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java index 558506db6..adfb751f2 100644 --- a/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java +++ b/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java @@ -3,14 +3,10 @@ import android.os.Build; import android.os.SystemClock; import android.util.Log; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; +import com.squareup.okhttp.FormEncodingBuilder; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; import yuku.afw.App; import yuku.afw.storage.Preferences; @@ -147,30 +143,34 @@ public void run() { Log.d(TAG, "tred pengirim dimulai. thread id = " + getId()); try { - HttpClient client = new DefaultHttpClient(); - HttpPost post = new HttpPost("http://www.kejut.com/prog/android/fidbek/kirim3.php"); - ArrayList params = new ArrayList<>(); + final OkHttpClient client = new OkHttpClient(); + final Request.Builder request = new Request.Builder(); + request.url("http://www.kejut.com/prog/android/fidbek/kirim3.php"); + + final FormEncodingBuilder form = new FormEncodingBuilder(); for (Entry entry : entries) { if (entry.body.length() > 100000) { entry.body = entry.body.substring(0, 100000); } - params.add(new BasicNameValuePair("uniqueId[]", getUniqueId())); - params.add(new BasicNameValuePair("package_name[]", App.context.getPackageName())); - params.add(new BasicNameValuePair("fidbek_isi[]", entry.body)); - params.add(new BasicNameValuePair("package_versionCode[]", String.valueOf(entry.versionCode))); - params.add(new BasicNameValuePair("timestamp[]", String.valueOf(entry.timestamp))); - params.add(new BasicNameValuePair("build_product[]", Build.PRODUCT)); - params.add(new BasicNameValuePair("build_device[]", Build.DEVICE)); - params.add(new BasicNameValuePair("version_sdk[]", String.valueOf(entry.versionSdk))); - params.add(new BasicNameValuePair("capjempol[]", entry.capjempol)); + + form + .add("uniqueId[]", getUniqueId()) + .add("package_name[]", App.context.getPackageName()) + .add("fidbek_isi[]", entry.body) + .add("package_versionCode[]", String.valueOf(entry.versionCode)) + .add("timestamp[]", String.valueOf(entry.timestamp)) + .add("build_product[]", Build.PRODUCT) + .add("build_device[]", Build.DEVICE) + .add("version_sdk[]", String.valueOf(entry.versionSdk)) + .add("capjempol[]", entry.capjempol); } - post.setEntity(new UrlEncodedFormEntity(params, "utf-8")); - HttpResponse response = client.execute(post); + request.post(form.build()); + + final Response response = client.newCall(request.build()).execute(); - HttpEntity entity = response.getEntity(); - InputStream content = entity.getContent(); + InputStream content = response.body().byteStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); while (true) { diff --git a/AmbilWarna/src/main/java/yuku/ambilwarna/widget/AmbilWarnaPrefWidgetView.java b/AmbilWarna/src/main/java/yuku/ambilwarna/widget/AmbilWarnaPrefWidgetView.java index 7ed4c4e37..fb61baa41 100644 --- a/AmbilWarna/src/main/java/yuku/ambilwarna/widget/AmbilWarnaPrefWidgetView.java +++ b/AmbilWarna/src/main/java/yuku/ambilwarna/widget/AmbilWarnaPrefWidgetView.java @@ -5,7 +5,6 @@ import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; -import android.util.FloatMath; import android.view.View; public class AmbilWarnaPrefWidgetView extends View { @@ -17,8 +16,8 @@ public AmbilWarnaPrefWidgetView(Context context, AttributeSet attrs) { super(context, attrs); float density = context.getResources().getDisplayMetrics().density; - rectSize = FloatMath.floor(24.f * density + 0.5f); - strokeWidth = FloatMath.floor(1.f * density + 0.5f); + rectSize = (float) Math.floor(24.f * density + 0.5f); + strokeWidth = (float) Math.floor(1.f * density + 0.5f); paint = new Paint(); paint.setColor(0xffffffff); From 394014ba74a29f8a0598f8fdf527a727c216612d Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 15:00:47 +0800 Subject: [PATCH 09/21] Remove unused resources --- .../main/res/drawable-hdpi/ic_menu_revert.png | Bin 765 -> 0 bytes .../main/res/drawable-mdpi/ic_menu_revert.png | Bin 470 -> 0 bytes .../main/res/drawable-xhdpi/ic_menu_revert.png | Bin 1053 -> 0 bytes .../main/res/drawable-xxhdpi/ic_menu_revert.png | Bin 1413 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 Alkitab/src/main/res/drawable-hdpi/ic_menu_revert.png delete mode 100755 Alkitab/src/main/res/drawable-mdpi/ic_menu_revert.png delete mode 100755 Alkitab/src/main/res/drawable-xhdpi/ic_menu_revert.png delete mode 100755 Alkitab/src/main/res/drawable-xxhdpi/ic_menu_revert.png diff --git a/Alkitab/src/main/res/drawable-hdpi/ic_menu_revert.png b/Alkitab/src/main/res/drawable-hdpi/ic_menu_revert.png deleted file mode 100755 index 9dc2e2fd531850895fa8f9081c932549d607e55e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 765 zcmVI)i-% z`V0g{pw%HX7!0P8B>5Gnv9x+?01{8nZvdF?9Doy#@M8e979<5GdgE#FyB%~1AS=F8 z0D0m&15hO1ChsawtwfvHM@H1Yn3Fnq4pfNGYTf3Cr`TOUzQh0-Hh|NtEUaTU01;H< z5)7c8E3&YLi}r*$>`+GOXTF~c+3cbKltHAIQ9uQ8(_kFSS3aC+3K0#U2qJGE0OYFX z0k+2|Ug0<2WE@2W$b%@_$beYD|4B;pBEFA&A)*6hAj)T&(`dmZ<}CoLfV|5Cq0VW&$L3P+bsx}brupPu8fQQ~8H6(7mQ^P} zdxK!y--<;yGF|lNtIkVhR6zg+p-oN4;>(!3pj1WD-HBHazf2)VsO=%WLv6&-g~Z00000NkvXXu0mjfWA0M} diff --git a/Alkitab/src/main/res/drawable-mdpi/ic_menu_revert.png b/Alkitab/src/main/res/drawable-mdpi/ic_menu_revert.png deleted file mode 100755 index 4496d9af2c42da04679eed5f5b18e185a9b27165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 470 zcmV;{0V)28P)3_9bM6^J@?BW5Rm|Fix~cj(OX6AdiDcfNp}ICm8^v<~eB=UPKW#$7H8mA({V8M{g3`8^Bgl-*^d7R-mlFFUQ4~A+|H=NdN!< M07*qoM6N<$f+2Irb^rhX diff --git a/Alkitab/src/main/res/drawable-xhdpi/ic_menu_revert.png b/Alkitab/src/main/res/drawable-xhdpi/ic_menu_revert.png deleted file mode 100755 index 3f2d7b3d223dbfb8333e2b3d65d1019e3a68c764..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1053 zcmV+&1mgRNP)&#c5kdOqLRJ$2?b@4Y+socqpw?mhL*yW^dEe!tK8{m%KF^C}$$Zv{)o=T;1K9C8uVS}Xr0QNEd2>?te6aX{xIDM`* z1GJ(6sLed;EEItF%$r#+Oaz#mH#1)t0QF|RNC1ZAe0;(CZ&RSz%*Q|s@%$P+L3hzR zGzgr(S?>^;Z9(;NK7m7W`ZIcnjsxLUfnA!E @ zIJgcSiNM(Y3c^;Ok&ronW|2^D8wA8u`d&cYXpBWcX|REQ+BuwCD*=oc361IiAWX!= zLy-&wtqIy44m*3#3t9%CUL-Utgdzx6=)c)=Si3_PeN{U+wGaS?MM5(G@-9k;N3k{G z63@F_i=~zWh(|)w3lSjfpzlRwc83pqUPFH^jHz2l0HeARi*|>5c)B3+R%?M4!~WFX zhgbt#j0Hj;{Z%WNcFc7#3>E=tKmcG9{cc))2LP}t&AUvWb_1{o!(Uhq4*_6ukpPUx z*&`|q>b^}1Qy0=!R6kf|XA6*9Vu?uMC<*Z$y=~j1zuY0^YhoQ@iu`?Hk zp=fn}j6vF_OuNB{9t`~HGDB^19LCV2II7EwVHX!X>+&KMgtod6!PsdydmAmWW?UyW z)$UpozKp}5Oc^S8ifV|8^C_Bms2t__G1!A>jAIaHLXn8geSYOG$GAey$(dWikftv?LP~a%uidM(C)f&4ayOb-1|~(`#_Rsp9dPlG zPL(VNu*FD`K1MJKQlXAFCn0FkDY!9l6X2*7Nc8%RE#y;tQ_-6s6$Zgd%fthS%E`B( zk?!o2_XkIJE%)Y8N{FK@#p{`BD;mm+@=B}R!TS}JnASzis327SS%IdPZeXn-X?U6J zi(>Xr+@h_Maip@xZmM!?V#uxB>9phyH!%H9Xb2MaMG3x^JVkZc%ibh>d(*5v>^ZJr za(R=Jycn8&!1Btf(~6KuMNU;%nj;ReooOf?AVV`E)CI-Cd&6jsa1m7vOgD?8T>*!J zYvw%BGy6*d;kjzMVqk!7nJ(PG6qkdSFmD|&`)MCrwRXvsy-|i`+D0i$KUl8z!BAeG~I0t^V2*N2N{*00M#UgYc(QO=L~ zc$nuBNR35Q*c8xtYN~+VD{v6k&PNkRYC7lvV=`|Agih?|*$KfCTx;N!>s|V=tN#42;2o(G zsK+;|Je{Zz8x^(_hcS$0jnrrU-xl3-wqw&vZ7|k#4p?kw^4REGelTG6R1pWxqWsc& zg0o(aCYa%QI6zzpXDsL#A_8&s_ka&*j5m`8x?K;91yv9UU|6!_Pfl7^3xi6~>Ub14 z{t(KV5FRoYcj?y0;CNy*K@k0U*?X_F@!6e`2@)1a3w|jMw3NlP>z{uxr!-XynQ*SJ z?~l;dKFI_Y^)k%Bw(d2t$g+k~$~ca_6Dm9_RU5Xb;?#G};G+D{I(JYWEYFJ$4Qv0i zBN4cJ`lL?a_MalO49qNuut}C-ilxU;6cP+pRk4vg+@aQET2^`+*Q`i}R~8;z*tpj8 zTZMAdzUpmE6+0u*w0|XiVzPMOPZXsW1AL?L@0&Vp4f^!o?C*Sg)R^Gu&SG&B*2nwN zBay;Hbsye4!dh^vLeEszeNceSX(%E`VK_BBqJbf=v76>g0R$S2s{V!Pm;+ zAyy1AB<-%Ev2SAUxz?N2=nT*6Prqlu%+{qB+Tl7L-p&?Vd#)(;=`IO$R_sNpU=WKH zDjr^2eJ-J6#Qynh@0eDpwNYUW;sO)xU%NVWK27(yuSaL{x2i1c;k=h9ibH8E}j}ExvI3Eb?YFlW=gBhSUS9myAr}&`| z+#}tXA%cz#4>|L&^t0jC9M{{sTpadPjxG43J)t>sHZFVo;=p%gRkvxl%dn599Cq_= z!z*omFlaZ%mT?079alB(gEKBC-K|gxqQ^RO(HV}a3>jPwy_e#Qr&`vr<3!=(8veG* i2xU-Y$npOQiZ3Y=yQ51qro4aLE3mP!H?KVIm-;U} Date: Tue, 25 Aug 2015 18:30:32 +0800 Subject: [PATCH 10/21] CrashReporter guard from null string --- .../src/main/java/yuku/kirimfidbek/CrashReporter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java b/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java index adfb751f2..9341e5f3d 100644 --- a/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java +++ b/AlkitabFeedback/src/main/java/yuku/kirimfidbek/CrashReporter.java @@ -157,13 +157,13 @@ public void run() { form .add("uniqueId[]", getUniqueId()) .add("package_name[]", App.context.getPackageName()) - .add("fidbek_isi[]", entry.body) + .add("fidbek_isi[]", "" + entry.body) .add("package_versionCode[]", String.valueOf(entry.versionCode)) .add("timestamp[]", String.valueOf(entry.timestamp)) - .add("build_product[]", Build.PRODUCT) - .add("build_device[]", Build.DEVICE) + .add("build_product[]", "" + Build.PRODUCT) + .add("build_device[]", "" + Build.DEVICE) .add("version_sdk[]", String.valueOf(entry.versionSdk)) - .add("capjempol[]", entry.capjempol); + .add("capjempol[]", "" + entry.capjempol); } request.post(form.build()); From 82ac75704b771e8336777f80dab41d20632946ae Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 18:49:35 +0800 Subject: [PATCH 11/21] Support extensions --- .../java/yuku/alkitab/base/IsiActivity.java | 63 ++++++++++++- .../src/main/java/yuku/alkitab/base/U.java | 7 +- .../alkitab/base/util/ExtensionManager.java | 94 +++++++++++++++++++ .../app/src/main/AndroidManifest.xml | 1 - 4 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index eb079d331..c10b26c3f 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -4,6 +4,7 @@ import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -84,6 +85,7 @@ import yuku.alkitab.base.util.Announce; import yuku.alkitab.base.util.Appearances; import yuku.alkitab.base.util.CurrentReading; +import yuku.alkitab.base.util.ExtensionManager; import yuku.alkitab.base.util.Highlights; import yuku.alkitab.base.util.History; import yuku.alkitab.base.util.Jumper; @@ -2034,8 +2036,15 @@ public void onClick(final Type type, final int arif, final Object source) { }; ActionMode.Callback actionMode_callback = new ActionMode.Callback() { + private static final int MENU_GROUP_EXTENSIONS = Menu.FIRST + 1; + private static final int MENU_EXTENSIONS_FIRST_ID = 0x1000; + + List extensions; + @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { getMenuInflater().inflate(R.menu.context_isi, menu); + + Log.d(TAG, "@@onCreateActionMode"); /* The following "esvsbasal" thing is a personal thing by yuku that doesn't matter to anyone else. * Please ignore it and leave it intact. */ @@ -2112,6 +2121,19 @@ public void onClick(final Type type, final int arif, final Object source) { && !Preferences.getBoolean(getString(R.string.pref_autoDictionaryAnalyze_key), getResources().getBoolean(R.bool.pref_autoDictionaryAnalyze_default)) ); + { // extensions + extensions = ExtensionManager.getExtensions(); + + menu.removeGroup(MENU_GROUP_EXTENSIONS); + + for (int i = 0; i < extensions.size(); i++) { + final ExtensionManager.Info extension = extensions.get(i); + if (single || (/* not single */ extension.supportMultipleVerses)) { + menu.add(MENU_GROUP_EXTENSIONS, MENU_EXTENSIONS_FIRST_ID + i, 0, extension.label); + } + } + } + return true; } @@ -2122,7 +2144,9 @@ public void onClick(final Type type, final int arif, final Object source) { final CharSequence reference = referenceFromSelectedVerses(selected, activeBook); - switch (item.getItemId()) { + final int itemId = item.getItemId(); + + switch (itemId) { case R.id.menuCopy: { // copy, can be multiple String[] t = prepareTextForCopyShare(selected, reference, false); if (activeSplitVersion != null) { @@ -2318,7 +2342,44 @@ public void onOk(int colorRgb) { startDictionaryMode(aris); } return true; + default: if (itemId >= MENU_EXTENSIONS_FIRST_ID && itemId < MENU_EXTENSIONS_FIRST_ID + extensions.size()) { + final ExtensionManager.Info extension = extensions.get(itemId - MENU_EXTENSIONS_FIRST_ID); + final Intent intent = new Intent(ExtensionManager.ACTION_SHOW_VERSE_INFO); + intent.setComponent(new ComponentName(extension.activityInfo.packageName, extension.activityInfo.name)); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // prepare extra "aris" + final int[] aris = new int[selected.size()]; + final int ariBc = Ari.encode(IsiActivity.this.activeBook.bookId, IsiActivity.this.chapter_1, 0); + for (int i = 0, len = selected.size(); i < len; i++) { + final int verse_1 = selected.get(i); + final int ari = Ari.encodeWithBc(ariBc, verse_1); + aris[i] = ari; + } + intent.putExtra("aris", aris); + + if (extension.includeVerseText) { + // prepare extra "verseTexts" + final String[] verseTexts = new String[selected.size()]; + for (int i = 0, len = selected.size(); i < len; i++) { + final int verse_1 = selected.get(i); + + final String verseText = lsSplit0.getVerse(verse_1); + if (extension.includeVerseTextFormatting) { + verseTexts[i] = verseText; + } else { + verseTexts[i] = U.removeSpecialCodes(verseText); + } + } + intent.putExtra("verseTexts", verseTexts); + } + + startActivity(intent); + + return true; + } } return false; } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/U.java b/Alkitab/src/main/java/yuku/alkitab/base/U.java index 10daad81a..aabc76a57 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/U.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/U.java @@ -5,6 +5,7 @@ import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable; import android.os.Build; +import android.support.annotation.Nullable; import android.support.v4.graphics.ColorUtils; import android.widget.TextView; import yuku.afw.storage.Preferences; @@ -24,18 +25,20 @@ public class U { static final String TAG = U.class.getSimpleName(); /** + * If text is null, this returns null. * If verse doesn't start with @: don't do anything. * Otherwise, remove all @'s and one character after that and also text between @< and @>. */ - public static String removeSpecialCodes(String text) { + @Nullable public static String removeSpecialCodes(@Nullable final String text) { return removeSpecialCodes(text, false); } /** + * If text is null, this returns null. * If verse doesn't start with @: don't do anything, except when force is set to true. * Otherwise, remove all @'s and one character after that and also text between @< and @>. */ - public static String removeSpecialCodes(final String text, final boolean force) { + @Nullable public static String removeSpecialCodes(@Nullable final String text, final boolean force) { if (text == null) return null; if (text.length() == 0) return text; if (!force && text.charAt(0) != '@') return text; diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java b/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java new file mode 100644 index 000000000..06f8a8fb4 --- /dev/null +++ b/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java @@ -0,0 +1,94 @@ +package yuku.alkitab.base.util; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; +import yuku.alkitab.base.App; +import yuku.alkitab.debug.BuildConfig; + +import java.util.ArrayList; +import java.util.List; + +public class ExtensionManager { + static final String TAG = ExtensionManager.class.getSimpleName(); + + public static final String ACTION_SHOW_VERSE_INFO = "yuku.alkitab.extensions.action.SHOW_VERSE_INFO"; + + private static final Intent openExtension = new Intent(ACTION_SHOW_VERSE_INFO); + + public static class Info { + public final ActivityInfo activityInfo; + public final CharSequence label; + public final boolean supportMultipleVerses; + public final boolean includeVerseText; + public final boolean includeVerseTextFormatting; + + public Info(final ActivityInfo activityInfo, final CharSequence label, final boolean supportMultipleVerses, final boolean includeVerseText, final boolean includeVerseTextFormatting) { + this.activityInfo = activityInfo; + this.label = label; + this.supportMultipleVerses = supportMultipleVerses; + this.includeVerseText = includeVerseText; + this.includeVerseTextFormatting = includeVerseTextFormatting; + } + } + + static List extensions; + + private static boolean getBooleanFromMetadata(@Nullable final Bundle metadata, @NonNull final String key, final boolean def) { + if (metadata == null) return def; + return metadata.getBoolean(key, def); + } + + public static synchronized List getExtensions() { + if (extensions == null) { + final PackageManager pm = App.context.getPackageManager(); + final List resolveInfos = pm.queryIntentActivities(openExtension, 0); + + extensions = new ArrayList<>(); + + for (final ResolveInfo ri : resolveInfos) { + try { + final ActivityInfo ai = pm.getActivityInfo(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name), PackageManager.GET_META_DATA); + final CharSequence label = ai.loadLabel(pm); + final boolean supportMultipleVerses = getBooleanFromMetadata(ai.metaData, "supportMultipleVerses", false); + final boolean includeVerseText = getBooleanFromMetadata(ai.metaData, "includeVerseText", false); + final boolean includeVerseTextFormatting = getBooleanFromMetadata(ai.metaData, "includeVerseTextFormatting", false); + + final Info info = new Info(ai, label, supportMultipleVerses, includeVerseText, includeVerseTextFormatting); + extensions.add(info); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "PackageManager should not emit this", e); + } + } + + if (BuildConfig.DEBUG) { + Log.d(TAG, "Found " + extensions.size() + " extensions:"); + for (final Info info : extensions) { + Log.d(TAG, "- " + info.activityInfo.packageName + "/" + info.activityInfo.name); + } + } + } + + return new ArrayList<>(extensions); + } + + public static synchronized void invalidate() { + extensions = null; + } + + public static class InvalidateExtensionsReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, final Intent intent) { + Log.d(TAG, "invalidating extensions because of " + intent.getAction()); + invalidate(); + } + } +} diff --git a/extensions/example-imagesharer/app/src/main/AndroidManifest.xml b/extensions/example-imagesharer/app/src/main/AndroidManifest.xml index c3ac189da..fb8da434c 100644 --- a/extensions/example-imagesharer/app/src/main/AndroidManifest.xml +++ b/extensions/example-imagesharer/app/src/main/AndroidManifest.xml @@ -26,7 +26,6 @@ android:label="Share as Image"> - Date: Tue, 25 Aug 2015 19:01:43 +0800 Subject: [PATCH 12/21] Typo --- .../src/main/java/yuku/alkitab/base/IsiActivity.java | 2 +- .../java/yuku/alkitab/base/util/ExtensionManager.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index c10b26c3f..cdef2718e 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -2128,7 +2128,7 @@ public void onClick(final Type type, final int arif, final Object source) { for (int i = 0; i < extensions.size(); i++) { final ExtensionManager.Info extension = extensions.get(i); - if (single || (/* not single */ extension.supportMultipleVerses)) { + if (single || (/* not single */ extension.supportsMultipleVerses)) { menu.add(MENU_GROUP_EXTENSIONS, MENU_EXTENSIONS_FIRST_ID + i, 0, extension.label); } } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java b/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java index 06f8a8fb4..a5c792f99 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/util/ExtensionManager.java @@ -27,14 +27,14 @@ public class ExtensionManager { public static class Info { public final ActivityInfo activityInfo; public final CharSequence label; - public final boolean supportMultipleVerses; + public final boolean supportsMultipleVerses; public final boolean includeVerseText; public final boolean includeVerseTextFormatting; - public Info(final ActivityInfo activityInfo, final CharSequence label, final boolean supportMultipleVerses, final boolean includeVerseText, final boolean includeVerseTextFormatting) { + public Info(final ActivityInfo activityInfo, final CharSequence label, final boolean supportsMultipleVerses, final boolean includeVerseText, final boolean includeVerseTextFormatting) { this.activityInfo = activityInfo; this.label = label; - this.supportMultipleVerses = supportMultipleVerses; + this.supportsMultipleVerses = supportsMultipleVerses; this.includeVerseText = includeVerseText; this.includeVerseTextFormatting = includeVerseTextFormatting; } @@ -58,11 +58,11 @@ public static synchronized List getExtensions() { try { final ActivityInfo ai = pm.getActivityInfo(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name), PackageManager.GET_META_DATA); final CharSequence label = ai.loadLabel(pm); - final boolean supportMultipleVerses = getBooleanFromMetadata(ai.metaData, "supportMultipleVerses", false); + final boolean supportsMultipleVerses = getBooleanFromMetadata(ai.metaData, "supportsMultipleVerses", false); final boolean includeVerseText = getBooleanFromMetadata(ai.metaData, "includeVerseText", false); final boolean includeVerseTextFormatting = getBooleanFromMetadata(ai.metaData, "includeVerseTextFormatting", false); - final Info info = new Info(ai, label, supportMultipleVerses, includeVerseText, includeVerseTextFormatting); + final Info info = new Info(ai, label, supportsMultipleVerses, includeVerseText, includeVerseTextFormatting); extensions.add(info); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "PackageManager should not emit this", e); From 6f83f8582e8aaee53e5fe06004589cf1b4c2d1f5 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 19:02:45 +0800 Subject: [PATCH 13/21] Update example extension --- .../java/yuku/alkitab.imagesharer/ShareVerseActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java index 39effdb1f..4528037f3 100644 --- a/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java +++ b/extensions/example-imagesharer/app/src/main/java/yuku/alkitab.imagesharer/ShareVerseActivity.java @@ -19,6 +19,7 @@ public class ShareVerseActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.activity_share_verse); // get the selected verse and its text Intent intent = getIntent(); @@ -53,7 +54,7 @@ public void onCreate(Bundle savedInstanceState) { p.setColor(0xff0000ff); // blue c.drawText(reference, 40, 200, p); - c.drawText(verseTexts[0], 40, 400, p); + c.drawText(verseTexts[0], 40, 240, p); // save as image and share try { @@ -62,6 +63,7 @@ public void onCreate(Bundle savedInstanceState) { f.close(); ShareCompat.IntentBuilder.from(this) + .setType("image/png") .addStream(Uri.fromFile(new File("/sdcard/tmp.png"))) .startChooser(); } catch (IOException e) { From e6969b0e6cb293ca056919cac7bc7f78fa0a04ad Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 19:19:29 +0800 Subject: [PATCH 14/21] Trigger extension refresh when other apps installed/changed/removed --- Alkitab/src/main/AndroidManifest.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Alkitab/src/main/AndroidManifest.xml b/Alkitab/src/main/AndroidManifest.xml index f0875f3fa..f69c1170c 100644 --- a/Alkitab/src/main/AndroidManifest.xml +++ b/Alkitab/src/main/AndroidManifest.xml @@ -498,6 +498,17 @@ + + + + + + + + + + + From c5d2206d34dc70d7574d125b6296f4d61becc250 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 19:20:23 +0800 Subject: [PATCH 15/21] Install LeakCanary --- Alkitab/build.gradle | 2 ++ Alkitab/src/main/java/yuku/alkitab/base/App.java | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/Alkitab/build.gradle b/Alkitab/build.gradle index 124e1a022..749540fe5 100644 --- a/Alkitab/build.gradle +++ b/Alkitab/build.gradle @@ -81,4 +81,6 @@ dependencies { compile 'com.afollestad:material-dialogs:0.7.6.0' compile 'com.android.support:design:23.0.0' testCompile 'junit:junit:4.12' + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' + releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/App.java b/Alkitab/src/main/java/yuku/alkitab/base/App.java index 2ced07b2b..753585738 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/App.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/App.java @@ -11,6 +11,7 @@ import com.google.android.gms.analytics.GoogleAnalytics; import com.google.android.gms.analytics.Tracker; import com.google.gson.Gson; +import com.squareup.leakcanary.LeakCanary; import com.squareup.okhttp.Call; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; @@ -90,6 +91,10 @@ public static OkHttpClient getLongTimeoutOkHttpClient() { APP_TRACKER = t; analytics.enableAutoActivityReports(this); } + + { // LeakCanary, also we need the Application instance. + LeakCanary.install(this); + } } public synchronized static void staticInit() { From fc6ab9c9c24e85aa62e5b3a114e559ed9d598603 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 20:56:51 +0800 Subject: [PATCH 16/21] Replace "[?]" with real null when a verse is not available when copying/sharing --- .../java/yuku/alkitab/base/IsiActivity.java | 50 +++++++++++-------- .../alkitab/base/widget/VerseAdapter.java | 7 +-- .../yuku/alkitab/base/widget/VersesView.java | 4 +- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index cdef2718e..3b4270b77 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -1006,21 +1006,24 @@ String[] prepareTextForCopyShare(IntArrayList selectedVerses_1, CharSequence ref // append each selected verse with verse number prepended for (int i = 0, len = selectedVerses_1.size(); i < len; i++) { - int verse_1 = selectedVerses_1.get(i); - res0.append(verse_1); - res1.append(verse_1); - res0.append(' '); - res1.append(' '); + final int verse_1 = selectedVerses_1.get(i); + final String verseText = isSplitVersion ? lsSplit1.getVerseText(verse_1) : lsSplit0.getVerseText(verse_1); - final String verseText = isSplitVersion ? lsSplit1.getVerse(verse_1) : lsSplit0.getVerse(verse_1); - final String verseTextPlain = U.removeSpecialCodes(verseText); + if (verseText != null) { + final String verseTextPlain = U.removeSpecialCodes(verseText); - res0.append(verseTextPlain); - res1.append(verseText); + res0.append(verse_1); + res1.append(verse_1); + res0.append(' '); + res1.append(' '); - if (i != len - 1) { - res0.append('\n'); - res1.append('\n'); + res0.append(verseTextPlain); + res1.append(verseText); + + if (i != len - 1) { + res0.append('\n'); + res1.append('\n'); + } } } } else { @@ -1028,16 +1031,19 @@ String[] prepareTextForCopyShare(IntArrayList selectedVerses_1, CharSequence ref // append each selected verse without verse number prepended for (int i = 0; i < selectedVerses_1.size(); i++) { - int verse_1 = selectedVerses_1.get(i); - if (i != 0) { - res0.append('\n'); - res1.append('\n'); - } - final String verseText = isSplitVersion ? lsSplit1.getVerse(verse_1) : lsSplit0.getVerse(verse_1); - final String verseTextPlain = U.removeSpecialCodes(verseText); + final int verse_1 = selectedVerses_1.get(i); + final String verseText = isSplitVersion ? lsSplit1.getVerseText(verse_1) : lsSplit0.getVerseText(verse_1); - res0.append(verseTextPlain); - res1.append(verseText); + if (verseText != null) { + final String verseTextPlain = U.removeSpecialCodes(verseText); + + if (i != 0) { + res0.append('\n'); + res1.append('\n'); + } + res0.append(verseTextPlain); + res1.append(verseText); + } } } @@ -2366,7 +2372,7 @@ public void onOk(int colorRgb) { for (int i = 0, len = selected.size(); i < len; i++) { final int verse_1 = selected.get(i); - final String verseText = lsSplit0.getVerse(verse_1); + final String verseText = lsSplit0.getVerseText(verse_1); if (extension.includeVerseTextFormatting) { verseTexts[i] = verseText; } else { diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java index e9fbdf655..5261b7a03 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; +import android.support.annotation.Nullable; import android.util.Log; import android.view.LayoutInflater; import android.widget.BaseAdapter; @@ -292,9 +293,9 @@ public int getVerseOrPericopeFromPosition(int position) { } } - public String getVerse(int verse_1) { - if (verses_ == null) return "[?]"; //$NON-NLS-1$ - if (verse_1 < 1 || verse_1 > verses_.getVerseCount()) return "[?]"; //$NON-NLS-1$ + @Nullable public String getVerseText(int verse_1) { + if (verses_ == null) return null; + if (verse_1 < 1 || verse_1 > verses_.getVerseCount()) return null; return verses_.getVerse(verse_1 - 1); } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java index 3b7ef5908..33d21652d 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java @@ -214,8 +214,8 @@ public void reloadAttributeMap() { adapter.reloadAttributeMap(); } - public String getVerse(int verse_1) { - return adapter.getVerse(verse_1); + @Nullable public String getVerseText(int verse_1) { + return adapter.getVerseText(verse_1); } /** From f47833e978e1955929c026788b3ac592b170521a Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 20:57:00 +0800 Subject: [PATCH 17/21] Fix leak --- .../java/yuku/alkitab/base/widget/LabeledSplitHandleButton.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/LabeledSplitHandleButton.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/LabeledSplitHandleButton.java index e161d479e..9ff12547a 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/LabeledSplitHandleButton.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/LabeledSplitHandleButton.java @@ -285,7 +285,7 @@ protected void onAttachedToWindow() { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - + App.getLbm().unregisterReceiver(nightModeChangedListener); } final BroadcastReceiver nightModeChangedListener = new BroadcastReceiver() { From d737d5c9b6981b0908ef3784b0b0b277a707215d Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 21:15:00 +0800 Subject: [PATCH 18/21] Fix memory leak --- .../yuku/alkitab/base/ac/ShareActivity.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java index a388e6041..aafadb38c 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java @@ -60,7 +60,7 @@ public static Result obtainResult(Intent data) { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreateWithNonToolbarUpButton(savedInstanceState); setContentView(R.layout.activity_share); - + String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); setTitle(title); @@ -69,8 +69,22 @@ public static Result obtainResult(Intent data) { final List rList = null; lsIntent = V.get(this, R.id.lsIntent); - - mPm = getPackageManager(); + + // fix for memory leak: + // https://github.com/square/leakcanary/blob/master/leakcanary-android/src/main/java/com/squareup/leakcanary/AndroidExcludedRefs.java + // + // UserManager has a static sInstance field that creates an instance and caches it the first + // time UserManager.get() is called. This instance is created with the outer context (which + // is an activity base context). + // Tracked here: https://code.google.com/p/android/issues/detail?id=173789 + // Introduced by: https://github.com/android/platform_frameworks_base/commit + // /27db46850b708070452c0ce49daf5f79503fbde6 + // Fix: trigger a call to UserManager.get() in Application.onCreate(), so that the + // UserManager instance gets cached with a reference to the application context. + // + // This fix: instead of calling this.getPackageManager(), call getPackageManager + // using the app context. + mPm = getApplicationContext().getPackageManager(); intent.setComponent(null); // show progress dialog so that it does not appear to be hang From eb9b48c80d8be558ac857bc67c05cfe4087d9a69 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 21:29:46 +0800 Subject: [PATCH 19/21] Add locale extra for starting maps app --- .../java/yuku/alkitab/base/IsiActivity.java | 35 ++++++++++++------- .../yuku/alkitab/base/model/VersionImpl.java | 5 +++ .../alkitab/base/widget/VerseAdapter.java | 10 +++--- .../yuku/alkitab/base/widget/VersesView.java | 8 +++-- .../main/java/yuku/alkitab/model/Version.java | 2 ++ 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index 3b4270b77..60752cdeb 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -456,7 +456,7 @@ public void onReceive(final Context context, final Intent intent) { // listeners lsSplit0.setParallelListener(parallelListener); - lsSplit0.setAttributeListener(attributeListener); + lsSplit0.setAttributeListener(new AttributeListener()); // have to be distinct from lsSplit1 lsSplit0.setInlineLinkSpanFactory(new VerseInlineLinkSpanFactory(lsSplit0)); lsSplit0.setSelectedVersesListener(lsSplit0_selectedVerses); lsSplit0.setOnVerseScrollListener(lsSplit0_verseScroll); @@ -466,7 +466,7 @@ public void onReceive(final Context context, final Intent intent) { lsSplit1.setVerseSelectionMode(VersesView.VerseSelectionMode.multiple); lsSplit1.setEmptyView(tSplitEmpty); lsSplit1.setParallelListener(parallelListener); - lsSplit1.setAttributeListener(attributeListener); + lsSplit1.setAttributeListener(new AttributeListener()); // have to be distinct from lsSplit0 lsSplit1.setInlineLinkSpanFactory(new VerseInlineLinkSpanFactory(lsSplit1)); lsSplit1.setSelectedVersesListener(lsSplit1_selectedVerses); lsSplit1.setOnVerseScrollListener(lsSplit1_verseScroll); @@ -1740,16 +1740,14 @@ void bVersion_click() { history.add(ari_target); } - VersesView.AttributeListener attributeListener = new VersesView.AttributeListener() { + class AttributeListener implements VersesView.AttributeListener { void openBookmarkDialog(final long _id) { final TypeBookmarkDialog dialog = TypeBookmarkDialog.EditExisting(IsiActivity.this, _id); - dialog.setListener(new TypeBookmarkDialog.Listener() { - @Override public void onModifiedOrDeleted() { - lsSplit0.reloadAttributeMap(); + dialog.setListener(() -> { + lsSplit0.reloadAttributeMap(); - if (activeSplitVersion != null) { - lsSplit1.reloadAttributeMap(); - } + if (activeSplitVersion != null) { + lsSplit1.reloadAttributeMap(); } }); dialog.show(); @@ -1897,10 +1895,23 @@ public void onDeleted() { @Override public void onHasMapsAttributeClick(final int ari) { + String locale = null; + + if (this == lsSplit0.getAttributeListener()) { + locale = S.activeVersion.getLocale(); + } else if (this == lsSplit1.getAttributeListener()) { + locale = activeSplitVersion.getLocale(); + } + try { - startActivity(new Intent("palki.maps.action.SHOW_MAPS_DIALOG") - .putExtra("ari", ari) - ); + final Intent intent = new Intent("palki.maps.action.SHOW_MAPS_DIALOG"); + intent.putExtra("ari", ari); + + if (locale != null) { + intent.putExtra("locale", locale); + } + + startActivity(intent); } catch (ActivityNotFoundException e) { new MaterialDialog.Builder(IsiActivity.this) .content(R.string.maps_could_not_open) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java b/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java index c910e0c0a..be310bbef 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java @@ -52,6 +52,11 @@ public String getLongName() { return bibleReader.getLongName(); } + @Override + public String getLocale() { + return bibleReader.getLocale(); + } + /** * Some books can be null. Using this method, the return value indexed will have the same value as the {@link Book#bookId}. * i.e. return_value[bookId].bookId == bookId. diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java index 5261b7a03..d4e91b0f5 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java @@ -48,8 +48,7 @@ public abstract class VerseAdapter extends BaseAdapter { boolean[] hasMapsMap_; LayoutInflater inflater_; - VersesView owner_; - + public VerseAdapter(Context context) { density_ = context.getResources().getDisplayMetrics().density; inflater_ = LayoutInflater.from(context); @@ -185,15 +184,18 @@ public void setParallelListener(CallbackSpan.OnClickListener parallelLis parallelListener_ = parallelListener; notifyDataSetChanged(); } + + public VersesView.AttributeListener getAttributeListener() { + return attributeListener_; + } public void setAttributeListener(VersesView.AttributeListener attributeListener) { attributeListener_ = attributeListener; notifyDataSetChanged(); } - public void setInlineLinkSpanFactory(final VerseInlineLinkSpan.Factory inlineLinkSpanFactory, VersesView owner) { + public void setInlineLinkSpanFactory(final VerseInlineLinkSpan.Factory inlineLinkSpanFactory) { inlineLinkSpanFactory_ = inlineLinkSpanFactory; - owner_ = owner; notifyDataSetChanged(); } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java index 33d21652d..e83f6f66c 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java @@ -174,12 +174,16 @@ public void setParallelListener(CallbackSpan.OnClickListener parallelLis adapter.setParallelListener(parallelListener); } - public void setAttributeListener(VersesView.AttributeListener attributeListener) { + public AttributeListener getAttributeListener() { + return adapter.getAttributeListener(); + } + + public void setAttributeListener(final AttributeListener attributeListener) { adapter.setAttributeListener(attributeListener); } public void setInlineLinkSpanFactory(final VerseInlineLinkSpan.Factory inlineLinkSpanFactory) { - adapter.setInlineLinkSpanFactory(inlineLinkSpanFactory, this); + adapter.setInlineLinkSpanFactory(inlineLinkSpanFactory); } public void setDictionaryListener(CallbackSpan.OnClickListener listener) { diff --git a/AlkitabModel/src/main/java/yuku/alkitab/model/Version.java b/AlkitabModel/src/main/java/yuku/alkitab/model/Version.java index c553c7392..30b72515e 100644 --- a/AlkitabModel/src/main/java/yuku/alkitab/model/Version.java +++ b/AlkitabModel/src/main/java/yuku/alkitab/model/Version.java @@ -13,6 +13,8 @@ public abstract class Version { public abstract String getLongName(); + public abstract String getLocale(); + /** * @return The highest bookId on this version plus one. */ From 10bfdcb470ed77f5a38cdd2c9094a3da9d886719 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 21:31:33 +0800 Subject: [PATCH 20/21] Guard for error when starting extension --- Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index 60752cdeb..c58d63449 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -2393,7 +2393,14 @@ public void onOk(int colorRgb) { intent.putExtra("verseTexts", verseTexts); } - startActivity(intent); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + new MaterialDialog.Builder(IsiActivity.this) + .content("Error ANFE starting extension\n\n" + extension.activityInfo.packageName + "/" + extension.activityInfo.name) + .positiveText(R.string.ok) + .show(); + } return true; } From 08d09b205a236dca1c555abed37c5ac9c05b17e2 Mon Sep 17 00:00:00 2001 From: Yuku on yuku8 Date: Tue, 25 Aug 2015 21:43:48 +0800 Subject: [PATCH 21/21] Bump version --- Alkitab/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Alkitab/build.gradle b/Alkitab/build.gradle index 749540fe5..58d7988af 100644 --- a/Alkitab/build.gradle +++ b/Alkitab/build.gradle @@ -17,8 +17,8 @@ android { applicationId 'yuku.alkitab.debug' minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 14000242 - versionName '4.3-beta2' + versionCode 14000243 + versionName '4.3-beta3' } buildTypes { release {