안드로이드에서는 Alpha 채널을 이용해 컬러에 투명도를 표시 할 수 있다. colors.xml 에 컬러값을 지정 해 놓고 쓰면된다.


1
2
<color name="black">#000000</color>
<color name="black">#99000000</color> 
cs


2번째에서 앞의 99가 Alpha 값이다. Hex값이기 때문에 얼마나 투명한지 정도를 알려면 계산이 좀 들어가야하는데 귀찮으니 정리해놓았다.

100% — FF
99% — FC
98% — FA
97% — F7
96% — F5
95% — F2
94% — F0
93% — ED
92% — EB
91% — E8
90% — E6
89% — E3
88% — E0
87% — DE
86% — DB
85% — D9
84% — D6
83% — D4
82% — D1
81% — CF
80% — CC
79% — C9
78% — C7
77% — C4
76% — C2
75% — BF
74% — BD
73% — BA
72% — B8
71% — B5
70% — B3
69% — B0
68% — AD
67% — AB
66% — A8
65% — A6
64% — A3
63% — A1
62% — 9E
61% — 9C
60% — 99
59% — 96
57% — 94
56% — 91
56% — 8F
55% — 8C
54% — 8A
53% — 87
52% — 85
51% — 82
50% — 80
49% — 7D
48% — 7A
47% — 78
46% — 75
45% — 73
44% — 70
43% — 6E
42% — 6B
41% — 69
40% — 66
39% — 63
38% — 61
37% — 5E
36% — 5C
35% — 59
34% — 57
33% — 54
32% — 52
31% — 4F
30% — 4D
28% — 4A
28% — 47
27% — 45
26% — 42
25% — 40
24% — 3D
23% — 3B
22% — 38
21% — 36
20% — 33
19% — 30
18% — 2E
17% — 2B
16% — 29
15% — 26
14% — 24
13% — 21
12% — 1F
11% — 1C
10% — 1A
9% — 17
8% — 14
7% — 12
6% — 0F
5% — 0D
4% — 0A
3% — 08
2% — 05
1% — 03
0% — 00







현재 앱의 Hash Key를 가져오는 메소드


페북이나 카카오톡 등 연동할 때 쓰자.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void getAppKeyHash() {
        try {
            PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md;
                md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                String something = new String(Base64.encode(md.digest(), 0));
                DLog.w("Hash key", something);
            }
        } catch (Exception e) {
            DLog.e("name not found", e.toString());
        }
    }
cs










File -> Settings -> Editor -> General -> Code Completion -> Case sensitive completion -> None












1. 키보드 내리기




1
2
InputMethodManager immhide = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
immhide.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
cs





2. 키보드 올리기


1
2
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
cs




넘나 간단한것











안드로이드 Material Design에서 샘플로 나온 컬러를 hex값으로 변환한것


