1. 程式人生 > >Qt for Android gradle編譯同時輸出多個渠道apk

Qt for Android gradle編譯同時輸出多個渠道apk

前言

Gradle是Android目前主流的編譯工具,Gradle剛出來的時候確實有很多詬病,比如編譯速度,那真是一個慢啊,不過隨著版本的更新,現在的gradle可比當年牛逼多了,功能也越來越完善,畢竟是谷歌的親兒子。那麼在用Qt 做android開發時候,也是預設使用Gradle來編譯,今天主要來看看如何在Qt工程下修改gradle檔案並輸出多個渠道的apk並自動簽名,輸出多個渠道apk主要是用於統計每個渠道的安裝資訊。

正文

在之前寫過的這篇文章中:Qt for Android建立AndroidManifest.xml和Java類檔案 介紹瞭如何建立AndroidManifest.xml檔案,建立後會自動生成gradle的相關檔案,如下圖:
在這裡插入圖片描述


在這裡我們只需要編輯build.gradle檔案即可,雙擊開啟然後修改該檔案,添加簽名以及將要輸出的渠道資訊:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

apply plugin: 'com.android.application'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

android {
    /*******************************************************
     * The following variables:
     * - androidBuildToolsVersion,
     * - androidCompileSdkVersion
     * - qt5AndroidDir - holds the path to qt android files
     *                   needed to build any Qt application
     *                   on Android.
     *
     * are defined in gradle.properties file. This file is
     * updated by QtCreator and androiddeployqt tools.
     * Changing them manually might break the compilation!
     *******************************************************/

    compileSdkVersion androidCompileSdkVersion.toInteger()

    buildToolsVersion androidBuildToolsVersion

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
            aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
            //res.srcDirs = [qt5AndroidDir + '/res', 'res']
            res.srcDirs = ['res']
            resources.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
       }
    }

    lintOptions {
        abortOnError false
    }

    signingConfigs {
            release {
                storeFile file("xxxxx.keystore")
                storePassword "xxxxxx"
                keyAlias "xxxxx"
                keyPassword "xxxxxx"
            }
        }

    buildTypes {
        release {
                   minifyEnabled false
                   proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
                   signingConfig signingConfigs.release
               }
        }
    productFlavors {
          yingyongbao {
                manifestPlaceholders = [ CHANNEL_NAME:"YingYongBao" ]
          }
          wandoujia {
                manifestPlaceholders = [ CHANNEL_NAME:"WanDouJia" ]
          }
          yingyongbao {
                manifestPlaceholders = [ CHANNEL_NAME:"YingYongBao" ]
          }
      }
}

def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
//這裡是修改輸出的apk名稱
android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def outputFile = output.outputFile
        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            File outputDirectory = new File(outputFile.parent);
            def fileName
            if (variant.buildType.name == "release") {
                fileName = "Demo_${variant.productFlavors[0].name}_${releaseTime()}.apk"
                output.outputFile = new File(outputDirectory, fileName)
            }
        }
    }
}

注意,下面就是配置自動簽名流程:

 signingConfigs {
        release {
                storeFile file("xxxxx.keystore")
                storePassword "xxxxxx"
                keyAlias "xxxxx"
                keyPassword "xxxxxx"
         }
 }

接下來在AndroidManifest.xml檔案中新增渠道獲取的資訊:

<meta-data android:name="CHANNEL" android:value="${CHANNEL_NAME}"/>

在這裡插入圖片描述

接著,回到java程式碼中,新增獲取渠道的介面:

public static String getChannel(){
            ComponentName componentName = new ComponentName(m_instance,MainActivity.class);
            try
            {
                ActivityInfo info = m_instance.getPackageManager()
                                  .getActivityInfo(componentName,
                                      PackageManager.GET_META_DATA);
                String msg =info.metaData.getString("CHANNEL");
                return msg;
              }catch (Exception e) {
                    e.printStackTrace();
                    return "";
               }

        }

需要匯入包:

import android.content.ComponentName;
import android.content.pm.ActivityInfo;

ok,這就能直接獲取到每個安裝包的渠道名了。