
Android配置应用主题皮肤
5+ API中提供plus.nativeUI.*提供系统原生类控件的调用,其样式由Android平台提供界面主题决定,新版本(5.9.0)App云端打包默认为“@android:style/Theme.DeviceDefault.Light”(以前版本默认为“@android:style/Theme.DeviceDefault”)。
从5.9.0版本后HBuilder可支持自定义程序主题,打开应用的manifest.json文件,切换到“代码视图”
- 5+ APP
在 "plus" -> "distribute" -> "google" 节点下添加“theme”字段 - uni-app
在 "app-plus" -> "distribute" -> "android" 节点下添加“theme”字段
并配置要使用的应用主题:
值为字符串类型,必须是Android系统支持的类型,注意云端打包编译环境。
- HBuilder
Android4.4(API Level19)SDK - HBuilderX
Android Q (API Level29)SDK
如果输入的类型无效则会提示以下错误:
res/values/dcloud_activity_styles.xml:2: error: Error retrieving parent for item: No resource found that matches the given name 'XXXXXXXXXXXXXXXX'.
推荐使用以下主题样式
- @android:style/Theme.DeviceDefault
系统默认样式(暗色系),通常是黑底白字 - @android:style/Theme.DeviceDefault.Light
系统默认明亮样式(亮色系),通常是白底黑字
Android API19支持的样式列表如下:
配置完成保存提交App云端打包后才能生效
注意!!!更改主题时建议使用NoActionBar系列主题。如果配置其他样式主题可能会导致页面顶部多出一个ActionBar UI(actionBar)
5+ API中提供plus.nativeUI.*提供系统原生类控件的调用,其样式由Android平台提供界面主题决定,新版本(5.9.0)App云端打包默认为“@android:style/Theme.DeviceDefault.Light”(以前版本默认为“@android:style/Theme.DeviceDefault”)。
从5.9.0版本后HBuilder可支持自定义程序主题,打开应用的manifest.json文件,切换到“代码视图”
- 5+ APP
在 "plus" -> "distribute" -> "google" 节点下添加“theme”字段 - uni-app
在 "app-plus" -> "distribute" -> "android" 节点下添加“theme”字段
并配置要使用的应用主题:
值为字符串类型,必须是Android系统支持的类型,注意云端打包编译环境。
- HBuilder
Android4.4(API Level19)SDK - HBuilderX
Android Q (API Level29)SDK
如果输入的类型无效则会提示以下错误:
res/values/dcloud_activity_styles.xml:2: error: Error retrieving parent for item: No resource found that matches the given name 'XXXXXXXXXXXXXXXX'.
推荐使用以下主题样式
- @android:style/Theme.DeviceDefault
系统默认样式(暗色系),通常是黑底白字 - @android:style/Theme.DeviceDefault.Light
系统默认明亮样式(亮色系),通常是白底黑字
Android API19支持的样式列表如下:
配置完成保存提交App云端打包后才能生效
注意!!!更改主题时建议使用NoActionBar系列主题。如果配置其他样式主题可能会导致页面顶部多出一个ActionBar UI(actionBar)

APICloud产品与DCloud深度对比分析
> 更新:最新版比较详见:https://ask.dcloud.net.cn/article/36732
========以下为历史内容=========
其实就选型对比而言,不深入看产品,有4点就足矣。
- APICloud反编译和抄袭DCloud代码,已经被北京知识产权法院判决,赔偿DCloud损失并向DCloud道歉。详见。
如此不道德的公司存在是给中国的程序员界丢脸。
而支持、纵容侵权产品,让侵权公司得不到应有惩罚,侵权行为屡禁不止,最终劣币驱逐良币,中国无人创新,最终我们用的软件都是外国写的。
这样的环境,是谁营造的?
其实人人有责。
抵制破解、抄袭、侵权,维护正义、维护中国的软件创新环境,人人有责。
2. DCloud的产品有众多一线互联网公司案例
除了众多创业公司,一线互联网公司如360、大众点评、京东、网易、唯品会、新浪、阿里巴巴也纷纷选择DCloud的工具开发app。
以唯品会、有道词典、大众点评为例,体验完全达到一线互联网公司的苛刻要求。(具体看DCloud官网案例)
这是其他跨平台开发工具所没有取得的成绩,在这些案例的过程中大公司们对DCloud的产品反复提要求,最终打磨出别的产品所不具备的功能和性能。
用DCloud的产品肯定可以达到这种效果,不用DCloud,万一没达到效果,客户和老板问起来:明明你知道DCloud可以,为何冒险用别的?好像很难解释。。。
3. 自卖自夸没用,要看三方有公信力的数据
DCloud的mui和facebook的react native,是当前最主流的跨平台开发工具。
下图是常见跨平台开发工具的百度指数对比。
访问index.baidu.com可以自己看。
蓝色是HBuilder,绿色是mui,紫色是apicloud,非常明显的可以看出DCloud的产品体量远超过apicloud,而且一直在良性增长,而apicloud已经做不起来了。
再补充一个数据,HBuilder已经有200万开发者了,和国外主流的开发ide也达到并驾齐驱的体量。可以自行查HBuilder和sublime、vscode的百度指数对比。
4. 免费免费免费
apicloud等其他国内跨平台工具都是收费的,虽然有免费版本,但是他们的目标还是要把开发者引导成他们的收费客户。
但DCloud是纯免费的,自由的技术产品。没有vip付费用户跟你抢资源,没有用到一定深度就让你付费。
DCloud的唯一的商业变现是你做好app后,如果想推广,可以找DCloud帮你发展用户,如果想广告变现,DCloud有广告平台帮你变现。
我们对自己的定位是,帮助开发者成功,成功做出app,成功运营好app。
5. 扩展性、灵活性、开放性
DCloud的5+SDK、开源mui,都使得任何开发者不会被我们的产品功能约束,都可以自己扩展原生能力,自己修改框架源码。
最后,即使你觉得DCloud的产品仍然不顺手,你也应该去使用react native、weex等干净的产品,而不是支持侵权的apicloud。
作恶的公司得不到抵制,反而被纵容,根本就不会反思,也给产业树立了极坏的样板。
维护产业健康、伸张正义,人人有责!
更新:DCloud新出了终极跨平台框架uni-app,无论功能、性能,apicloud相比毫无优势。
不止是产品,uni-app在文档、技术服务、视频、插件生态上也都秒杀对手。
不要再谈论DCloud的社区不活跃、文档不友好、没有视频培训教程、插件不够多了,这些观点都过时了,都反超apicloud的了
> 更新:最新版比较详见:https://ask.dcloud.net.cn/article/36732
========以下为历史内容=========
其实就选型对比而言,不深入看产品,有4点就足矣。
- APICloud反编译和抄袭DCloud代码,已经被北京知识产权法院判决,赔偿DCloud损失并向DCloud道歉。详见。
如此不道德的公司存在是给中国的程序员界丢脸。
而支持、纵容侵权产品,让侵权公司得不到应有惩罚,侵权行为屡禁不止,最终劣币驱逐良币,中国无人创新,最终我们用的软件都是外国写的。
这样的环境,是谁营造的?
其实人人有责。
抵制破解、抄袭、侵权,维护正义、维护中国的软件创新环境,人人有责。
2. DCloud的产品有众多一线互联网公司案例
除了众多创业公司,一线互联网公司如360、大众点评、京东、网易、唯品会、新浪、阿里巴巴也纷纷选择DCloud的工具开发app。
以唯品会、有道词典、大众点评为例,体验完全达到一线互联网公司的苛刻要求。(具体看DCloud官网案例)
这是其他跨平台开发工具所没有取得的成绩,在这些案例的过程中大公司们对DCloud的产品反复提要求,最终打磨出别的产品所不具备的功能和性能。
用DCloud的产品肯定可以达到这种效果,不用DCloud,万一没达到效果,客户和老板问起来:明明你知道DCloud可以,为何冒险用别的?好像很难解释。。。
3. 自卖自夸没用,要看三方有公信力的数据
DCloud的mui和facebook的react native,是当前最主流的跨平台开发工具。
下图是常见跨平台开发工具的百度指数对比。
访问index.baidu.com可以自己看。
蓝色是HBuilder,绿色是mui,紫色是apicloud,非常明显的可以看出DCloud的产品体量远超过apicloud,而且一直在良性增长,而apicloud已经做不起来了。
再补充一个数据,HBuilder已经有200万开发者了,和国外主流的开发ide也达到并驾齐驱的体量。可以自行查HBuilder和sublime、vscode的百度指数对比。
4. 免费免费免费
apicloud等其他国内跨平台工具都是收费的,虽然有免费版本,但是他们的目标还是要把开发者引导成他们的收费客户。
但DCloud是纯免费的,自由的技术产品。没有vip付费用户跟你抢资源,没有用到一定深度就让你付费。
DCloud的唯一的商业变现是你做好app后,如果想推广,可以找DCloud帮你发展用户,如果想广告变现,DCloud有广告平台帮你变现。
我们对自己的定位是,帮助开发者成功,成功做出app,成功运营好app。
5. 扩展性、灵活性、开放性
DCloud的5+SDK、开源mui,都使得任何开发者不会被我们的产品功能约束,都可以自己扩展原生能力,自己修改框架源码。
最后,即使你觉得DCloud的产品仍然不顺手,你也应该去使用react native、weex等干净的产品,而不是支持侵权的apicloud。
作恶的公司得不到抵制,反而被纵容,根本就不会反思,也给产业树立了极坏的样板。
维护产业健康、伸张正义,人人有责!
更新:DCloud新出了终极跨平台框架uni-app,无论功能、性能,apicloud相比毫无优势。
不止是产品,uni-app在文档、技术服务、视频、插件生态上也都秒杀对手。
不要再谈论DCloud的社区不活跃、文档不友好、没有视频培训教程、插件不够多了,这些观点都过时了,都反超apicloud的了