colors.xml에 지정해놓고 쓰자.



    <!-- Grey -->

    <color name="grey_50">#FAFAFA</color>

    <color name="grey_100">#F5F5F5</color>

    <color name="grey_200">#EEEEEE</color>

    <color name="grey_300">#E0E0E0</color>

    <color name="grey_400">#BDBDBD</color>

    <color name="grey_500">#9E9E9E</color>

    <color name="grey_600">#757575</color>

    <color name="grey_700">#616161</color>

    <color name="grey_800">#424242</color>

    <color name="grey_900">#212121</color>

    <!-- Grey -->


    <!-- Red -->

    <color name="red_50">#FFEBEE</color>

    <color name="red_100">#FFCDD2</color>

    <color name="red_200">#EF9A9A</color>

    <color name="red_300">#E57373</color>

    <color name="red_400">#EF5350</color>

    <color name="red_500">#F44336</color>

    <color name="red_600">#E53935</color>

    <color name="red_700">#D32F2F</color>

    <color name="red_800">#C62828</color>

    <color name="red_900">#B71C1C</color>

    <color name="red_A100">#FF8A80</color>

    <color name="red_A200">#FF5252</color>

    <color name="red_A400">#FF1744</color>

    <color name="red_A700">#D50000</color>

    <!-- Red -->


    <!-- Pink -->

    <color name="pink_50">#FCE4EC</color>

    <color name="pink_100">#F8BBD0</color>

    <color name="pink_200">#F48FB1</color>

    <color name="pink_300">#F06292</color>

    <color name="pink_400">#EC407A</color>

    <color name="pink_500">#E91E63</color>

    <color name="pink_600">#D81B60</color>

    <color name="pink_700">#C2185B</color>

    <color name="pink_800">#AD1457</color>

    <color name="pink_900">#880E4F</color>

    <color name="pink_A100">#FF80AB</color>

    <color name="pink_A200">#FF4081</color>

    <color name="pink_A400">#F50057</color>

    <color name="pink_A700">#C51162</color>

    <!-- Pink -->


    <!-- Purple -->

    <color name="purple_50">#F3E5F5</color>

    <color name="purple_100">#E1BEE7</color>

    <color name="purple_200">#CE93D8</color>

    <color name="purple_300">#BA68C8</color>

    <color name="purple_400">#AB47BC</color>

    <color name="purple_500">#9C27B0</color>

    <color name="purple_600">#8E24AA</color>

    <color name="purple_700">#7B1FA2</color>

    <color name="purple_800">#6A1B9A</color>

    <color name="purple_900">#4A148C</color>

    <color name="purple_A100">#EA80FC</color>

    <color name="purple_A200">#E040FB</color>

    <color name="purple_A400">#D500F9</color>

    <color name="purple_A700">#AA00FF</color>

    <!-- Purple -->


    <!-- Deep Purple -->

    <color name="dark_purple_50">#EDE7F6</color>

    <color name="dark_purple_100">#D1C4E9</color>

    <color name="dark_purple_200">#B39DDB</color>

    <color name="dark_purple_300">#9575CD</color>

    <color name="dark_purple_400">#7E57C2</color>

    <color name="dark_purple_500">#673AB7</color>

    <color name="dark_purple_600">#5E35B1</color>

    <color name="dark_purple_700">#512DA8</color>

    <color name="dark_purple_800">#4527A0</color>

    <color name="dark_purple_900">#311B92</color>

    <color name="dark_purple_A100">#B388FF</color>

    <color name="dark_purple_A200">#7C4DFF</color>

    <color name="dark_purple_A400">#651FFF</color>

    <color name="dark_purple_A700">#6200EA</color>

    <!-- Deep Purple -->


    <!-- Indigo -->

    <color name="indigo_50">#E8EAF6</color>

    <color name="indigo_100">#C5CAE9</color>

    <color name="indigo_200">#9FA8DA</color>

    <color name="indigo_300">#7986CB</color>

    <color name="indigo_400">#5C6BC0</color>

    <color name="indigo_500">#3F51B5</color>

    <color name="indigo_600">#3949AB</color>

    <color name="indigo_700">#303F9F</color>

    <color name="indigo_800">#283593</color>

    <color name="indigo_900">#1A237E</color>

    <color name="indigo_A100">#8C9EFF</color>

    <color name="indigo_A200">#536DFE</color>

    <color name="indigo_A400">#3D5AFE</color>

    <color name="indigo_A700">#304FFE</color>

    <!-- Indigo -->


    <!-- Blue -->

    <color name="blue_50">#E3F2FD</color>

    <color name="blue_100">#BBDEFB</color>

    <color name="blue_200">#90CAF9</color>

    <color name="blue_300">#64B5F6</color>

    <color name="blue_400">#42A5F5</color>

    <color name="blue_500">#2196F3</color>

    <color name="blue_600">#1E88E5</color>

    <color name="blue_700">#1976D2</color>

    <color name="blue_800">#1565C0</color>

    <color name="blue_900">#0D47A1</color>

    <color name="blue_A100">#82B1FF</color>

    <color name="blue_A200">#448AFF</color>

    <color name="blue_A400">#2979FF</color>

    <color name="blue_A700">#2962FF</color>

    <!-- Blue -->


    <!-- Light Blue -->

    <color name="light_blue_50">#E1F5FE</color>

    <color name="light_blue_100">#B3E5FC</color>

    <color name="light_blue_200">#81D4FA</color>

    <color name="light_blue_300">#4FC3F7</color>

    <color name="light_blue_400">#29B6F6</color>

    <color name="light_blue_500">#03A9F4</color>

    <color name="light_blue_600">#039BE5</color>

    <color name="light_blue_700">#0288D1</color>

    <color name="light_blue_800">#0277BD</color>

    <color name="light_blue_900">#01579B</color>

    <color name="light_blue_A100">#80D8FF</color>

    <color name="light_blue_A200">#40C4FF</color>

    <color name="light_blue_A400">#00B0FF</color>

    <color name="light_blue_A700">#0091EA</color>

    <!-- Light Blue -->


    <!-- Cyan -->

    <color name="cyan_50">#E0F7FA</color>

    <color name="cyan_100">#B2EBF2</color>

    <color name="cyan_200">#80DEEA</color>

    <color name="cyan_300">#4DD0E1</color>

    <color name="cyan_400">#26C6DA</color>

    <color name="cyan_500">#00BCD4</color>

    <color name="cyan_600">#00ACC1</color>

    <color name="cyan_700">#0097A7</color>

    <color name="cyan_800">#00838F</color>

    <color name="cyan_900">#006064</color>

    <color name="cyan_A100">#84FFFF</color>

    <color name="cyan_A200">#18FFFF</color>

    <color name="cyan_A400">#00E5FF</color>

    <color name="cyan_A700">#00B8D4</color>

    <!-- Cyan -->


    <!-- Teal -->

    <color name="teal_50">#E0F2F1</color>

    <color name="teal_100">#B2DFDB</color>

    <color name="teal_200">#80CBC4</color>

    <color name="teal_300">#4DB6AC</color>

    <color name="teal_400">#26A69A</color>

    <color name="teal_500">#009688</color>

    <color name="teal_600">#00897B</color>

    <color name="teal_700">#00796B</color>

    <color name="teal_800">#00695C</color>

    <color name="teal_900">#004D40</color>

    <color name="teal_A100">#A7FFEB</color>

    <color name="teal_A200">#64FFDA</color>

    <color name="teal_A400">#1DE9B6</color>

    <color name="teal_A700">#00BFA5</color>

    <!-- Teal -->


    <!-- Green -->

    <color name="green_50">#E8F5E9</color>

    <color name="green_100">#C8E6C9</color>

    <color name="green_200">#A5D6A7</color>

    <color name="green_300">#81C784</color>

    <color name="green_400">#66BB6A</color>

    <color name="green_500">#4CAF50</color>

    <color name="green_600">#43A047</color>

    <color name="green_700">#388E3C</color>

    <color name="green_800">#2E7D32</color>

    <color name="green_900">#1B5E20</color>

    <color name="green_A100">#B9F6CA</color>

    <color name="green_A200">#69F0AE</color>

    <color name="green_A400">#00E676</color>

    <color name="green_A700">#00C853</color>

    <!-- Green -->


    <!-- Light Green -->

    <color name="light_green_50">#F1F8E9</color>

    <color name="light_green_100">#DCEDC8</color>

    <color name="light_green_200">#C5E1A5</color>

    <color name="light_green_300">#AED581</color>

    <color name="light_green_400">#9CCC65</color>

    <color name="light_green_500">#8BC34A</color>

    <color name="light_green_600">#7CB342</color>

    <color name="light_green_700">#689F38</color>

    <color name="light_green_800">#558B2F</color>

    <color name="light_green_900">#33691E</color>

    <color name="light_green_A100">#CCFF90</color>

    <color name="light_green_A200">#B2FF59</color>

    <color name="light_green_A400">#76FF03</color>

    <color name="light_green_A700">#64DD17</color>

    <!-- Light Green -->


    <!-- Lime -->

    <color name="lime_50">#F9FBE7</color>

    <color name="lime_100">#F0F4C3</color>

    <color name="lime_200">#E6EE9C</color>

    <color name="lime_300">#DCE775</color>

    <color name="lime_400">#D4E157</color>

    <color name="lime_500">#CDDC39</color>

    <color name="lime_600">#C0CA33</color>

    <color name="lime_700">#AFB42B</color>

    <color name="lime_800">#9E9D24</color>

    <color name="lime_900">#827717</color>

    <color name="lime_A100">#F4FF81</color>

    <color name="lime_A200">#EEFF41</color>

    <color name="lime_A400">#C6FF00</color>

    <color name="lime_A700">#AEEA00</color>

    <!-- Lime -->


    <!-- Yellow -->

    <color name="yellow_50">#FFFDE7</color>

    <color name="yellow_100">#FFF9C4</color>

    <color name="yellow_200">#FFF59D</color>

    <color name="yellow_300">#FFF176</color>

    <color name="yellow_400">#FFEE58</color>

    <color name="yellow_500">#FFEB3B</color>

    <color name="yellow_600">#FDD835</color>

    <color name="yellow_700">#FBC02D</color>

    <color name="yellow_800">#F9A825</color>

    <color name="yellow_900">#F57F17</color>

    <color name="yellow_A100">#FFFF8D</color>

    <color name="yellow_A200">#FFFF00</color>

    <color name="yellow_A400">#FFEA00</color>

    <color name="yellow_A700">#FFD600</color>

    <!-- Yellow -->


    <!-- Amber -->

    <color name="amber_50">#FFF8E1</color>

    <color name="amber_100">#FFECB3</color>

    <color name="amber_200">#FFE082</color>

    <color name="amber_300">#FFD54F</color>

    <color name="amber_400">#FFCA28</color>

    <color name="amber_500">#FFC107</color>

    <color name="amber_600">#FFB300</color>

    <color name="amber_700">#FFA000</color>

    <color name="amber_800">#FF8F00</color>

    <color name="amber_900">#FF6F00</color>

    <color name="amber_A100">#FFE57F</color>

    <color name="amber_A200">#FFD740</color>

    <color name="amber_A400">#FFC400</color>

    <color name="amber_A700">#FFAB00</color>

    <!-- Amber -->


    <!-- Orange -->

    <color name="orange_50">#FFF3E0</color>

    <color name="orange_100">#FFE0B2</color>

    <color name="orange_200">#FFCC80</color>

    <color name="orange_300">#FFB74D</color>

    <color name="orange_400">#FFA726</color>

    <color name="orange_500">#FF9800</color>

    <color name="orange_600">#FB8C00</color>

    <color name="orange_700">#F57C00</color>

    <color name="orange_800">#EF6C00</color>

    <color name="orange_900">#E65100</color>

    <color name="orange_A100">#FFD180</color>

    <color name="orange_A200">#FFAB40</color>

    <color name="orange_A400">#FF9100</color>

    <color name="orange_A700">#FF6D00</color>

    <!-- Orange -->


    <!-- Deep Orange -->

    <color name="deep_orange_50">#FBE9E7</color>

    <color name="deep_orange_100">#FFCCBC</color>

    <color name="deep_orange_200">#FFAB91</color>

    <color name="deep_orange_300">#FF8A65</color>

    <color name="deep_orange_400">#FF7043</color>

    <color name="deep_orange_500">#FF5722</color>

    <color name="deep_orange_600">#F4511E</color>

    <color name="deep_orange_700">#E64A19</color>

    <color name="deep_orange_800">#D84315</color>

    <color name="deep_orange_900">#BF360C</color>

    <color name="deep_orange_A100">#FF9E80</color>

    <color name="deep_orange_A200">#FF6E40</color>

    <color name="deep_orange_A400">#FF3D00</color>

    <color name="deep_orange_A700">#DD2C00</color>

    <!-- Deep Orange -->


    <!-- Brown -->

    <color name="brown_50">#EFEBE9</color>

    <color name="brown_100">#D7CCC8</color>

    <color name="brown_200">#BCAAA4</color>

    <color name="brown_300">#A1887F</color>

    <color name="brown_400">#8D6E63</color>

    <color name="brown_500">#795548</color>

    <color name="brown_600">#6D4C41</color>

    <color name="brown_700">#5D4037</color>

    <color name="brown_800">#4E342E</color>

    <color name="brown_900">#3E2723</color>

    <!-- Brown -->


    <!-- Blue Grey -->

    <color name="blue_grey_50">#ECEFF1</color>

    <color name="blue_grey_100">#CFD8DC</color>

    <color name="blue_grey_200">#B0BEC5</color>

    <color name="blue_grey_300">#90A4AE</color>

    <color name="blue_grey_400">#78909C</color>

    <color name="blue_grey_500">#607D8B</color>

    <color name="blue_grey_600">#546E7A</color>

    <color name="blue_grey_700">#455A64</color>

    <color name="blue_grey_800">#37474F</color>

    <color name="blue_grey_900">#263238</color>

    <!-- Blue Grey -->





