1. 程式人生 > >android多渠道打包(動態改變地址打包,只需改下版本號)

android多渠道打包(動態改變地址打包,只需改下版本號)

多渠道打包本來不想寫的,因為比較麻煩,所以沒打算寫。只是前段時間因為電腦藍屏重灌了系統,導致不能打包了,所以又百度了半天,今天就寫下來做個筆記。

廢話不多說,進入主題。

配置多渠道打包就要使用友盟統計


build.gradle中新增友盟的依賴包:

//友盟統計
compile 'com.umeng.analytics:analytics:latest.integration'

一、配置AndroidManifest.xml

1、許可權(4個許可權一定要寫,   ps:我這裡就不寫了,因為我這裡4個都是重複的,就做下備註.   大家去友盟裡面複製下來貼上)

<!-- 友盟統計許可權 這4個許可權都是必須新增
ACCESS_NETWORK_STATEACCESS_WIFI_STATEINTERNETREAD_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;