【分享】淘宝商品评分示例
无图无真相,先看效果图:
接下来是代码实现部分,比较简单,自己看:
HTML 部分
<div class="icons" >
<i data-index="1" class="mui-icon mui-icon-star"></i>
<i data-index="2" class="mui-icon mui-icon-star"></i>
<i data-index="3" class="mui-icon mui-icon-star"></i>
<i data-index="4" class="mui-icon mui-icon-star"></i>
<i data-index="5" class="mui-icon mui-icon-star"></i>
</div>
为每个星星节点添加index索引,方便获取当前所点击元素
JavaScript 部分
mui.init();
mui('.icons').on('click','i',function(){
var index = parseInt(this.getAttribute("data-index"));//获取当前元素的索引值
var parent = this.parentNode;//获取当前元素的父节点
var children = parent.children;//获取父节点下所有子元素
if(this.classList.contains("mui-icon-star")){//判断当前节点列表中是否含有.mui-icon-star元素
for(var i=0;i<index;i ){//亮星
children[i].classList.remove('mui-icon-star');
children[i].classList.add('mui-icon-star-filled');
}
}else{//重置已经亮星的元素
for (var i = index; i < 5; i++ ) {
children[i].classList.add('mui-icon-star')
children[i].classList.remove('mui-icon-star-filled')
}
}
document.getElementById("info").innerHTML = parent.previousElementSibling.innerText ":" index "星好评";
})
已开源,提交至Github,地址: https://github.com/qhhsy/pingfen
无图无真相,先看效果图:
接下来是代码实现部分,比较简单,自己看:
HTML 部分
<div class="icons" >
<i data-index="1" class="mui-icon mui-icon-star"></i>
<i data-index="2" class="mui-icon mui-icon-star"></i>
<i data-index="3" class="mui-icon mui-icon-star"></i>
<i data-index="4" class="mui-icon mui-icon-star"></i>
<i data-index="5" class="mui-icon mui-icon-star"></i>
</div>
为每个星星节点添加index索引,方便获取当前所点击元素
JavaScript 部分
mui.init();
mui('.icons').on('click','i',function(){
var index = parseInt(this.getAttribute("data-index"));//获取当前元素的索引值
var parent = this.parentNode;//获取当前元素的父节点
var children = parent.children;//获取父节点下所有子元素
if(this.classList.contains("mui-icon-star")){//判断当前节点列表中是否含有.mui-icon-star元素
for(var i=0;i<index;i ){//亮星
children[i].classList.remove('mui-icon-star');
children[i].classList.add('mui-icon-star-filled');
}
}else{//重置已经亮星的元素
for (var i = index; i < 5; i++ ) {
children[i].classList.add('mui-icon-star')
children[i].classList.remove('mui-icon-star-filled')
}
}
document.getElementById("info").innerHTML = parent.previousElementSibling.innerText ":" index "星好评";
})
已开源,提交至Github,地址: https://github.com/qhhsy/pingfen
收起阅读 »
有关苹果无法导出p12证书的问题解决办法。
有关苹果无法导出p12 证书的问题解决办法:
很多人刚接触苹果证书的时候感觉很复杂,大部分原因是因为都纯英文,然后再个加上步骤繁琐导致很多同学都不知所措,
就算是出了问题也不知道从何查起。这篇文章不是申请证书的教程,如果找教程请移步 iOS证书(.p12)和描述文件(.mobileprovision)申请或者Google之。
出现问题的截图:
今天就有关无法导出p12证书可能出现的原因做个解释以及解决办法。
原因一
所选类型选择错误。
解决办法:
左侧有两个分类,一个是钥匙串,一个是种类,要选择种类中的我的证书或者证书。然后在右侧证书列表中,右键导出即可。
原因二
使用钥匙串生成的证书有问题,格式为(certSigningRequest)
解决办法:
钥匙串访问--> 证书助理 --> 从证书颁发机构请求证书...
原因三
前两个原因确保没有问题,那么就有可能是Mac系统缺少AppleWWDRCA.cer证书。
解决办法:
这个证书是苹果官方的证书,Apple World Wide Developer Relations Certification Authority
下载地址: Apple PKI
有关苹果无法导出p12 证书的问题解决办法:
很多人刚接触苹果证书的时候感觉很复杂,大部分原因是因为都纯英文,然后再个加上步骤繁琐导致很多同学都不知所措,
就算是出了问题也不知道从何查起。这篇文章不是申请证书的教程,如果找教程请移步 iOS证书(.p12)和描述文件(.mobileprovision)申请或者Google之。
出现问题的截图:
今天就有关无法导出p12证书可能出现的原因做个解释以及解决办法。
原因一
所选类型选择错误。
解决办法:
左侧有两个分类,一个是钥匙串,一个是种类,要选择种类中的我的证书或者证书。然后在右侧证书列表中,右键导出即可。
原因二
使用钥匙串生成的证书有问题,格式为(certSigningRequest)
解决办法:
钥匙串访问--> 证书助理 --> 从证书颁发机构请求证书...
原因三
前两个原因确保没有问题,那么就有可能是Mac系统缺少AppleWWDRCA.cer证书。
解决办法:
这个证书是苹果官方的证书,Apple World Wide Developer Relations Certification Authority
下载地址: Apple PKI