Android Studio에서 아무 설정도 하지 않고 APK를 생성하면 release, debug 이런식으로 생성이 되기 때문에 생성후에 다시 이름을 바꿔줘야한다. 


이것은 매우 귀찮은 일이다..


그러므로 build.gradle에서 설정 해주도록 하자.







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
 
android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'
//    lintOptions {
//        checkReleaseBuilds false
//    }
    dexOptions {
        javaMaxHeapSize '2g'
    }
    defaultConfig {
        applicationId 'com.fullstack'
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 113
        versionName "1.1.3"
        multiDexEnabled true
    }
 
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
        }
 
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def apk = output.outputFile;
                def newName = apk.name.replace(".apk""_" + defaultConfig.versionCode + ".apk");
                output.outputFile = new File(apk.parentFile, newName);
            }
        }
 
    }
}
 
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
}
cs



코드는 뭐 이런식으로 되어있을 테고.. 봐야할 부분은 다음이다. buildTypes안에 넣어주면 된다.


1
2
3
4
5
6
7
8
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def apk = output.outputFile;
        def newName = apk.name.replace(".apk""_" + defaultConfig.versionCode + ".apk");
        output.outputFile = new File(apk.parentFile, newName);
    }
}
 
cs

apk.name.replace에서 원하는 부분으로 바꿔주도록 한다. 위에 설정은 .apk 부분을 버전 코드를 넣어서 바꾼 부분이다.

