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{
...
}
在清单文件里,通过 ${icon},${app_name} 引用module中build.gradle文件的manifestPlaceholders 容器中设置 icon , app_name等值。
<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">
<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>
关键代码:
"${icon}"
android:label="${app_name}"
android:roundIcon="${icon}">
"app_name"
android:value="${app_name}"/>
"icon"
android:value="${icon}"/>
和动态设定App名称、应用图标,基本一样,这里唯一不同的就是,需要在代码里获取manifestPlaceholders设置的值,进行动态改变。
注意:新增的配置同样需要在清单文件中添加 meta-data节点。
data
android:name="welcome_bg"
android:value="${welcome_bg}"/>
data
android:name="tint_color"
android:value="${tint_color}"/>
data
android:name="load_url"
android:value="${load_url}"/>
一般在 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;
}
}
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 属性。不然会报相同资源引用错误。
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一致吧。同环境不能安装两个或以上。
这是我用他们的demo做的测试。
有米广告的sdk是没有问题的,问题是我没注意人家有的文档说明
对了,就是android:authorities这个属性,包名.fileProvider。
所以每个渠道包,也需要不同的android:authorities
然后,就可以愉快地玩耍了。
applicationId 每段的命名不要以全是数字方式命名,否则会有问题的。
比如:applicationId=“com.xuewei.360”这个。
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'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xuewei">
<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">
<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>
<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: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