MUI实现actionsheet的自定义样式
大家对于类似于这种效果的社交分享都不陌生,但MUI里没有实现这种效果,官方提供的只能是按钮,样式不能自定义,可能以后会实现样式自定义,但对于目前来说,这种效果还是很急需的。于是自己就想着用5 的窗口遮罩来实现,中间也遇到了好多问题,调试了很长时间,始终效果不理想,虽然用5 的floatWebview实现了遮罩效果,但是点击遮罩部分,并不会使这个分享页面消失。最终在“Dcloud-MUI-CHB”君的指点下用mask:窗口的遮罩实现了。还有一点需要注意的是,分享的时候我们用的logo图标大小不能超过3kb,不然分享直接失败,返回-3.在此分享一下:
<script type="text/javascript">
function openShare() {
shareWebview();
}
mui.plusReady(function() {
ws = plus.webview.currentWebview();
//关闭splash页面;
plus.navigator.closeSplashscreen();
})
var sharew;
var ws = null;
/**
*分享窗口
*/
function shareWebview() {
ws = plus.webview.currentWebview();
if (sharew) { // 避免快速多次点击创建多个窗口
return;
}
var top = plus.display.resolutionHeight - 134;
var href = "share.html";
sharew = plus.webview.create(href, "share.html", {
width: '100%',
height: '134',
top: top,
scrollIndicator: 'none',
scalable: false,
popGesture: 'none'
}, {
shareInfo: {
"url": "test",
"title": "测试",
"content": "测试",
"pageSourceId": ws.id
}
});
sharew.addEventListener("loaded", function() {
sharew.show('slide-in-bottom', 300);
}, false);
// 显示遮罩层
ws.setStyle({
mask: "rgba(0,0,0,0.5)"
});
// 点击关闭遮罩层
ws.addEventListener("maskClick", closeMask, false);
}
function closeMask() {
ws.setStyle({
mask: "none"
});
//避免出现特殊情况,确保分享页面在初始化时关闭
if (!sharew) {
sharew = plus.webview.getWebviewById("share.html");
}
if (sharew) {
sharew.close();
sharew = null;
}
}
</script>
share.html 核心代码
mui.back = function() {
var sourcePage = plus.webview.getWebviewById(pageSourceId);
if (sourcePage) {
sourcePage.evalJS("closeMask()");
}
}
效果图:
源代码在附件share.zip中,可直接在HB中运行。
大家对于类似于这种效果的社交分享都不陌生,但MUI里没有实现这种效果,官方提供的只能是按钮,样式不能自定义,可能以后会实现样式自定义,但对于目前来说,这种效果还是很急需的。于是自己就想着用5 的窗口遮罩来实现,中间也遇到了好多问题,调试了很长时间,始终效果不理想,虽然用5 的floatWebview实现了遮罩效果,但是点击遮罩部分,并不会使这个分享页面消失。最终在“Dcloud-MUI-CHB”君的指点下用mask:窗口的遮罩实现了。还有一点需要注意的是,分享的时候我们用的logo图标大小不能超过3kb,不然分享直接失败,返回-3.在此分享一下:
<script type="text/javascript">
function openShare() {
shareWebview();
}
mui.plusReady(function() {
ws = plus.webview.currentWebview();
//关闭splash页面;
plus.navigator.closeSplashscreen();
})
var sharew;
var ws = null;
/**
*分享窗口
*/
function shareWebview() {
ws = plus.webview.currentWebview();
if (sharew) { // 避免快速多次点击创建多个窗口
return;
}
var top = plus.display.resolutionHeight - 134;
var href = "share.html";
sharew = plus.webview.create(href, "share.html", {
width: '100%',
height: '134',
top: top,
scrollIndicator: 'none',
scalable: false,
popGesture: 'none'
}, {
shareInfo: {
"url": "test",
"title": "测试",
"content": "测试",
"pageSourceId": ws.id
}
});
sharew.addEventListener("loaded", function() {
sharew.show('slide-in-bottom', 300);
}, false);
// 显示遮罩层
ws.setStyle({
mask: "rgba(0,0,0,0.5)"
});
// 点击关闭遮罩层
ws.addEventListener("maskClick", closeMask, false);
}
function closeMask() {
ws.setStyle({
mask: "none"
});
//避免出现特殊情况,确保分享页面在初始化时关闭
if (!sharew) {
sharew = plus.webview.getWebviewById("share.html");
}
if (sharew) {
sharew.close();
sharew = null;
}
}
</script>
share.html 核心代码
mui.back = function() {
var sourcePage = plus.webview.getWebviewById(pageSourceId);
if (sourcePage) {
sourcePage.evalJS("closeMask()");
}
}
效果图:
源代码在附件share.zip中,可直接在HB中运行。 收起阅读 »

关于js对sqlite的支持
看到问题咨询里有一些关于js是否支持Sqlite的问题,这里抛砖引玉。答案是可以支持。
在github上已经有关于这块的代码支持:[https://github.com/kripken/sql.js/](https://github.com/kripken/sql.js/),打开链接地址我们可以看到各种连接办法。例如:node.js,浏览器支持等。
如果我们手上已经有了sqlite的数据库,可以直接添加到我们的app项目中来,通过如下代码方式直接访问:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/test.db', true);//在App中的相对路径
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
var db = new SQL.Database(uInt8Array);
var contents = db.exec("SELECT * FROM my_table");//执行查询语句
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
//查询结果获取办法contents [i].values
};
xhr.send();
看到问题咨询里有一些关于js是否支持Sqlite的问题,这里抛砖引玉。答案是可以支持。
在github上已经有关于这块的代码支持:[https://github.com/kripken/sql.js/](https://github.com/kripken/sql.js/),打开链接地址我们可以看到各种连接办法。例如:node.js,浏览器支持等。
如果我们手上已经有了sqlite的数据库,可以直接添加到我们的app项目中来,通过如下代码方式直接访问:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/test.db', true);//在App中的相对路径
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
var db = new SQL.Database(uInt8Array);
var contents = db.exec("SELECT * FROM my_table");//执行查询语句
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
//查询结果获取办法contents [i].values
};
xhr.send();
收起阅读 »

HTML5+ API文档 CHM精编版
在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~
不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~
另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~
【update】
5.30 修正部分文档链接错误
在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~
不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~
另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~
【update】
5.30 修正部分文档链接错误

[分享]简单使用模板,代替字符串拼接。
1.移动互联网应用非常重要的是网络数据的交互,而获取的数据如何转化为我们希望的页面效果,使我们这节课讨论的重点。我们使用固定的数据源做演示。
2.经常会将数据在前台展示,一般情况下,我们会拼接字符串,或者使用第三方提供的模板引擎,这里我们推荐一种简单粗暴的方式(不建议使用到大项目中),但是对于中小型项目可以考虑使用。
其思想和模板引擎的思想类似,没有那么复杂。
直接说如何使用:
①引入JS
②定义模板
③加载数据
④对特殊数据处理(回调函数)
代码中有注释,很容易理解。
html文件
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="../static/styles/mui.min.css" />
<link rel="stylesheet" href="../static/styles/ui-box.css">
<link rel="stylesheet" href="../static/styles/ui-base.css">
<link rel="stylesheet" href="../static/styles/ui-input.css">
<link rel="stylesheet" href="../static/styles/style.css">
<link rel="stylesheet" href="../static/styles/infor.css">
<link rel="stylesheet" type="text/css" href="../static/styles/animate.min.css" />
</head>
<body class="um-vp c-gra1">
<div class="mui-content">
<div class="ub-f1">
<table class='listTable' border='0' cellpadding='0' cellspacing='0' id="cminfo">
</table>
</div>
</div>
</body>
<script src="../static/scripts/mui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../static/scripts/zy_tmpl.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
(function($, doc) {
$.init();
//$.plusReady(function() {
//数据加载(这里演示就不从后台获取了,直接将获取的数据拿过来)
var data = '[{"id":"43743","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001.003","cm_name":"毕祖辉","cm_tel":"","cm_work_tel":"8570269","cm_color":"10","fphoto":"","cm_sex":"男"},{"id":"43762","cm_id":"0011504030002","cm_areaname":"0.001.001.001.002","cm_name":"严丽华","cm_tel":"","cm_work_tel":"6110357","cm_color":"11","fphoto":"","cm_sex":"女"},{"id":"43709","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001","cm_name":"马强","cm_tel":"","cm_work_tel":"5946083","cm_color":"12","fphoto":"","cm_sex":"男"},{"dataCount":"4731"}]';
//转化为JSON对象
var dataObj = JSON.parse(data);
var dataCount = dataObj.pop();//数据总数量,不是本数据数量(直接忽略)
//定义模板
var t = _t.toString();
var tmp = t.substr(17,t.length-21);
//加载数据 参数解释(模板,数据数量,回调函数[可以不传]);
var res = tmpl(tmp,dataObj,tmpl_count(dataObj),tmpCallBack);
doc.querySelector('#cminfo').innerHTML = res;
//})
function _t(){/*
<tr id='${id}' cm_id='${cm_id}' cm_areaname='${cm_areaname}' style="color:${cb:cm_color}">
<td class="preTd">
<img src='${cb:fphoto}' class='preIcon uc-a2'></td>
<td class="td_name_style">
<div class="td_div">${cm_name}</div>
<p class="ulim">${cb:cm_tel}</p></td>
<td onclick="dialPhone('${cb:cm_tel}')" class='more' width='10%'><img src='../static/imgs/call.png' class='lastIcon'></td>
</tr>
*/}
function tmpCallBack(a,b)
{
switch (b[1]){
case 'cm_tel':
return !isNull(a.cm_tel)?a.cm_work_tel:a.cm_tel;
break;
case "fphoto":
if(!isNull(a.fphoto))
{
var src = a.cm_sex&&~(a.cm_sex).indexOf('女')?"../static/imgs/head-picn.png":"../static/imgs/head-pic.png";
return src;
}else{
return a.fphoto;//如果有则先加载到本地
}
break;
case "cm_color":
return !isNull(a.cm_color)?'':HTMLColor(a.cm_color);
break;
default:
break;
}
return '';
}
//下面的方法可以写为公共的方法
function isNull(value)
{
if(value == null || value == "" || value == "undefined" || value == undefined || value == "null" || value == "(null)" || value == 'NULL' || typeof(value) == 'undefined'){
return false;
}
else{
value = value+"";
value = value.replace(/\s/g,"");
if(value == ""){
return false;
}
return true;
}
}
function HTMLColor(num)
{
var htmlColor = ",Aqua,Black,Blue,Fuchsia,Gray,Green,Lime,Maroon,Navy,Olive,Purple,Red,Silver,Teal,White,Yellow";
var hcs = htmlColor.split(",");
return num > 0 && num < hcs.length ? hcs[num] : '' ;
}
}(mui, document))
</script>
</html>
tmpl.js文件
var tmpl_count=function(dd)
{
if(Object.prototype.toString.apply(dd)==="[object Array]")
{
return dd.length;
}
else
{
var c=0;
for(var i in dd)
c++;
return c;
}
}
var _f = function(d,c,k1,k2,l){
var q = c.match(/(first:|last:)(\"|\'*)([^\"\']*)(\"|\'*)/);
if(!q) return;
if(q[1]==k1){
if(q[2]=='\"'||q[2]=='\''){
return q[3];
}
else
return d[q[3]];
}
else if(q[1]==k2 && l>1)
return "";
}
var t_f = function(t,d,i,l,cb){
return t.replace( /\$\{([^\}]*)\}/g,function(m,c){
if(c.match(/index:/)){
return i;
}
if(c.match(/cb:/) && cb){
return cb(d,c.match(/cb:(.*)/));
}
if(i==0){
var s=_f(d,c,"first:","last:",l);
if(s) return s;
}
if(i==(l-1)){
var s= _f(d,c,"last:","first:",l);
if(s) return s;
}
var ar=c.split('.');
var res=d;
for(var key in ar)
res=res[ar[key]];
return res||"";
});
}
var tmpl = function(t,dd,l,cb,scb){
var r = "";
{
var index=0;
for(var i in dd)
{
if(scb)
scb(0,i,dd[i]);
var rr=t_f(t,dd[i],index,l,cb);
if(scb)
scb(1,rr,dd[i]);
r+=rr;
index++;
}
}
return r;
}
var tmpl_s = function(t,dd,cb)
{
return t_f(t,dd,-1,-1,cb);
}
1.移动互联网应用非常重要的是网络数据的交互,而获取的数据如何转化为我们希望的页面效果,使我们这节课讨论的重点。我们使用固定的数据源做演示。
2.经常会将数据在前台展示,一般情况下,我们会拼接字符串,或者使用第三方提供的模板引擎,这里我们推荐一种简单粗暴的方式(不建议使用到大项目中),但是对于中小型项目可以考虑使用。
其思想和模板引擎的思想类似,没有那么复杂。
直接说如何使用:
①引入JS
②定义模板
③加载数据
④对特殊数据处理(回调函数)
代码中有注释,很容易理解。
html文件
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="../static/styles/mui.min.css" />
<link rel="stylesheet" href="../static/styles/ui-box.css">
<link rel="stylesheet" href="../static/styles/ui-base.css">
<link rel="stylesheet" href="../static/styles/ui-input.css">
<link rel="stylesheet" href="../static/styles/style.css">
<link rel="stylesheet" href="../static/styles/infor.css">
<link rel="stylesheet" type="text/css" href="../static/styles/animate.min.css" />
</head>
<body class="um-vp c-gra1">
<div class="mui-content">
<div class="ub-f1">
<table class='listTable' border='0' cellpadding='0' cellspacing='0' id="cminfo">
</table>
</div>
</div>
</body>
<script src="../static/scripts/mui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../static/scripts/zy_tmpl.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
(function($, doc) {
$.init();
//$.plusReady(function() {
//数据加载(这里演示就不从后台获取了,直接将获取的数据拿过来)
var data = '[{"id":"43743","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001.003","cm_name":"毕祖辉","cm_tel":"","cm_work_tel":"8570269","cm_color":"10","fphoto":"","cm_sex":"男"},{"id":"43762","cm_id":"0011504030002","cm_areaname":"0.001.001.001.002","cm_name":"严丽华","cm_tel":"","cm_work_tel":"6110357","cm_color":"11","fphoto":"","cm_sex":"女"},{"id":"43709","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001","cm_name":"马强","cm_tel":"","cm_work_tel":"5946083","cm_color":"12","fphoto":"","cm_sex":"男"},{"dataCount":"4731"}]';
//转化为JSON对象
var dataObj = JSON.parse(data);
var dataCount = dataObj.pop();//数据总数量,不是本数据数量(直接忽略)
//定义模板
var t = _t.toString();
var tmp = t.substr(17,t.length-21);
//加载数据 参数解释(模板,数据数量,回调函数[可以不传]);
var res = tmpl(tmp,dataObj,tmpl_count(dataObj),tmpCallBack);
doc.querySelector('#cminfo').innerHTML = res;
//})
function _t(){/*
<tr id='${id}' cm_id='${cm_id}' cm_areaname='${cm_areaname}' style="color:${cb:cm_color}">
<td class="preTd">
<img src='${cb:fphoto}' class='preIcon uc-a2'></td>
<td class="td_name_style">
<div class="td_div">${cm_name}</div>
<p class="ulim">${cb:cm_tel}</p></td>
<td onclick="dialPhone('${cb:cm_tel}')" class='more' width='10%'><img src='../static/imgs/call.png' class='lastIcon'></td>
</tr>
*/}
function tmpCallBack(a,b)
{
switch (b[1]){
case 'cm_tel':
return !isNull(a.cm_tel)?a.cm_work_tel:a.cm_tel;
break;
case "fphoto":
if(!isNull(a.fphoto))
{
var src = a.cm_sex&&~(a.cm_sex).indexOf('女')?"../static/imgs/head-picn.png":"../static/imgs/head-pic.png";
return src;
}else{
return a.fphoto;//如果有则先加载到本地
}
break;
case "cm_color":
return !isNull(a.cm_color)?'':HTMLColor(a.cm_color);
break;
default:
break;
}
return '';
}
//下面的方法可以写为公共的方法
function isNull(value)
{
if(value == null || value == "" || value == "undefined" || value == undefined || value == "null" || value == "(null)" || value == 'NULL' || typeof(value) == 'undefined'){
return false;
}
else{
value = value+"";
value = value.replace(/\s/g,"");
if(value == ""){
return false;
}
return true;
}
}
function HTMLColor(num)
{
var htmlColor = ",Aqua,Black,Blue,Fuchsia,Gray,Green,Lime,Maroon,Navy,Olive,Purple,Red,Silver,Teal,White,Yellow";
var hcs = htmlColor.split(",");
return num > 0 && num < hcs.length ? hcs[num] : '' ;
}
}(mui, document))
</script>
</html>
tmpl.js文件
var tmpl_count=function(dd)
{
if(Object.prototype.toString.apply(dd)==="[object Array]")
{
return dd.length;
}
else
{
var c=0;
for(var i in dd)
c++;
return c;
}
}
var _f = function(d,c,k1,k2,l){
var q = c.match(/(first:|last:)(\"|\'*)([^\"\']*)(\"|\'*)/);
if(!q) return;
if(q[1]==k1){
if(q[2]=='\"'||q[2]=='\''){
return q[3];
}
else
return d[q[3]];
}
else if(q[1]==k2 && l>1)
return "";
}
var t_f = function(t,d,i,l,cb){
return t.replace( /\$\{([^\}]*)\}/g,function(m,c){
if(c.match(/index:/)){
return i;
}
if(c.match(/cb:/) && cb){
return cb(d,c.match(/cb:(.*)/));
}
if(i==0){
var s=_f(d,c,"first:","last:",l);
if(s) return s;
}
if(i==(l-1)){
var s= _f(d,c,"last:","first:",l);
if(s) return s;
}
var ar=c.split('.');
var res=d;
for(var key in ar)
res=res[ar[key]];
return res||"";
});
}
var tmpl = function(t,dd,l,cb,scb){
var r = "";
{
var index=0;
for(var i in dd)
{
if(scb)
scb(0,i,dd[i]);
var rr=t_f(t,dd[i],index,l,cb);
if(scb)
scb(1,rr,dd[i]);
r+=rr;
index++;
}
}
return r;
}
var tmpl_s = function(t,dd,cb)
{
return t_f(t,dd,-1,-1,cb);
}
收起阅读 »

如何安装node.js支持插件
在eclipse插件中,node.js插件中比较知名的是nodeclipse。
从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可
- 在js文件里提示node.js
注意:nodeclipse的编辑器和HBuilder的编辑器不同。但node.js和web的js均以.js为扩展名,打开js文件时需分清使用哪个js编辑器打开。
一般而言,由于nodeclipse是后安装的,所以.js文件默认以node的编辑器打开,在此编辑器中是不提示HBuilder的语法助手的。
要更换打开方式,在项目管理器里对js文件点右键-打开方式,选择自己想要的编辑器打开。
还可以在菜单里设置永久文件关联,你可以设置你最常使用的方式打开。推荐设置.js文件默认使用HBuilder的js编辑器打开后,然后在打开node.js的js文件时点右键选择nodeclipse编辑器打开。
历史材料归档:
HBuilder6.3以下的版本安装nodeclipse插件的方法如下:
前言,nodeclipse是基于jsdt的,HBuilder没有内置jsdt,如果要安装nodeclipse,则先要安装jsdt插件。
安装JSDT
- 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
- 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
- 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
- 加载完毕后,找到programming languages如下图
- 勾选programming languages下的JavaScript Development Tools如下图
6.点击下一步,接受许可协议并安装,安装完毕后重启即可
安装nodeclipse - 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可 - 安装完毕后重启HBuilder
- 新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可 - 在js文件里提示node.js
在eclipse插件中,node.js插件中比较知名的是nodeclipse。
从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可
- 在js文件里提示node.js
注意:nodeclipse的编辑器和HBuilder的编辑器不同。但node.js和web的js均以.js为扩展名,打开js文件时需分清使用哪个js编辑器打开。
一般而言,由于nodeclipse是后安装的,所以.js文件默认以node的编辑器打开,在此编辑器中是不提示HBuilder的语法助手的。
要更换打开方式,在项目管理器里对js文件点右键-打开方式,选择自己想要的编辑器打开。
还可以在菜单里设置永久文件关联,你可以设置你最常使用的方式打开。推荐设置.js文件默认使用HBuilder的js编辑器打开后,然后在打开node.js的js文件时点右键选择nodeclipse编辑器打开。
历史材料归档:
HBuilder6.3以下的版本安装nodeclipse插件的方法如下:
前言,nodeclipse是基于jsdt的,HBuilder没有内置jsdt,如果要安装nodeclipse,则先要安装jsdt插件。
安装JSDT
- 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
- 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
- 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
- 加载完毕后,找到programming languages如下图
- 勾选programming languages下的JavaScript Development Tools如下图
6.点击下一步,接受许可协议并安装,安装完毕后重启即可
安装nodeclipse - 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可 - 安装完毕后重启HBuilder
- 新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可 - 在js文件里提示node.js

iOS离线打包-友盟统计配置
添加友盟统计插件
注:Linker Flags的添加方法请参考这个文档
-
添加以下静态库:liblibStatistic.a
-
添加以下framework: "UMAnalytics.framework",
"UMCommon.framework", -
添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd
配置友盟统计插件
1.到友盟开放平台申请Appkey
2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey
注意:
IDFA说明
友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))
添加友盟统计插件
注:Linker Flags的添加方法请参考这个文档
-
添加以下静态库:liblibStatistic.a
-
添加以下framework: "UMAnalytics.framework",
"UMCommon.framework", -
添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd
配置友盟统计插件
1.到友盟开放平台申请Appkey
2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey
注意:
IDFA说明
友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))