이렇게 하면 apk가 생성되었을 때 버전 코드가 같이 붙어나오므로 보기도 편하고 관리도 쉽다. 






계속 업데이트중입니다.


플랫폼 버전API 레벨버전 코드참고
Android 10.029Q플랫폼 하이라이트
Android 928P플랫폼 하이라이트
Android 8.127O_MR1플랫폼 하이라이트
Android 8.026O플랫폼 하이라이트
Android 7.1.1
Android 7.1
25N_MR1플랫폼 하이라이트
Android 7.024N플랫폼 하이라이트
Android 6.023M플랫폼 하이라이트
Android 5.122LOLLIPOP_MR1플랫폼 하이라이트
Android 5.021LOLLIPOP
Android 4.4W20KITKAT_WATCH웨어러블 기기 전용 KitKat
Android 4.419KITKAT플랫폼 하이라이트
Android 4.318JELLY_BEAN_MR2플랫폼 하이라이트
Android 4.2, 4.2.217JELLY_BEAN_MR1플랫폼 하이라이트
Android 4.1, 4.1.116JELLY_BEAN플랫폼 하이라이트
Android 4.0.3, 4.0.415ICE_CREAM_SANDWICH_MR1플랫폼 하이라이트
Android 4.0, 4.0.1, 4.0.214ICE_CREAM_SANDWICH
Android 3.213HONEYCOMB_MR2
Android 3.1.x12HONEYCOMB_MR1플랫폼 하이라이트
Android 3.0.x11HONEYCOMB플랫폼 하이라이트
Android 2.3.4
Android 2.3.3
10GINGERBREAD_MR1플랫폼 하이라이트
Android 2.3.2
Android 2.3.1
Android 2.3
9GINGERBREAD
Android 2.2.x8FROYO플랫폼 하이라이트
Android 2.1.x7ECLAIR_MR1플랫폼 하이라이트
Android 2.0.16ECLAIR_0_1
Android 2.05ECLAIR
Android 1.64DONUT플랫폼 하이라이트
Android 1.53CUPCAKE플랫폼 하이라이트
Android 1.12BASE_1_1
Android 1.01BASE



