Android Studio Gradle多渠道打包(动态设定App名称,应用图标,背景图片,状态栏颜色)、配置签名文件

动态设定App名称,应用图标

Module设置

build.gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.xuewei"
        minSdkVersion 17
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    /**
    * 多渠道配置:动态设定App名称,应用图标,背景图片,状态栏颜色。
     * 1.applicationId不一致,避免了覆盖安装;
     * 2.针对不同的商家 App名称,图标得使用manifestPlaceholders,manifestPlaceholders是一个类似HashMap的容器;
     *
     *
     */
    productFlavors{
        /**
         * QQ应用宝
         * http://open.qq.com/
         */
        QQ{
            applicationId "com.xuewei.qq"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 360手机助手
         * http://dev.360.cn/
         */
        _360{
            applicationId "com.xuewei.360"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 小米应用商店开发者平台
         * http://dev.xiaomi.com/console/
         */
        XIAOMI{
            applicationId "com.xuewei.xiaomi"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-百度手机助手
         * http://app.baidu.com/serve/
         */
        BAIDU_ZHUSHO{
            applicationId "com.xuewei.baiduzs"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-91市场
         * http://app.baidu.com/serve/
         */
        BAIDU_91{
            applicationId "com.xuewei.baidu91"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-android市场
         * http://app.baidu.com/serve/
         */
        BAIDU_ANDROID{
            applicationId "com.xuewei.baiduandroid"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
   }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
    compile 'com.android.support:support-v4:25.2.0'
}

关键代码:

defaultConfig{} 默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用

 productFlavors{
    ...
 }

AndroidManifest.xml

在清单文件里,通过 ${icon},${app_name} 引用module中build.gradle文件的manifestPlaceholders 容器中设置 icon , app_name等值。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xuewei">

    <application
        android:name=".XWApplication"
        android:allowBackup="true"
        android:icon="${icon}"
        android:label="${app_name}"
        android:roundIcon="${icon}"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--${icon},${app_name} 引用 manifestPlaceholders 容器中 icon , app_name 的值。-->
        <meta-data
            android:name="app_name"
            android:value="${app_name}"/>
        <meta-data
            android:name="icon"
            android:value="${icon}"/>
        <activity
            android:name=".activity.SplashActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

关键代码:

    <application
        android:icon="${icon}"
        android:label="${app_name}"
        android:roundIcon="${icon}">
        <meta-data
            android:name="app_name"
            android:value="${app_name}"/>
        <meta-data
            android:name="icon"
            android:value="${icon}"/>
    </application>

动态设定背景图片,状态栏颜色

和动态设定App名称、应用图标,基本一样,这里唯一不同的就是,需要在代码里获取manifestPlaceholders设置的值,进行动态改变。

注意:新增的配置同样需要在清单文件中添加 meta-data节点。

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

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

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

通过 Java 代码获取到 meta-data节点下 Android:value的值。

一般在 MyApplication 获取节点的值:

    ApplicationInfo info = null;
    try {
        info = this.getPackageManager().getApplicationInfo(getPackageName(), PackageManager
                .GET_META_DATA);
        int tintColor = info.metaData.getInt("tint_color");
        String loadUrl=info.metaData.getString("load_url");
        String welcomePath = info.metaData.getString("welcome_bg");

    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

注意:设置welcome_bg:”@mipmap/klg_welcome”,我这里以int welcomeRes = info.metaData.getInt(“welcome_bg”);去取值,每次都返回0,但tint_color的值就正常。按正常思维@mipmap/klg_welcome返回的是 int 值,后来我换成getString还真获取到了值:res/mipmap-hdpi-v4/sjyg_welcome.png。获取到路径值,背景的图片资源就不能直接使用。

那么我们把路径资源转换成int资源,这里就用到了 Java 的反射。具体代码如下:

   Class c = R.mipmap.class;
    Field[] fields = c.getFields();
    for (Field field : fields) {
        if (field.getName().equals(welcomePath.substring(welcomePath.lastIndexOf("/") + 1,
                welcomePath.lastIndexOf(".")))) {
            this.welcomeBgRes = (int) field.get(c.newInstance());
            break;
        }
    }

还有一种方式在Java代码中可以方便获取到gradle配置文件的数据

    productFlavors{
    ...
        /**
         * QQ应用宝
         * http://open.qq.com/
         */
        QQ{
            applicationId "com.xuewei.qq"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
            resValue("string","key","123")
        }
        ...
   }

关键代码:

resValue("string","key","123")

通过代码:context.getResources().getString(R.string.key);获取值。

注意通过此方式 strings.xml 文件下不能有同名的 key 属性。不然会报相同资源引用错误。

生成APK和配置签名文件

生成所有渠道的包

Terminal命令输入如下指令:

gradlew assembleRelease

陈科肇
或者不使用命令
陈科肇
注意:*-unsigned.apk,都是没有签名的
我们需要在build.gradle配置签名文件

关键代码signingConfigs、buildTypes>release>signingConfig:

    signingConfigs {
        release {
            storeFile file("G:\\android\\signed\\xuewei\\xw.jks")
            storePassword "......"
            keyAlias "陈科肇"
            keyPassword "......"
            v2SigningEnabled true
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

陈科肇

签名文件配置成功

完整build.gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.xuewei"
        minSdkVersion 17
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    /**
    * 多渠道配置:动态设定App名称,应用图标,背景图片,状态栏颜色。
     * 1.applicationId不一致,避免了覆盖安装;
     * 2.针对不同的商家 App名称,图标得使用manifestPlaceholders,manifestPlaceholders是一个类似HashMap的容器;
     *
     *
     */
    productFlavors{
        /**
         * QQ应用宝
         * http://open.qq.com/
         */
        QQ{
            applicationId "com.xuewei.qq"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
            resValue("string","key","123")
        }
        /**
         * 360手机助手
         * http://dev.360.cn/
         */
        _360{
            applicationId "com.xuewei.360"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 小米应用商店开发者平台
         * http://dev.xiaomi.com/console/
         */
        XIAOMI{
            applicationId "com.xuewei.xiaomi"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-百度手机助手
         * http://app.baidu.com/serve/
         */
        BAIDU_ZHUSHO{
            applicationId "com.xuewei.baiduzs"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-91市场
         * http://app.baidu.com/serve/
         */
        BAIDU_91{
            applicationId "com.xuewei.baidu91"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
        /**
         * 百度-android市场
         * http://app.baidu.com/serve/
         */
        BAIDU_ANDROID{
            applicationId "com.xuewei.baiduandroid"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo"]
        }
   }
    signingConfigs {
        release {
            storeFile file("G:\\android\\signed\\xuewei\\xw.jks")
            storePassword "......"
            keyAlias "陈科肇"
            keyPassword "......"
            v2SigningEnabled true
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
    compile 'com.android.support:support-v4:25.2.0'
}

针对某个渠道打包

方式一:
陈科肇

方式二:
在defaultConfig配置manifestPlaceholders就可以。

问题

陈科肇

打包是成功,但同环境下不能安装多个多渠道打包(不同的applicationId)的apk。

不知道问题出在哪了,有人知道吗?


我们来看看Gradle Console打印的信息

E:\0Develop\work\gitHub\XueWei>gradlew assembleRelease
NDK is missing a "platforms" directory.ject > Resolving dependencies ':classpath'
If you are using NDK, verify the ndk.dir is set to a valid NDK directory.  It is currently set to I:\sdk\ndk-bundle.
If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning.

Incremental java compilation is an incubating feature.
:app:preBuild UP-TO-DATE
...
...
...

大概意思是,我项目使用了ndk,而android studio还没配置ndk环境。

好,接下来,我们配置好ndk环境再试试。

ndk配置:file>Project Structure…>SDK Location>Android NDK location
陈科肇

还是一样,不行。

我猜可能是三方包引用引起的问题,因为我另一个项目,完全可以。

陈科肇

最后,暂时设置applicationId一致吧。同环境不能安装两个或以上。

问题原因

终于找到原因了,原来是集成了有米移动广告的sdk造成的。
陈科肇

这是我用他们的demo做的测试。


有米广告的sdk是没有问题的,问题是我没注意人家有的文档说明
陈科肇

对了,就是android:authorities这个属性,包名.fileProvider。

所以每个渠道包,也需要不同的android:authorities

然后,就可以愉快地玩耍了。

陈科肇

注意

applicationId 每段的命名不要以全是数字方式命名,否则会有问题的。
比如:applicationId=“com.xuewei.360”这个。

安装时,会报解析包时出现问题
陈科肇

最终的build.gradle、AndroidManifest.xml文件配置

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.xuewei"
        minSdkVersion 17
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }


    /**
    * 多渠道配置:动态设定App名称,应用图标,背景图片,状态栏颜色。
     * 1.applicationId不一致,避免了覆盖安装;
     * 2.针对不同的商家 App名称,图标得使用manifestPlaceholders,manifestPlaceholders是一个类似HashMap的容器;
     * 3.defaultConfig{}    默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用;
     *
     *
     */
    productFlavors{
        /**
         * QQ应用宝
         * http://open.qq.com/
         */
        QQ{
            applicationId "com.xuewei.qq"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_qq",youmi_channel:"youmi_channel_qq",authorities:"com.xuewei.qq.fileProvider"]
        }
        /**
         * 360手机助手
         * http://dev.360.cn/
         */
        S360{
            applicationId "com.xuewei.s360"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_360",youmi_channel:"youmi_channel_360",authorities:"com.xuewei.360.fileProvider"]
        }
        /**
         * 小米应用商店开发者平台
         * http://dev.xiaomi.com/console/
         */
        XIAOMI{
            applicationId "com.xuewei.xiaomi"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_xiaomi",youmi_channel:"youmi_channel_xiaomi",authorities:"com.xuewei.xiaomi.fileProvider"]
        }
        /**
         * 百度-百度手机助手
         * http://app.baidu.com/serve/
         */
        BAIDU_ZHUSHO{
            applicationId "com.xuewei.baiduzs"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_baiduzs",youmi_channel:"youmi_channel_baiduzs",authorities:"com.xuewei.baiduzs.fileProvider"]
        }
        /**
         * 百度-91市场
         * http://app.baidu.com/serve/
         */
        BAIDU_91{
            applicationId "com.xuewei.baidu91"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_baidu91",youmi_channel:"youmi_channel_baidu91",authorities:"com.xuewei.baidu91.fileProvider"]
        }
        /**
         * 百度-android市场
         * http://app.baidu.com/serve/
         */
        BAIDU_ANDROID{
            applicationId "com.xuewei.baiduandroid"
            manifestPlaceholders=[app_name:"高清图解.穴位",icon:"@mipmap/logo",umeng_channel:"umeng_channel_baiduandroid",youmi_channel:"youmi_channel_baiduandroid",authorities:"com.xuewei.baiduandroid.fileProvider"]
        }
   }

    signingConfigs {
        release {
            storeFile file("G:\\android\\signed\\xuewei\\xw.jks")
            storePassword "......"
            keyAlias "陈科肇"
            keyPassword "......"
            v2SigningEnabled true
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
    compile 'com.android.support:support-v4:25.2.0'
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xuewei">
    <!-- 友盟实时统计权限
    <uses-sdk android:minSdkVersion="4" />
 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <application
        android:name=".XWApplication"
        android:allowBackup="true"
        android:icon="${icon}"
        android:label="${app_name}"
        android:roundIcon="${icon}"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--${icon},${app_name} 引用 manifestPlaceholders 容器中 icon , app_name 的值。-->
        <meta-data
            android:name="app_name"
            android:value="${app_name}"/>
        <meta-data
            android:name="icon"
            android:value="${icon}"/>
        <meta-data
            android:name="youmi_channel"
            android:value="${youmi_channel}"/>
        <meta-data
            android:name="authorities"
            android:value="${authorities}"/>

        <meta-data
            android:name="design_width"
            android:value="1080" />
        <meta-data
            android:name="design_height"
            android:value="1920" />
        <meta-data
            android:name="UMENG_APPKEY"
            android:value="......" />
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${umeng_channel}" />

        <activity android:name=".activity.MainActivity"/>
        <activity android:name=".activity.XWEffectActivity" />
        <activity android:name=".activity.HDMapActivity" />

        <!-- 有米广告   开始 -->
        <activity
            android:name=".activity.SplashActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="net.youmi.android.AdBrowser"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
            android:theme="@android:style/Theme.Light.NoTitleBar"/>

        <service
            android:name="net.youmi.android.AdService"
            android:exported="false"/>

        <receiver android:name="net.youmi.android.AdReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />

                <data android:scheme="package" />
            </intent-filter>
        </receiver>

        <!-- 有米SDK为了兼容Android N应用间共享文件行为变更而需要配置的FileProvider -->
        <!-- 这里主要为授予有米SDK拥有打开apk安装界面的功能 -->
        <!-- 请务必修改 android:authorities 为贵应用的标识,一般为 包名.fileProvider -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${authorities}"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider" />
        </provider>

        <!-- 有米渠道号(可选配置) 渠道号不能带空格,类型为整数 -->
        <meta-data
            android:name="YOUMI_CHANNEL"
            android:value="${youmi_channel}" >
        </meta-data >
        <!-- 有米视频播放Activity暂时不支持Android N的分屏模式,需要显示声明不支持(android:resizeableActivity="false")-->
        <activity
            android:name="net.youmi.android.normal.video.VideoActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
            android:resizeableActivity="false"
            android:screenOrientation="landscape"
            android:taskAffinity=""
            android:theme="@android:style/Theme.NoTitleBar" >
        </activity >
        <!-- 有米广告   结束 -->
    </application>

</manifest>

参考:http://blog.csdn.net/u012551350/article/details/62041833

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值