搞一搞百度定位
如果有版式问题,移步到这phillyx
关于百度定位
- 这是官方定位的解释:geolocation
- 地图插件配置
- 我在问答里面找到了这位童鞋的百度定位,地址变更提醒
不过,童鞋倒是给具体的示例啊,木有\~\~\~\~(>_<)\~\~\~\~ 官方的插件配置也看的懵懵懂懂,一塌糊涂 ok,自己搞,搞了大半天基本上弄清楚了,下面就总结一下自己的心血历程吧!!!~~~~~
- 首先要到百度lbs开放平台注册开发者账号
- 在应用里面创建应用我的应用
- 服务器、Android、ios、浏览器逐个建立一个遍
- 安卓和ios的安全码采用dcloud官方的“BA:AD:09:3A:82:82:9F:B4:32:A7:B2:8C:B4:CC:F0:E9:F3:7D:AE:58;io.dcloud.HBuilder”
- 服务器和浏览器的Refer白名单默认“*”
- 下面就是挖坑填坑的经历了
- 刚开始的使用JavaScript API大众版, 根据demo:helloworld照葫芦画瓢,可是太尼玛慢
- 接着看到了JavaScript API极速版, ok 这次快了好多,能不能更快呢,当然可以O(∩_∩)O~
- 秘诀就是这Web服务API
使用Geocoding API
通过逆地理编码服务获取数据
我们可以将以下链接放到浏览器地址栏中试一下
http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderReverse&location=39.983424,116.322987&output=json&pois=1
到这终于可以松一口气了,差多搞定了,下面就是码转了,为了方便,直接贴代码了
<!--废弃-->
<!--<script type="text/javascript" src="http://api.map.baidu.com/api?type=quick&ak=你的key&v=1.0"></script>-->
(function($) {
/**
* @description 获取百度定位信息
* @param {Function} callback
*/
function getPosition(callback) {
try {
plus.geolocation.getCurrentPosition(function(position) {
console.log(JSON.stringify(position));
var codns = position.coords; //获取地理坐标信息;
// var geoc = new BMap.Geocoder();
// var pt = new BMap.Point(codns.longitude, codns.latitude);
// geoc.getLocation(pt, function(rs) {
// var addComp = rs.addressComponents;
// console.log(JSON.stringify(addComp));
// var lo =addComp.province+','+addComp.city;
// callback(lo);
// });
var req = 'http://api.map.baidu.com/geocoder/v2/';
var parms = {
ak: '你的key',
callback: 'renderReverse',
output: 'json',
location: codns.latitude + ',' + codns.longitude
//,pois:1(周边poi数组) //不建议要,周边数据太杂,不需要
};
mui.ajax(req, {
data: parms,
dataType: 'json', //服务器返回json格式数据
type: 'post', //HTTP请求类型
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
console.log(JSON.stringify(data));
myStorage.setItem('geolocation',data);
if (data.status == 0) {
var lo = data.result.addressComponent.province + ',' + data.result.addressComponent.city;
callback(lo);
} else {
callback(false);
}
},
error: function(xhr, type, errorThrown) {
callback(false);
}
});
}, function(e) {
console.log("获取定位位置信息失败:" + e.message);
callback(false);
}, {
provider: 'baidu'
});
} catch (e) {
callback(false);
console.error(e.message);
}
}
$.getbaiduposition = getPosition;
}(mui));
tip:帖子使用[Haroopad](http://pad.haroopress.com/user.html)构建,狂拽酷炫吊炸天
如果有版式问题,移步到这phillyx
关于百度定位
- 这是官方定位的解释:geolocation
- 地图插件配置
- 我在问答里面找到了这位童鞋的百度定位,地址变更提醒
不过,童鞋倒是给具体的示例啊,木有\~\~\~\~(>_<)\~\~\~\~ 官方的插件配置也看的懵懵懂懂,一塌糊涂 ok,自己搞,搞了大半天基本上弄清楚了,下面就总结一下自己的心血历程吧!!!~~~~~
- 首先要到百度lbs开放平台注册开发者账号
- 在应用里面创建应用我的应用
- 服务器、Android、ios、浏览器逐个建立一个遍
- 安卓和ios的安全码采用dcloud官方的“BA:AD:09:3A:82:82:9F:B4:32:A7:B2:8C:B4:CC:F0:E9:F3:7D:AE:58;io.dcloud.HBuilder”
- 服务器和浏览器的Refer白名单默认“*”
- 下面就是挖坑填坑的经历了
- 刚开始的使用JavaScript API大众版, 根据demo:helloworld照葫芦画瓢,可是太尼玛慢
- 接着看到了JavaScript API极速版, ok 这次快了好多,能不能更快呢,当然可以O(∩_∩)O~
- 秘诀就是这Web服务API
使用Geocoding API
通过逆地理编码服务获取数据
我们可以将以下链接放到浏览器地址栏中试一下
http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderReverse&location=39.983424,116.322987&output=json&pois=1
到这终于可以松一口气了,差多搞定了,下面就是码转了,为了方便,直接贴代码了
<!--废弃-->
<!--<script type="text/javascript" src="http://api.map.baidu.com/api?type=quick&ak=你的key&v=1.0"></script>-->
(function($) {
/**
* @description 获取百度定位信息
* @param {Function} callback
*/
function getPosition(callback) {
try {
plus.geolocation.getCurrentPosition(function(position) {
console.log(JSON.stringify(position));
var codns = position.coords; //获取地理坐标信息;
// var geoc = new BMap.Geocoder();
// var pt = new BMap.Point(codns.longitude, codns.latitude);
// geoc.getLocation(pt, function(rs) {
// var addComp = rs.addressComponents;
// console.log(JSON.stringify(addComp));
// var lo =addComp.province+','+addComp.city;
// callback(lo);
// });
var req = 'http://api.map.baidu.com/geocoder/v2/';
var parms = {
ak: '你的key',
callback: 'renderReverse',
output: 'json',
location: codns.latitude + ',' + codns.longitude
//,pois:1(周边poi数组) //不建议要,周边数据太杂,不需要
};
mui.ajax(req, {
data: parms,
dataType: 'json', //服务器返回json格式数据
type: 'post', //HTTP请求类型
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
console.log(JSON.stringify(data));
myStorage.setItem('geolocation',data);
if (data.status == 0) {
var lo = data.result.addressComponent.province + ',' + data.result.addressComponent.city;
callback(lo);
} else {
callback(false);
}
},
error: function(xhr, type, errorThrown) {
callback(false);
}
});
}, function(e) {
console.log("获取定位位置信息失败:" + e.message);
callback(false);
}, {
provider: 'baidu'
});
} catch (e) {
callback(false);
console.error(e.message);
}
}
$.getbaiduposition = getPosition;
}(mui));
tip:帖子使用[Haroopad](http://pad.haroopress.com/user.html)构建,狂拽酷炫吊炸天
收起阅读 »

Android平台离线打包推送插件配置
个推推送平台配置
需要拷贝的文件
需要引入工程的jar/aar文件
需要将以下jar/aar文件放到工程的libs目录下
路径 | 文件 |
---|---|
SDK\libs(1.9.9.52372之前) | aps.jar, aps-igexin.jar, GetuiSDK2.10.3.5.jar |
SDK\libs(1.9.9.52372之后) | aps-release.aar, aps-igexin-release.aar |
需要将以下so文件放到工程的libs\armeabi目录下(1.9.9.52372版本之后不需要设置此项)
路径 | 文件名 |
---|---|
SDK\libs\armeabi | libgetuiext2.so |
SDK\libs\armeabi-v7a | libgetuiext2.so |
SDK\libs\x86 | libgetuiext2.so |
需要引入工程的资源文件
需要将以下文件放到工程的res/layout目录下(1.9.9.52372版本之后不需要设置此项)
路径 | 文件名 |
---|---|
SDK\res\layout | getui_notification.xml |
SDK\res\raw | keep.xml |
Androidmainfest.xml文件需要修改的项
需要在application节点前添加权限
因Android L(android 5.0)系统自身限制,多个应用安装时,如果拥有同一个Service权限,会导致权限冲突,只能安装一个带有此权限的应用。对此,个推SDK在声明自定义权限时需要添加apk的包名以避免和其他使用个推的应用冲突。
<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.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="getui.permission.GetuiService.$你的APK包名"/>
<permission android:name="getui.permission.GetuiService.$你的APK包名" android:protectionLevel="normal"/>
<application>
节点下配置如下代码
<meta-data android:name="PUSH_APPID" android:value="$你自己的APPID"/>
<meta-data android:name="PUSH_APPKEY" android:value="$你的appkey"/>
<meta-data android:name="PUSH_APPSECRET" android:value="$你的appsecret"/>
<service
android:name="com.igexin.sdk.PushService"
android:exported="true"
android:label="NotificationCenter"
android:process=":pushservice">
<intent-filter>
<action android:name="com.igexin.sdk.action.service.message"/>
</intent-filter>
</service>
<receiver android:name="com.igexin.sdk.PushReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="com.igexin.sdk.action.refreshls"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
<activity
android:name="com.igexin.sdk.PushActivity"
android:excludeFromRecents="true"
android:exported="false"
android:process=":pushservice"
android:taskAffinity="com.igexin.sdk.PushActivityTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity
android:name="com.igexin.sdk.GActivity"
android:excludeFromRecents="true"
android:exported="true"
android:process=":pushservice"
android:taskAffinity="com.igexin.sdk.PushActivityTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<receiver android:name="io.dcloud.feature.apsGt.GTNotificationReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="填写APK的包名.__CREATE_NOTIFICATION"/>
<action android:name="填写APK的包名.__REMOVE_NOTIFICATION"/>
<action android:name="填写APK的包名.__CLEAR_NOTIFICATION"/>
<action android:name="填写APK的包名.__CLILK_NOTIFICATION"/>
</intent-filter>
</receiver>
<service
android:name="io.dcloud.feature.apsGt.GTNormalIntentService"/>
dcloud_properties.xml需要添加如下代码
dcloud_properties.xml文件在assets/data目录下
features节点下添加
<feature name="Push" value="io.dcloud.feature.aps.APSFeatureImpl"><module name="igexin" value="io.dcloud.feature.apsGt.GTPushService"/></feature>
services节点下添加
<service
name="push"
value="io.dcloud.feature.aps.APSFeatureImpl" />
小米推送
需要拷贝的文件
需要将以下jar/aar文件拷贝到工程中
路径 | 文件 |
---|---|
SDK\libs(1.9.9.52372之前) | aps.jar,aps-xiaomi.jar,MiPush_SDK_Client_3_1_2.jar, |
SDK\libs(1.9.9.52372之后) | aps-release.aar, aps-xiaomi-release.aar |
Androidmainfest.xml文件需要修改的项
需要在application节点前添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<permission android:name="填写APK的包名.permission.MIPUSH_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="填写APK的包名.permission.MIPUSH_RECEIVE"/>
application节点下配置如下代码
<service android:enabled="true" android:process=":pushservice" android:name="com.xiaomi.push.service.XMPushService"/>
<service android:name="com.xiaomi.push.service.XMJobService" android:enabled="true" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE" android:process=":pushservice"/>
<service android:enabled="true" android:exported="true" android:name="com.xiaomi.mipush.sdk.PushMessageHandler"/>
<service android:enabled="true" android:name="com.xiaomi.mipush.sdk.MessageHandleService"/>
<receiver android:exported="true" android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<receiver android:exported="false" android:process=":pushservice" android:name="com.xiaomi.push.service.receivers.PingReceiver">
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER"/>
</intent-filter>
</receiver>
<receiver android:exported="true" android:name="io.dcloud.feature.apsXm.XMMessageReceiver">
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>
<receiver android:exported="true" android:name="io.dcloud.feature.apsXm.XMNotificationReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="%填写APK的包名%.__CREATE_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__REMOVE_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__CLEAR_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__CLILK_NOTIFICATION"/>
</intent-filter>
</receiver>
<meta-data android:name="PUSH_APPID" android:value="_%小米推送的APPID%"/>
<meta-data android:name="PUSH_APPKEY" android:value="_%小米推送的APPKEY%"/>
dcloud_properties.xml需要添加如下代码
dcloud_properties.xml文件在ADT工程assets/data目录下
Features节点下添加
<feature name="Push" value="io.dcloud.feature.aps.APSFeatureImpl">
<module name="xiaomi" value="io.dcloud.feature.apsXm.XMPushService"/>
</feature>
Service节点下添加
<service name="push" value="io.dcloud.feature.aps.APSFeatureImpl"/>
个推推送平台配置
需要拷贝的文件
需要引入工程的jar/aar文件
需要将以下jar/aar文件放到工程的libs目录下
路径 | 文件 |
---|---|
SDK\libs(1.9.9.52372之前) | aps.jar, aps-igexin.jar, GetuiSDK2.10.3.5.jar |
SDK\libs(1.9.9.52372之后) | aps-release.aar, aps-igexin-release.aar |
需要将以下so文件放到工程的libs\armeabi目录下(1.9.9.52372版本之后不需要设置此项)
路径 | 文件名 |
---|---|
SDK\libs\armeabi | libgetuiext2.so |
SDK\libs\armeabi-v7a | libgetuiext2.so |
SDK\libs\x86 | libgetuiext2.so |
需要引入工程的资源文件
需要将以下文件放到工程的res/layout目录下(1.9.9.52372版本之后不需要设置此项)
路径 | 文件名 |
---|---|
SDK\res\layout | getui_notification.xml |
SDK\res\raw | keep.xml |
Androidmainfest.xml文件需要修改的项
需要在application节点前添加权限
因Android L(android 5.0)系统自身限制,多个应用安装时,如果拥有同一个Service权限,会导致权限冲突,只能安装一个带有此权限的应用。对此,个推SDK在声明自定义权限时需要添加apk的包名以避免和其他使用个推的应用冲突。
<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.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="getui.permission.GetuiService.$你的APK包名"/>
<permission android:name="getui.permission.GetuiService.$你的APK包名" android:protectionLevel="normal"/>
<application>
节点下配置如下代码
<meta-data android:name="PUSH_APPID" android:value="$你自己的APPID"/>
<meta-data android:name="PUSH_APPKEY" android:value="$你的appkey"/>
<meta-data android:name="PUSH_APPSECRET" android:value="$你的appsecret"/>
<service
android:name="com.igexin.sdk.PushService"
android:exported="true"
android:label="NotificationCenter"
android:process=":pushservice">
<intent-filter>
<action android:name="com.igexin.sdk.action.service.message"/>
</intent-filter>
</service>
<receiver android:name="com.igexin.sdk.PushReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="com.igexin.sdk.action.refreshls"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
<activity
android:name="com.igexin.sdk.PushActivity"
android:excludeFromRecents="true"
android:exported="false"
android:process=":pushservice"
android:taskAffinity="com.igexin.sdk.PushActivityTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity
android:name="com.igexin.sdk.GActivity"
android:excludeFromRecents="true"
android:exported="true"
android:process=":pushservice"
android:taskAffinity="com.igexin.sdk.PushActivityTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<receiver android:name="io.dcloud.feature.apsGt.GTNotificationReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="填写APK的包名.__CREATE_NOTIFICATION"/>
<action android:name="填写APK的包名.__REMOVE_NOTIFICATION"/>
<action android:name="填写APK的包名.__CLEAR_NOTIFICATION"/>
<action android:name="填写APK的包名.__CLILK_NOTIFICATION"/>
</intent-filter>
</receiver>
<service
android:name="io.dcloud.feature.apsGt.GTNormalIntentService"/>
dcloud_properties.xml需要添加如下代码
dcloud_properties.xml文件在assets/data目录下
features节点下添加
<feature name="Push" value="io.dcloud.feature.aps.APSFeatureImpl"><module name="igexin" value="io.dcloud.feature.apsGt.GTPushService"/></feature>
services节点下添加
<service
name="push"
value="io.dcloud.feature.aps.APSFeatureImpl" />
小米推送
需要拷贝的文件
需要将以下jar/aar文件拷贝到工程中
路径 | 文件 |
---|---|
SDK\libs(1.9.9.52372之前) | aps.jar,aps-xiaomi.jar,MiPush_SDK_Client_3_1_2.jar, |
SDK\libs(1.9.9.52372之后) | aps-release.aar, aps-xiaomi-release.aar |
Androidmainfest.xml文件需要修改的项
需要在application节点前添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<permission android:name="填写APK的包名.permission.MIPUSH_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="填写APK的包名.permission.MIPUSH_RECEIVE"/>
application节点下配置如下代码
<service android:enabled="true" android:process=":pushservice" android:name="com.xiaomi.push.service.XMPushService"/>
<service android:name="com.xiaomi.push.service.XMJobService" android:enabled="true" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE" android:process=":pushservice"/>
<service android:enabled="true" android:exported="true" android:name="com.xiaomi.mipush.sdk.PushMessageHandler"/>
<service android:enabled="true" android:name="com.xiaomi.mipush.sdk.MessageHandleService"/>
<receiver android:exported="true" android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<receiver android:exported="false" android:process=":pushservice" android:name="com.xiaomi.push.service.receivers.PingReceiver">
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER"/>
</intent-filter>
</receiver>
<receiver android:exported="true" android:name="io.dcloud.feature.apsXm.XMMessageReceiver">
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>
<receiver android:exported="true" android:name="io.dcloud.feature.apsXm.XMNotificationReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="%填写APK的包名%.__CREATE_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__REMOVE_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__CLEAR_NOTIFICATION"/>
<action android:name="%填写APK的包名%.__CLILK_NOTIFICATION"/>
</intent-filter>
</receiver>
<meta-data android:name="PUSH_APPID" android:value="_%小米推送的APPID%"/>
<meta-data android:name="PUSH_APPKEY" android:value="_%小米推送的APPKEY%"/>
dcloud_properties.xml需要添加如下代码
dcloud_properties.xml文件在ADT工程assets/data目录下
Features节点下添加
<feature name="Push" value="io.dcloud.feature.aps.APSFeatureImpl">
<module name="xiaomi" value="io.dcloud.feature.apsXm.XMPushService"/>
</feature>
Service节点下添加
<service name="push" value="io.dcloud.feature.aps.APSFeatureImpl"/>
收起阅读 »