출처 : http://developer.android.com/intl/ko/guide/topics/manifest/uses-sdk-element.html





HttpURLConnection을 사용하여 Multipart Upload를 수행하고 그 과정을 ProgressBar로 보여주기를 하는 코드이다.


다음 순서대로 작성하고 적용하면 끝.





1. 인터페이스 생성



1
2
3
4
public interface ProgressListener { 
   void onProgressUpdate(int progress);
}
 
cs




2. MultipartUpload 클래스



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 
public class MultipartUpload {
 
    private final String boundary;
    private final String tail;
    private static final String LINE_END = "\r\n";
    private static final String TWOHYPEN = "--";
    private HttpURLConnection httpConn;
    private String charset;
    private PrintWriter writer;
    private OutputStream outputStream;
    private static final String TAG = "MultipartUtility";
    int maxBufferSize = 1024;
    private ProgressListener progressListener;
    private long startTime;
 
    public MultipartUpload(String requestURL, String charset) throws IOException {
        this.charset = charset;
 
        boundary = "===" + System.currentTimeMillis() + "===";
        tail = LINE_END + TWOHYPEN + boundary + TWOHYPEN + LINE_END;
        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();        
        httpConn.setDoOutput(true); 
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type""multipart/form-data; boundary=" + boundary);
    }
 
