diff --git a/.github/workflows/testBranch.yml b/.github/workflows/testBranch.yml
index 86eb842..e2aac81 100644
--- a/.github/workflows/testBranch.yml
+++ b/.github/workflows/testBranch.yml
@@ -31,6 +31,9 @@ jobs:
uses: android-actions/setup-android@v3
- name: Generate kover coverage report
+ env:
+ ADMOB_APP_ID: ${{ secrets.ADMOB_APP_ID }}
+ ADMOB_BANNER_ID: ${{ secrets.ADMOB_BANNER_ID }}
run: |
chmod +x ./gradlew
./gradlew koverXmlReport
diff --git a/app/.gitignore b/app/.gitignore
index 42afabf..626c8a5 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -1 +1,2 @@
-/build
\ No newline at end of file
+/build
+.env
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index bcc8a7a..c2fee4c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -18,8 +18,9 @@ android {
targetSdk = 35
versionCode = 1
versionName = "1.0"
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ resValue("string", "admob_app_id", System.getenv("ADMOB_APP_ID") ?: "")
+ resValue("string", "admob_banner_id", System.getenv("ADMOB_BANNER_ID") ?: "")
}
buildTypes {
@@ -160,4 +161,7 @@ dependencies {
kspTest(libs.hilt.android.compiler)
androidTestImplementation(libs.hilt.android.testing)
kspAndroidTest(libs.hilt.android.compiler)
+
+ // 구글 광고
+ implementation(libs.play.services.ads)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5428f7d..3145652 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,6 +17,10 @@
android:theme="@style/Theme.NotiManager"
android:enableOnBackInvokedCallback="true"
tools:targetApi="35">
+
+
Unit, onAdFailedToLoad: (LoadAdError) -> Unit): AdLoader {
+ return AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110")
+ .forNativeAd { ad: NativeAd ->
+ onAdLoaded(ad) // 광고가 로드되었을 때 호출
+ }
+ .withAdListener(object : AdListener() {
+ override fun onAdFailedToLoad(adError: LoadAdError) {
+ onAdFailedToLoad(adError) // 광고 로드 실패 시 호출
+ }
+ })
+ .withNativeAdOptions(NativeAdOptions.Builder().build())
+ .build()
+}
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt
new file mode 100644
index 0000000..8c9b6ab
--- /dev/null
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt
@@ -0,0 +1,38 @@
+package com.example.notimanager.presentation.ui.ads
+
+import android.app.Activity
+import android.content.Context
+import android.os.Build
+import android.view.WindowMetrics
+import com.example.notimanager.R
+import com.google.android.gms.ads.AdRequest
+import com.google.android.gms.ads.AdSize
+import com.google.android.gms.ads.AdView
+
+object AdsUtil{
+ // Get the ad size with screen width.
+ private fun getAdSize(context: Context): AdSize {
+ val displayMetrics = context.resources.displayMetrics
+ val adWidthPixels =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ val windowMetrics: WindowMetrics = (context as? Activity)?.windowManager!!.currentWindowMetrics
+ windowMetrics.bounds.width()
+ } else {
+ displayMetrics.widthPixels
+ }
+ val density = displayMetrics.density
+ val adWidth = (adWidthPixels / density).toInt()
+ return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth)
+ }
+
+ fun getAdView(context: Context): AdView{
+ val unitId = context.getString(R.string.admob_banner_id)
+ val adView = AdView(context)
+ adView.adUnitId = unitId
+ adView.setAdSize(getAdSize(context))
+
+ val adRequest = AdRequest.Builder().build()
+ adView.loadAd(adRequest)
+ return adView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt
new file mode 100644
index 0000000..33b7290
--- /dev/null
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt
@@ -0,0 +1,39 @@
+package com.example.notimanager.presentation.ui.ads
+
+import android.view.View
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.viewinterop.AndroidView
+import com.google.android.gms.ads.nativead.NativeAd
+import com.google.android.gms.ads.nativead.NativeAdView
+
+@Composable
+fun NotiNativeAdView(
+ ad: NativeAd,
+ adContent: @Composable (ad: NativeAd, contentView: View) -> Unit,
+) {
+ val contentViewId by remember { mutableIntStateOf(View.generateViewId()) }
+ val adViewId by remember { mutableIntStateOf(View.generateViewId()) }
+ AndroidView(
+ factory = { context ->
+ val contentView = ComposeView(context).apply {
+ id = contentViewId
+ }
+ NativeAdView(context).apply {
+ id = adViewId
+ addView(contentView)
+ }
+ },
+ update = { view ->
+ val adView = view.findViewById(adViewId)
+ val contentView = view.findViewById(contentViewId)
+
+ adView.setNativeAd(ad)
+ adView.callToActionView = contentView
+ contentView.setContent { adContent(ad, contentView) }
+ }
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt
new file mode 100644
index 0000000..1a409cc
--- /dev/null
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt
@@ -0,0 +1,65 @@
+package com.example.notimanager.presentation.ui.ads
+
+import android.util.Log
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Badge
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import com.example.notimanager.R
+import com.example.notimanager.common.objects.DateFormatter.toBitmap
+import com.example.notimanager.presentation.ui.component.common.AppIconView
+import com.google.android.gms.ads.nativead.NativeAd
+
+@Composable
+fun NotiNativeAds(nativeAd: NativeAd) {
+ NotiNativeAdView(ad = nativeAd) { ad, view ->
+ Row(
+ modifier = Modifier.padding(16.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ AppIconView(ad.icon?.drawable?.toBitmap())
+ Column {
+ // 광고 뱃지와 함께 광고 제목
+ Row(){
+ Image(
+ painter = painterResource(id = R.drawable.ad_badge),
+ contentDescription = "ad badge",
+ modifier = Modifier.size(16.dp)
+ )
+ ad.headline?.let {
+ Text(
+ text = it,
+ style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold),
+ )
+ }
+ }
+ ad.body?.let {
+ Text(
+ text = it,
+ style = MaterialTheme.typography.bodySmall,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
+ )
+ }
+ }
+ TextButton(
+ content = { ad.callToAction?.let { Text(text = it) } },
+ onClick = { view.performClick() },
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt
index 031551d..223e103 100644
--- a/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt
@@ -113,6 +113,5 @@ fun DateFormatterView(
Text(apply)
}
}
-
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt
index fa049f6..472c5a2 100644
--- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt
@@ -1,6 +1,11 @@
package com.example.notimanager.presentation.ui.component.list
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.HorizontalDivider
@@ -10,13 +15,19 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavController
import com.example.notimanager.presentation.stateholder.state.NotificationAppPriorityState
import com.example.notimanager.presentation.stateholder.state.NotificationAppState
import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel
import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel
+import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView
import com.example.notimanager.presentation.ui.component.item.NotificationAppItemView
@Composable
@@ -30,6 +41,10 @@ fun NotificationAppListView(
var currentNotiPriority by remember { mutableStateOf(priorityState.notificationAppList) }
var currentNoti by remember { mutableStateOf(notificationAppState.notificationAppList) }
+ // 광고
+ val context = LocalContext.current
+ val adView = getAdView(context)
+
LaunchedEffect(priorityState.notificationAppList) {
if (!priorityState.isLoading) {
currentNotiPriority = priorityState.notificationAppList
@@ -42,41 +57,48 @@ fun NotificationAppListView(
}
}
- LazyColumn(
- Modifier.fillMaxSize()
- ) {
- items(currentNotiPriority) { notification ->
- NotificationAppItemView(
- notification = notification,
- onClick = {
- navController
- .navigate(
- "titleScreen/${notification.appName}"
- )
- },
- viewModel = viewModel,
- priorityViewModel = priorityViewModel
- )
- }
- if (currentNotiPriority.isNotEmpty()){
- item {
- HorizontalDivider()
+ Box(modifier = Modifier.fillMaxSize()) {
+ LazyColumn(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(bottom = 56.dp) // AndroidView의 높이만큼 패딩 추가
+ ) {
+ items(currentNotiPriority) { notification ->
+ NotificationAppItemView(
+ notification = notification,
+ onClick = {
+ navController.navigate("titleScreen/${notification.appName}")
+ },
+ viewModel = viewModel,
+ priorityViewModel = priorityViewModel
+ )
+ }
+ if (currentNotiPriority.isNotEmpty()) {
+ item {
+ HorizontalDivider()
+ }
}
- }
-
- items(currentNoti) { notification ->
- NotificationAppItemView(
- notification = notification,
- onClick = {
- navController
- .navigate(
- "titleScreen/${notification.appName}"
- )
- },
- viewModel = viewModel,
- priorityViewModel = priorityViewModel
- )
+ items(currentNoti) { notification ->
+ NotificationAppItemView(
+ notification = notification,
+ onClick = {
+ navController.navigate("titleScreen/${notification.appName}")
+ },
+ viewModel = viewModel,
+ priorityViewModel = priorityViewModel
+ )
+ }
}
+
+ AndroidView(
+ factory = { adView },
+ update = {},
+ modifier = Modifier
+ .align(Alignment.BottomCenter)
+ .fillMaxWidth()
+ .height(56.dp)
+ )
}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt
index 39b5a31..b130aef 100644
--- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt
@@ -1,6 +1,10 @@
package com.example.notimanager.presentation.ui.component.list
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
@@ -9,9 +13,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
import com.example.notimanager.presentation.stateholder.state.NotificationState
+import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView
import com.example.notimanager.presentation.ui.component.item.NotificationItemView
@@ -24,6 +32,8 @@ fun NotificationListView(
val context = LocalContext.current
var currentNoti by remember { mutableStateOf(notificationState.notificationList) }
+ val adView = getAdView(context)
+
LaunchedEffect(notificationState.notificationList) {
if (!notificationState.isLoading) {
currentNoti = notificationState.notificationList
@@ -33,15 +43,27 @@ fun NotificationListView(
}
}
- LazyColumn(
- modifier = Modifier.fillMaxSize()
- ) {
- items(currentNoti) { notification ->
- NotificationItemView (notification = notification, onClick = {
- if (notification.intent?.action != null)
- context.startActivity(notification.intent) },
- onDelete = onDelete
- )
+ Box(modifier = Modifier.fillMaxSize()) {
+ LazyColumn(
+ modifier = Modifier.fillMaxSize().padding(bottom = 56.dp)
+ ) {
+ items(currentNoti) { notification ->
+ NotificationItemView (notification = notification, onClick = {
+ if (notification.intent?.action != null)
+ context.startActivity(notification.intent) },
+ onDelete = onDelete
+ )
+ }
+
}
+
+ AndroidView(
+ factory = { adView },
+ update = {},
+ modifier = Modifier
+ .align(Alignment.BottomCenter)
+ .fillMaxWidth()
+ .height(56.dp)
+ )
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt
index 54a3e29..eaf7074 100644
--- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt
+++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt
@@ -1,6 +1,10 @@
package com.example.notimanager.presentation.ui.component.list
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.HorizontalDivider
@@ -11,13 +15,18 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavController
import com.example.notimanager.common.objects.Encoder.getEncodedString
import com.example.notimanager.presentation.stateholder.state.NotificationTitlePriorityState
import com.example.notimanager.presentation.stateholder.state.NotificationTitleState
import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel
import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel
+import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView
import com.example.notimanager.presentation.ui.component.item.NotificationTitleItemView
@Composable
@@ -35,6 +44,9 @@ fun NotificationTitleListView(
var currentNotiPriority by remember { mutableStateOf(priorityState.notificationTitleList) }
var currentNoti by remember { mutableStateOf(notificationTitleState.notificationTitleList) }
+ val context = LocalContext.current
+ val adView = getAdView(context)
+
LaunchedEffect(priorityState.notificationTitleList) {
if (!priorityState.isLoading) {
currentNotiPriority = priorityState.notificationTitleList
@@ -47,44 +59,56 @@ fun NotificationTitleListView(
}
}
- LazyColumn(
- modifier = Modifier.fillMaxSize()
- ) {
- items(currentNotiPriority) { notification ->
- NotificationTitleItemView(notification = notification, onClick = {
- if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False")
- else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True")
- }, viewModel = viewModel, priorityViewModel = priorityViewModel)
- }
-
- if (currentNotiPriority.isNotEmpty()){
- item {
- HorizontalDivider()
+ Box(){
+ LazyColumn(
+ modifier = Modifier.fillMaxSize().padding(bottom = 56.dp)
+ ) {
+ items(currentNotiPriority) { notification ->
+ NotificationTitleItemView(notification = notification, onClick = {
+ if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False")
+ else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True")
+ }, viewModel = viewModel, priorityViewModel = priorityViewModel)
}
- }
- items(currentNoti) { notification ->
- NotificationTitleItemView(notification = notification, onClick = {
- if (notification.subText == "") {
- viewModel.updateAsRead(notification.title)
- navController.navigate(
- "notificationScreen/${viewModel.getAppName()}/${
- getEncodedString(
- notification.title
- )
- }/False"
- )
+ if (currentNotiPriority.isNotEmpty()){
+ item {
+ HorizontalDivider()
}
- else {
- viewModel.updateAsSubText(notification.subText)
- navController.navigate(
- "notificationScreen/${viewModel.getAppName()}/${
- getEncodedString(
- notification.subText
- )
- }/True"
- )
- }}, viewModel = viewModel, priorityViewModel = priorityViewModel)
+ }
+
+ items(currentNoti) { notification ->
+ NotificationTitleItemView(notification = notification, onClick = {
+ if (notification.subText == "") {
+ viewModel.updateAsRead(notification.title)
+ navController.navigate(
+ "notificationScreen/${viewModel.getAppName()}/${
+ getEncodedString(
+ notification.title
+ )
+ }/False"
+ )
+ }
+ else {
+ viewModel.updateAsSubText(notification.subText)
+ navController.navigate(
+ "notificationScreen/${viewModel.getAppName()}/${
+ getEncodedString(
+ notification.subText
+ )
+ }/True"
+ )
+ }}, viewModel = viewModel, priorityViewModel = priorityViewModel)
+ }
}
+
+ AndroidView(
+ factory = { adView },
+ update = {},
+ modifier = Modifier
+ .align(Alignment.BottomCenter)
+ .fillMaxWidth()
+ .height(56.dp)
+ )
}
+
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ad_badge.xml b/app/src/main/res/drawable/ad_badge.xml
new file mode 100644
index 0000000..9cd3608
--- /dev/null
+++ b/app/src/main/res/drawable/ad_badge.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e3d1df0..1f52c41 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-agp = "8.8.2"
+agp = "8.9.0"
byteBuddy = "1.17.1"
byteBuddyAgent = "1.17.1"
coilCompose = "3.1.0"
@@ -29,6 +29,7 @@ composeBom = "2025.02.00"
mockk = "1.13.16"
mockkAndroid = "1.13.16"
navigationCompose = "2.8.7"
+playServicesAds = "24.0.0"
protoliteWellKnownTypes = "18.0.0"
roomCompiler = "2.6.1"
roomVersion = "2.6.1"
@@ -81,6 +82,7 @@ mockk-mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
mockk-mockk-android = { module = "io.mockk:mockk-android" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
androidx-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "runtimeLivedata" }
+play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "playServicesAds" }
protolite-well-known-types = { module = "com.google.firebase:protolite-well-known-types", version.ref = "protoliteWellKnownTypes" }
[plugins]
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index d922a38..fffb202 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Tue Feb 18 09:46:15 KST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists