android多渠道打包(動態改變地址打包,只需改下版本號)
多渠道打包本來不想寫的,因為比較麻煩,所以沒打算寫。只是前段時間因為電腦藍屏重灌了系統,導致不能打包了,所以又百度了半天,今天就寫下來做個筆記。
廢話不多說,進入主題。
配置多渠道打包就要使用友盟統計
build.gradle中新增友盟的依賴包:
//友盟統計 compile 'com.umeng.analytics:analytics:latest.integration'
一、配置AndroidManifest.xml
1、許可權(4個許可權一定要寫, ps:我這裡就不寫了,因為我這裡4個都是重複的,就做下備註. 大家去友盟裡面複製下來貼上)
<!-- 友盟統計許可權 這4個許可權都是必須新增ACCESS_NETWORK_STATE、ACCESS_WIFI_STATE、INTERNET、READ_PHONE_STATE -->
2、友盟配置(value 就是你的Appkey)
<!-- 友盟 --> <!-- 替換為在友盟後臺申請的應用Appkey --> <meta-data android:name="UMENG_APPKEY" android:value="5aXXX2df29d9821bbXXXXXX"/> <!-- 應用的推廣渠道名稱,Channel ID自定義 --> <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/>
二、在build.gradle設定productFlavors
記住:渠道包名稱不能以數字開頭。比如:360的包就不可以, 我在前面加了一個大寫C
android{
productFlavors {dandanzhuan { dimension "default" } //蛋蛋賺 yingyongbao { dimension "default" } //騰訊開放平臺-應用寶 huawei { dimension "default" } //智匯雲應用市場-華為 ppzhushou { dimension"default" } //PP助手 C360 { dimension "default" } //360應用市場 diankai { dimension "default" } //點開廣告 oppo { dimension "default" } //oppo應用市場 youmi { dimension "default" } //有米廣告 xiaomi { dimension "default" } //小米應用市場 meizu { dimension "default" } //魅族應用市場 xunfei { dimension "default" } //訊飛更新包 mumayi { dimension "default" } //木螞蟻 vivo { dimension "default" } //vivo } productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] }
}
三、配置渠道包的輸出路徑(jglc是我的專案簡稱, _v是版本字母的開頭字母。例如jglc_v3.1.0_20180425_release_Releases.apk)
//修改生成的最終檔名 applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) {def fileName if (!project.hasProperty('FILE_NAME')) { if (variant.buildType.name == "release") { // 輸出apk名稱為app_v1.0.0_2015-06-15_playStore.apk _${variant.productFlavors[0].name} fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "releaselog") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "check") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "debug") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "dev") { // fileName = outputFile.name fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } } else { fileName = FILE_NAME } outputFileName = fileName } } }
獲取時間程式碼(位置與android{}同級):
def releaseTime() { return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) }
接下來我們說下怎麼動態獲取正式服、開發服、測試服的地址 以及 動態指定版本號版本名
四、在build.gradle裡面配置url地址以及版本號、版本名
//預設版本號和版本名 def DEF_VERSION_CODE = 27 def DEF_VERSION_NAME = "3.1.0"//正式環境 def API_RELEASE_HOST = "\"https://www.XXXXXX.cn\"" //開發環境 def API_DEV_HOST = "\"http://develop.XXXXXX.cn\"" //測試環境 def API_TEST_HOST = "\"http://test.XXXXXX.cn\""
defaultConfig {//動態指定版本號版本名 versionCode project.hasProperty('VERSION_CODE') ? Integer.parseInt(VERSION_CODE) : DEF_VERSION_CODE versionName project.hasProperty('VERSION_NAME') ? VERSION_NAME : "${DEF_VERSION_NAME}" flavorDimensions "default" println("versionCode = " + versionCode + " versionName = " + versionName) buildConfigField("String", "API_HOST", "${API_RELEASE_HOST}") }
buildTypes { debug { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_TEST_HOST}" minifyEnabled false //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }release { // 不顯示Log buildConfigField "boolean", "LOG_DEBUG", "false" buildConfigField "String", "API_HOST", "${API_RELEASE_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 正式環境顯示log */ releaselog { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_RELEASE_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 開發環境 */ dev { buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_DEV_HOST}" minifyEnabled false //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 測試環境 */ check { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_TEST_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
moudle裡面也要配置(如圖):
我的build.gradle的配置
apply plugin: 'com.android.application' apply plugin: 'com.jakewharton.butterknife' android { compileSdkVersion 25 buildToolsVersion '26.0.2' //預設版本號和版本名 def DEF_VERSION_CODE = 27 def DEF_VERSION_NAME = "3.1.0" useLibrary 'org.apache.http.legacy' //正式環境 def API_RELEASE_HOST = "\"https://www.XXXXX.cn\"" //開發環境 def API_DEV_HOST = "\"http://develop.XXXXX.cn\"" //測試環境 def API_TEST_HOST = "\"http://test.XXXXX.cn\"" defaultConfig { applicationId "cn.XXXXX.app" minSdkVersion 15 targetSdkVersion 22 multiDexEnabled true //動態指定版本號版本名 versionCode project.hasProperty('VERSION_CODE') ? Integer.parseInt(VERSION_CODE) : DEF_VERSION_CODE versionName project.hasProperty('VERSION_NAME') ? VERSION_NAME : "${DEF_VERSION_NAME}" flavorDimensions "default" println("versionCode = " + versionCode + " versionName = " + versionName) buildConfigField("String", "API_HOST", "${API_RELEASE_HOST}") ndk { //設定支援的SO庫架構 abiFilters "armeabi", "x86"//, 'armeabi-v7a', 'x86_64', 'arm64-v8a' } manifestPlaceholders = [ JPUSH_PKGNAME: applicationId, JPUSH_APPKEY : "88d9754a5b3589d6f09a362e", //JPush上註冊的包名對應的appkey. JPUSH_CHANNEL: "developer-default", //暫時填寫預設值即可. ] } signingConfigs { release { storeFile file(STORE_FILE); storePassword STORE_PASSWORD keyAlias KEY_ALIAS keyPassword KEY_PASSWORD } debug { storeFile file(STORE_FILE); storePassword STORE_PASSWORD keyAlias KEY_ALIAS keyPassword KEY_PASSWORD } } buildTypes { debug { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_TEST_HOST}" minifyEnabled false //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }release { // 不顯示Log buildConfigField "boolean", "LOG_DEBUG", "false" buildConfigField "String", "API_HOST", "${API_RELEASE_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 正式環境顯示log */ releaselog { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_RELEASE_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 開發環境 */ dev { buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_DEV_HOST}" minifyEnabled false //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } /* 測試環境 */ check { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "API_HOST", "${API_TEST_HOST}" minifyEnabled true //是否混淆 //是否設定zip對齊優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //簽名 signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } lintOptions { disable 'MissingTranslation' abortOnError false } dexOptions { // preDexLibraries true // javaMaxHeapSize "8g" // incremental true // dexInProcess = true } //修改生成的最終檔名 applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) {def fileName if (!project.hasProperty('FILE_NAME')) { if (variant.buildType.name == "release") { // 輸出apk名稱為app_v1.0.0_2015-06-15_playStore.apk _${variant.productFlavors[0].name} fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "releaselog") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "check") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "debug") { fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } else if (variant.buildType.name == "dev") { // fileName = outputFile.name fileName = "jglc_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}_${variant.productFlavors[0].name}.apk" } } else { fileName = FILE_NAME } outputFileName = fileName } } } //配置多版本的apk productFlavors {dandanzhuan { dimension "default" } //蛋蛋賺 yingyongbao { dimension "default" } //騰訊開放平臺-應用寶 huawei { dimension "default" } //智匯雲應用市場-華為 ppzhushou { dimension "default" } //PP助手 C360 { dimension "default" } //360應用市場 diankai { dimension "default" } //點開廣告 oppo { dimension "default" } //oppo應用市場 youmi { dimension "default" } //有米廣告 xiaomi { dimension "default" } //小米應用市場 meizu { dimension "default" } //魅族應用市場 xunfei { dimension "default" } //訊飛更新包 mumayi { dimension "default" } //木螞蟻 vivo { dimension "default" } //vivo } productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] } } def releaseTime() { return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) } repositories { flatDir { dirs 'libs' } google() } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') // compile 'com.mcxiaoke.volley:library:1.0.19' compile(name: 'viewpagerindicator-2.4.2', ext: 'aar') // compile 'com.github.navasmdc:MaterialDesign:[email protected]' // compile 'it.neokree:MaterialNavigationDrawer:1.3.2' // compile 'me.zhanghai.android.materialprogressbar:library:1.1.4' compile files('libs/Baofoo_SDK_IDC_V2.0.jar') // compile 'com.tencent.bugly:crashreport_upgrade:latest.release' //其中latest.release指代最新版本號,也可以指定明確的版本號,例如1.0.0 compile files('libs/AutoUpdate_SDK.jar') implementation project(':library') // 此處以JPush 3.0.0 版本為例。 // 此處以JCore 1.0.0 版本為例。 // compile 'com.github.barteksc:android-pdf-viewer:2.1.0' compile files('libs/MobCommons-2017.0608.1618.jar') compile files('libs/MobTools-2017.0608.1618.jar') compile files('libs/ShareSDK-Core-3.0.0.jar') compile files('libs/ShareSDK-QQ-3.0.0.jar') compile files('libs/ShareSDK-QZone-3.0.0.jar') compile files('libs/ShareSDK-SinaWeibo-3.0.0.jar') compile files('libs/ShareSDK-Wechat-3.0.0.jar') compile files('libs/ShareSDK-Wechat-Core-3.0.0.jar') compile files('libs/ShareSDK-Wechat-Favorite-3.0.0.jar') compile files('libs/ShareSDK-Wechat-Moments-3.0.0.jar') //其中latest.release指代最新Bugly SDK版本號,也可以指定明確的版本號,例如2.1.9 compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:design:23.4.0' compile 'com.android.support:multidex:1.0.1' compile 'de.greenrobot:eventbus:2.4.0' compile 'in.srain.cube:ultra-ptr:1.0.11' compile 'in.srain.cube:cube-sdk:[email protected]' compile 'in.srain.cube:clog:1.0.2' compile 'com.baoyz.swipemenulistview:library:1.3.0' compile 'com.bigkoo:pickerview:1.0.3' compile 'com.bigkoo:convenientbanner:2.0.5' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.zcw:togglebutton-library:1.0.0' compile 'com.github.barteksc:android-pdf-viewer:2.7.0-beta' compile 'com.android.support:support-v4:25.3.1' compile 'cn.jiguang.sdk:jpush:3.0.0' compile 'cn.jiguang.sdk:jcore:1.0.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support:cardview-v7:23.4.0' compile 'com.tencent.bugly:crashreport:2.6.5' compile 'com.bm.photoview:library:1.4.1' compile 'com.android.support:percent:23.4.0' //retrofit+rxjava+okhttp compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'com.squareup.okhttp3:okhttp:3.8.0' compile 'com.squareup.okhttp3:logging-interceptor:3.8.0' compile 'io.reactivex.rxjava2:rxjava:2.1.0' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.flyco.dialog:FlycoDialog_Lib:1.0.0' compile 'com.google.zxing:core:3.3.0' compile 'com.github.yidun:captcha-android-demo:2.4' //友盟統計 compile 'com.umeng.analytics:analytics:latest.integration' //butterknife compile 'com.jakewharton:butterknife:8.4.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' //logger compile 'com.orhanobut:logger:2.1.1' }
然後就是你URL工具類的配置,如下圖:
public static final String SERVER_HOST = BuildConfig.API_HOST;
基本已經完成了所有的配置,如下圖:
在terminal中使用gradle命令打包的前提就是先配置gradle(2種方法)。
1、在你電腦系統環境變數中配置(我的gradle路徑)
新建,變數名:GRADLE_HOME
變數值:D:\Gradle_4.3all\gradle-4.3.1-all\gradle-4.3.1
Path中新增: %GRADLE_HOME%\bin
第二種配置gradle就是直接在terminal中輸入 gradlew回車,自動去下載,很慢的。
配置完成之後:
在terminal中輸入命令列 (比如打C360正式服的渠道包):
window系統:gradle assembleC360Release
mac系統:./gradle assembleC360Release
如果沒有配置gradle,會提示:'gradle' 不是內部或外部命令,也不是可執行的程式 或批處理檔案。
上面的配置完成之後友盟也收不到使用者在哪下載的,因為渠道邀請碼還沒寫,友盟怎麼能收集到呢,接下來才是重點。
下面就是具體操作用友盟來收集各個渠道的下載量 (渠道邀請碼(XXXX)大家去找運營要),工具類:
package com.XXXX.app.base.util;