    public void setProgressListener(ProgressListener progressListener) {
        this.progressListener = progressListener;
    }
 
    public JSONObject upload(HashMap<StringString> params, HashMap<StringString> files) throws IOException {
        String paramsPart = "";
        String fileHeader = "";
        String filePart = "";
        long fileLength = 0;
        startTime = System.currentTimeMillis();
 
        ArrayList<String> paramHeaders = new ArrayList<>();
        for (Map.Entry<StringString> entry : params.entrySet()) {
 
            String param = TWOHYPEN + boundary + LINE_END
                    + "Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END
                    + "Content-Type: text/plain; charset=" + charset + LINE_END
                    + LINE_END
                    + entry.getValue() + LINE_END;
            paramsPart += param;
            paramHeaders.add(param);
        }
 
        ArrayList<File> filesAL = new ArrayList<>();
        ArrayList<String> fileHeaders = new ArrayList<>();
 
        for (Map.Entry<StringString> entry : files.entrySet()) {
            
            File file = new File(entry.getValue());
            fileHeader = TWOHYPEN + boundary + LINE_END
                    + "Content-Disposition: form-data; name=\"" + entry.getKey() + "\"; filename=\"" + file.getName() + "\"" + LINE_END
                    + "Content-Type: " + URLConnection.guessContentTypeFromName(file.getAbsolutePath()) + LINE_END
                    + "Content-Transfer-Encoding: binary" + LINE_END
                    + LINE_END;
            fileLength += file.length() + LINE_END.getBytes(charset).length;
            filePart += fileHeader;
 
            fileHeaders.add(fileHeader);
            filesAL.add(file);
        }
        String partData = paramsPart + filePart;
 
        long requestLength = partData.getBytes(charset).length + fileLength + tail.getBytes(charset).length;
        httpConn.setRequestProperty("Content-length""" + requestLength);
        httpConn.setFixedLengthStreamingMode((int) requestLength);
        httpConn.connect();
 
        outputStream = new BufferedOutputStream(httpConn.getOutputStream());
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
 
        for (int i = 0; i < paramHeaders.size(); i++) {
            writer.append(paramHeaders.get(i));
            writer.flush();
        }
 
        int totalRead = 0;
        int bytesRead;
        byte buf[] = new byte[maxBufferSize];
        for (int i = 0; i < filesAL.size(); i++) {
            writer.append(fileHeaders.get(i));
            writer.flush();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filesAL.get(i)));
            while ((bytesRead = bufferedInputStream.read(buf)) != -1) {
 
                outputStream.write(buf, 0, bytesRead);
                writer.flush();
                totalRead += bytesRead;
                if (progressListener != null) {
                    float progress = (totalRead / (float) requestLength) * 100;
                    progressListener.onProgressUpdate((int) progress);
                }
            }
            outputStream.write(LINE_END.getBytes());
            outputStream.flush();
            bufferedInputStream.close();
        }
        writer.append(tail);
        writer.flush();
        writer.close();
 
        JSONObject jObj = null;
        StringBuilder sb = new StringBuilder();
        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "UTF-8"), 8);
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            reader.close();
            httpConn.disconnect();            
        } else {
            throw new IOException("Server returned non-OK status: " + status + " " + httpConn.getResponseMessage());
        }
        try {
            jObj = new JSONObject(sb.toString());
        } catch (JSONException | NullPointerException e) {
            e.printStackTrace();
        }
        return jObj;
 
    }
 
}
cs





