HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Android配置应用主题皮肤

Android Theme 主题 换肤

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深度对比分析

侵权 APICloud

> 更新:最新版比较详见:https://ask.dcloud.net.cn/article/36732

========以下为历史内容=========

其实就选型对比而言,不深入看产品,有4点就足矣。

  1. 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点就足矣。

  1. 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的了

收起阅读 »

【分享】淘宝商品评分示例

评分 技术分享 星星评分

无图无真相,先看效果图:
image
接下来是代码实现部分,比较简单,自己看:
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

继续阅读 »

无图无真相,先看效果图:
image
接下来是代码实现部分,比较简单,自己看:
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证书的问题解决办法。

iOS iOS证书

有关苹果无法导出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的自定义样式

分享插件 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的支持

HTML5+
 看到问题咨询里有一些关于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精编版

HTML5+ 文档 chm

在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~

不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~

另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~

【update】
5.30 修正部分文档链接错误

继续阅读 »

在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~

不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~

另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~

【update】
5.30 修正部分文档链接错误

收起阅读 »

[分享]简单使用模板,代替字符串拼接。

js 模板

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支持插件

node.js 插件 nodejs node

在eclipse插件中,node.js插件中比较知名的是nodeclipse。

从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
node
5.选择要新建的nodejs项目类型新建项目即可

  1. 在js文件里提示node.js
    nodezhushou

注意: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

  1. 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
  2. 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
  3. 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
  4. 加载完毕后,找到programming languages如下图
  5. 勾选programming languages下的JavaScript Development Tools如下图

    6.点击下一步,接受许可协议并安装,安装完毕后重启即可
    安装nodeclipse
  6. 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
    nodeclipse
    2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可
  7. 安装完毕后重启HBuilder
  8. 新建node项目:依次点击菜单文件→新建→其他如下图
    node
    5.选择要新建的nodejs项目类型新建项目即可
  9. 在js文件里提示node.js
    nodezhushou
继续阅读 »

在eclipse插件中,node.js插件中比较知名的是nodeclipse。

从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
node
5.选择要新建的nodejs项目类型新建项目即可

  1. 在js文件里提示node.js
    nodezhushou

注意: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

  1. 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
  2. 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
  3. 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
  4. 加载完毕后,找到programming languages如下图
  5. 勾选programming languages下的JavaScript Development Tools如下图

    6.点击下一步,接受许可协议并安装,安装完毕后重启即可
    安装nodeclipse
  6. 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
    nodeclipse
    2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可
  7. 安装完毕后重启HBuilder
  8. 新建node项目:依次点击菜单文件→新建→其他如下图
    node
    5.选择要新建的nodejs项目类型新建项目即可
  9. 在js文件里提示node.js
    nodezhushou
收起阅读 »

iOS离线打包-友盟统计配置

离线打包

添加友盟统计插件

注:Linker Flags的添加方法请参考这个文档

  1. 添加以下静态库:liblibStatistic.a

  2. 添加以下framework: "UMAnalytics.framework",
    "UMCommon.framework",

  3. 添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd

配置友盟统计插件

1.到友盟开放平台申请Appkey

2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey

注意:

IDFA说明

友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))

继续阅读 »

添加友盟统计插件

注:Linker Flags的添加方法请参考这个文档

  1. 添加以下静态库:liblibStatistic.a

  2. 添加以下framework: "UMAnalytics.framework",
    "UMCommon.framework",

  3. 添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd

配置友盟统计插件

1.到友盟开放平台申请Appkey

2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey

注意:

IDFA说明

友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))

收起阅读 »

搞一搞百度定位

定位

如果有版式问题,移步到这phillyx

关于百度定位

  1. 这是官方定位的解释:geolocation
  2. 地图插件配置
  3. 我在问答里面找到了这位童鞋的百度定位,地址变更提醒
    不过,童鞋倒是给具体的示例啊,木有\~\~\~\~(>_<)\~\~\~\~  
    官方的插件配置也看的懵懵懂懂,一塌糊涂  
    ok,自己搞,搞了大半天基本上弄清楚了,下面就总结一下自己的心血历程吧!!!~~~~~  

  4. 首先要到百度lbs开放平台注册开发者账号
  5. 在应用里面创建应用我的应用
  6. 服务器、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白名单默认“*”
  7. 下面就是挖坑填坑的经历了
    • 刚开始的使用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

关于百度定位

  1. 这是官方定位的解释:geolocation
  2. 地图插件配置
  3. 我在问答里面找到了这位童鞋的百度定位,地址变更提醒
    不过,童鞋倒是给具体的示例啊,木有\~\~\~\~(>_<)\~\~\~\~  
    官方的插件配置也看的懵懵懂懂,一塌糊涂  
    ok,自己搞,搞了大半天基本上弄清楚了,下面就总结一下自己的心血历程吧!!!~~~~~  

  4. 首先要到百度lbs开放平台注册开发者账号
  5. 在应用里面创建应用我的应用
  6. 服务器、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白名单默认“*”
  7. 下面就是挖坑填坑的经历了
    • 刚开始的使用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平台离线打包推送插件配置

离线打包 5+App开发 SDK

个推推送平台配置

需要拷贝的文件

需要引入工程的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"/>
收起阅读 »