3. 사용법



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class UploadAsync extends AsyncTask<Object, Integer, JSONObject> implements ProgressListener {
 
    private ProgressDialog progressDialog;
    private Context mContext;    
    private HashMap<StringString> param;
    private HashMap<StringString> files;
 
    public UploadAsync(Context context, HashMap<StringString> param, HashMap<StringString> files) {
        mContext = context;
        this.param = param;
        this.files = files;
    }
 
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        startTime = System.currentTimeMillis();
        progressDialog = new ProgressDialog(mContext);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMessage(mContext.getString(R.string.wait));
        progressDialog.setMax(100);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }
 
    @Override
    protected JSONObject doInBackground(Object... params) {
        JSONObject json = null;
        try {
        
            String url = "http://요청할 URL";
            MultipartUpload multipartUpload = new MultipartUpload(url, "UTF-8");
            multipartUpload.setProgressListener(this);
            json = multipartUpload.upload(param, files);            
 
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
 
    }
 
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (progressDialog != null && progressDialog.isShowing()) {
            if (values[1== 1) {
                progressDialog.setProgress(values[0]);
            } else {
                progressDialog.setProgress(values[0]);
            }
        }
    }
 
    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
 
        if (result != null) {
            try {
                if (result.getInt("success"== 1) {                            
                    Toast.makeText(mContext, R.string.success, Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(mContext, R.string.conntection_error, Toast.LENGTH_SHORT).show();
        }
    }
 
    @Override
    public void onProgressUpdate(int progress) {
        publishProgress(progress, 0);
    }
}
 
cs


  네트워크 작업이므로 반드시 스레드 안에서 실행해야 한다.


  생성자로 접속할 url과 캐릭터셋을 넣고,  프로그레스를 받을 인터페이스 리스너를 등록 한 후 파라미터 파트와 파일 파트를 HashMap으로 구성하여 인자로 넘겨준다. 


  한가지 문제점은 실제로 접속하여 파일을 전송하는 과정이 progress되지 않는다는 점이다. MultipartUpload 클래스에 보면 outputstream에 쓰는 과정을 progress로 보여주는데 사실 이것이 파일이 전송됨을 의미하지는 않는다는 점이다. 단지 버퍼에서 읽는 부분일뿐.. 실제 예제를 만들어 progress가 100%가 후에 전송을 시작하여 마치 앱이 멈춘것 처럼 동작한다. 파일 크기가 작으면 전송이 빨리되어 약간의 딜레이가 생기겠지만 파일이 큰 경우 오류난것 처럼 보인다. 


  버퍼에 쓴다음 바로 flush를 해줘도 똑같다. setFixedLenghStreamingMode를 해주면 된다고는 하는데 안된다! 이거 실제 전송되는 부분 아시는분은 알려주시면 감사하겠습니다. 


+ Recent posts