HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

类似美团底部栏实现

程序基础框架:base.html

<body>  
    <div class="mui-content">  
        <div id="output"></div>  
    </div>  
    <footer class="mui-bar-footer mui-hidden" id="footer">  
        <nav class="mui-bar mui-bar-tab">  
            <a class="mui-tab-item mui-active" id="home" href="javascript:;" pageurl="./template/home/home.html">  
                <span class="mui-icon mui-icon-home"></span>  
                <span class="mui-tab-label">首页</span>  
            </a>  
            <a class="mui-tab-item" id="user" href="javascript:;" pageurl="./template/user/user.html">  
                <span class="mui-icon mui-icon-contact"></span>  
                <span class="mui-tab-label">我的</span>  
            </a>  
            <a class="mui-tab-item" id="more" href="javascript:;" pageurl="./template/more/more.html">  
                <span class="mui-icon mui-icon-more"></span>  
                <span class="mui-tab-label">更多</span>  
            </a>  
        </nav>  
    </footer>  
       <script type="text/javascript" src="base.js"></script>  
</body>

脚本:base.js


        var _preloadPages = Array();  
        var arr = mui('.mui-bar-footer a');  
        for(var i=0;i<arr.length;i++){  
            var pageurl = arr[i].getAttribute('pageurl');  
            var pageid = arr[i].getAttribute('id');  
            _preloadPages.push({  
                url:pageurl,  
                id:pageid,  
                styles:{  
                    top:'0',  
                    bottom:'50px'  
                }  
            });  
        };  

        mui.init({preloadPages:_preloadPages,keyEventBind:{backbutton: true}});  
        mui('.mui-bar-footer').on('tap','a',function(){  
            var jmp_id= this.getAttribute('id');  
            mui.openWindow({  
                id:jmp_id  
             });  
        });  

        mui.later(function(){  
            mui.openWindow({  
                id:'home'  
             });  

            document.getElementById("footer").classList.remove("mui-hidden");  

        },1000);  

2级页面底部条按钮:home.html user.html more.html
2级页面必须禁止返回键(包含以下代码),每个按钮对应一个webview


<script type="text/javascript">  
    mui.init({  
        keyEventBind: {  
                backbutton: false  //关闭back按键监听  
            }  
    });  
</script>  

3级页面底部条按钮比如:home.html 的a标签跳转的到页面
3级页面必须不用禁止返回键(包含以下代码)


<script type="text/javascript">
mui.init();
</script>


除了base.html 必须固定格式外,其他页面通通用<a href="3级页面.html" >
实现跳转

继续阅读 »

程序基础框架:base.html

<body>  
    <div class="mui-content">  
        <div id="output"></div>  
    </div>  
    <footer class="mui-bar-footer mui-hidden" id="footer">  
        <nav class="mui-bar mui-bar-tab">  
            <a class="mui-tab-item mui-active" id="home" href="javascript:;" pageurl="./template/home/home.html">  
                <span class="mui-icon mui-icon-home"></span>  
                <span class="mui-tab-label">首页</span>  
            </a>  
            <a class="mui-tab-item" id="user" href="javascript:;" pageurl="./template/user/user.html">  
                <span class="mui-icon mui-icon-contact"></span>  
                <span class="mui-tab-label">我的</span>  
            </a>  
            <a class="mui-tab-item" id="more" href="javascript:;" pageurl="./template/more/more.html">  
                <span class="mui-icon mui-icon-more"></span>  
                <span class="mui-tab-label">更多</span>  
            </a>  
        </nav>  
    </footer>  
       <script type="text/javascript" src="base.js"></script>  
</body>

脚本:base.js


        var _preloadPages = Array();  
        var arr = mui('.mui-bar-footer a');  
        for(var i=0;i<arr.length;i++){  
            var pageurl = arr[i].getAttribute('pageurl');  
            var pageid = arr[i].getAttribute('id');  
            _preloadPages.push({  
                url:pageurl,  
                id:pageid,  
                styles:{  
                    top:'0',  
                    bottom:'50px'  
                }  
            });  
        };  

        mui.init({preloadPages:_preloadPages,keyEventBind:{backbutton: true}});  
        mui('.mui-bar-footer').on('tap','a',function(){  
            var jmp_id= this.getAttribute('id');  
            mui.openWindow({  
                id:jmp_id  
             });  
        });  

        mui.later(function(){  
            mui.openWindow({  
                id:'home'  
             });  

            document.getElementById("footer").classList.remove("mui-hidden");  

        },1000);  

2级页面底部条按钮:home.html user.html more.html
2级页面必须禁止返回键(包含以下代码),每个按钮对应一个webview


<script type="text/javascript">  
    mui.init({  
        keyEventBind: {  
                backbutton: false  //关闭back按键监听  
            }  
    });  
</script>  

3级页面底部条按钮比如:home.html 的a标签跳转的到页面
3级页面必须不用禁止返回键(包含以下代码)


<script type="text/javascript">
mui.init();
</script>


除了base.html 必须固定格式外,其他页面通通用<a href="3级页面.html" >
实现跳转

收起阅读 »

外包一个视频APP管理

视频

有做过的联系

包括后台开发!@

QQ 1120094610

有做过的联系

包括后台开发!@

QQ 1120094610

mui.openWindow新页面无法获取焦点

页面A
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
<style>
</style>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui.plusReady(function() {
document.getElementById("btn").addEventListener("tap", function(e) {
mui.openWindow({
url: 'test2.html',
id: 'test1'
});
}, false);
});
</script>
</head>
<body>test1
<button id="btn">OPEN</button>
</body>
</html>

页面B

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
<style>
</style>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui.plusReady(function() {
document.getElementById("txt").focus();
});
</script>
</head>
<body>test2
<input type="text" id="txt" />
</body>
</html>

页面A点击打开页面B,B页面无法获取焦点,如果直接打开页面B可以获取焦点

继续阅读 »

页面A
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
<style>
</style>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui.plusReady(function() {
document.getElementById("btn").addEventListener("tap", function(e) {
mui.openWindow({
url: 'test2.html',
id: 'test1'
});
}, false);
});
</script>
</head>
<body>test1
<button id="btn">OPEN</button>
</body>
</html>

页面B

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
<style>
</style>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui.plusReady(function() {
document.getElementById("txt").focus();
});
</script>
</head>
<body>test2
<input type="text" id="txt" />
</body>
</html>

页面A点击打开页面B,B页面无法获取焦点,如果直接打开页面B可以获取焦点

收起阅读 »

关于HBuilder的问题提起

HTML5+

第一次注册的时候可能因为服务器的原因发送邮件比较缓慢所以需要等比较久的时间,我等了10多分钟,

第一次注册的时候可能因为服务器的原因发送邮件比较缓慢所以需要等比较久的时间,我等了10多分钟,

mui + react的组件化开发

原文地址:http://www.jianshu.com/p/5698c0edb307

原文地址:http://www.jianshu.com/p/5698c0edb307

wap2app 打包教程

wap2app云端打包 wap2app App云端打包 云端打包

需求明确

此教程适用于利用 HBuilder 云打包 - 打原生安装包(apk/ipa)的用户。

详细步骤

Android

  1. 需要证书,HBuilder云端打包默认证书是DCloud的公用证书,可以直接用这个证书,也可以使用自有证书,两者不影响安装包的发布,唯一的差别就是证书中开发者和企业信息不同。关于公用证书的信息,请参考Android打包证书; 关于使用自有证书打包,请参考生成Android签名证书
  2. 需要注意 manifest.json 中的应用信息是否填写正确。如果填写的有问题,打包按钮是会被禁用的。
  3. 配置打包信息,App包名是必填项,建议使用反向域名风格的字符串,如“com.domainname.appname”。记住这个包名,如果需要实现第三方业务比如个推,地图定位,分享,支付之类会需要你在开发者平台中填写包名。注意:wap2app中如果首页有适配到css,也就是根目录下appid + 'append.css'文件是有内容的,需要在manifest.json中配置 “解压资源后运行”打包之后才会提前注入该css文件,默认是“不解压直接运行”,如下图所示
  4. 查看打包状态,菜单栏上发行 -> 查看打包状态,打开“查看App打包状态”对话框,可查看打包历史记录和状态
  5. 下载安装包,在“查看App打包状态”对话框中 “打开下载目录”可查看并下载安装包
  6. 安装到手机上,有很多手机和电脑的同步工具比如360手机助手,Android文件传输等等。

iOS

iOS打包分为两种:越狱包使用苹果证书 打包。

越狱包
只能安装在已越狱的设备上,只需填写AppID,即可打包。

使用苹果证书打包
可通过iDP证书打包提交到Appstore发布、或通过iEP证书打包在企业内部发布,请点击查看关于iDP和iEP的区别以及如何安装ipa包到手机上

点击菜单栏 发行 -> 打原生安装包,切换到ios ,使用自有证书打包,你会看到如下信息需要你填写,详细说明如下:

  • AppID:iOS应用标识,推荐使用反向域名风格的字符串,如“com.domainname.appname”,必须与profile文件绑定的App ID匹配。
  • 私钥证书:iOS Certificates文件(.p12);
  • 私钥密码:导入私钥证书的密码;
  • Profile文件:iOS Provisioning Profile文件(.mobileprovision),必须与苹果App ID和私钥证书区配;

步骤如下:

  1. 首先得申请证书,需要 profile(.mobileprovision)文件 和 私钥证书(.p12),详细申请证书教程可参考iOS证书(.p12)和描述文件(.mobileprovision)申请
  2. 配置打包信息,在上一步操作中你可以申请到开发(Development)证书和发布(Distribution)证书以及配套的描述文件,所以此时你可以打出测试包和正式包。两者的区别就是通过iTools安装到手机时,测试包能安装成功,正式包不行。当然,如果你需要在提交审核前测试正式包的话,也可以上传到appsotre上然后通过 testFlight 测试。
  3. 查看打包状态。菜单栏上发行 -> 查看打包状态,打开“查看App打包状态”对话框,可查看打包历史记录和状态
  4. 下载安装包,与 Android 的一样
  5. 安装到手机上,请点击查看如何安装ipa包到手机上

补充说明

  1. 真机运行时涉及第三方业务比如地图定位,分享,支付默认是支持的,但是打包成原生安装包时,因为需要绑定包名,所以需开发者到相应的开发者平台申请。
  2. 常见错误请参考App云端打包失败常见问题汇总
继续阅读 »

需求明确

此教程适用于利用 HBuilder 云打包 - 打原生安装包(apk/ipa)的用户。

详细步骤

Android

  1. 需要证书,HBuilder云端打包默认证书是DCloud的公用证书,可以直接用这个证书,也可以使用自有证书,两者不影响安装包的发布,唯一的差别就是证书中开发者和企业信息不同。关于公用证书的信息,请参考Android打包证书; 关于使用自有证书打包,请参考生成Android签名证书
  2. 需要注意 manifest.json 中的应用信息是否填写正确。如果填写的有问题,打包按钮是会被禁用的。
  3. 配置打包信息,App包名是必填项,建议使用反向域名风格的字符串,如“com.domainname.appname”。记住这个包名,如果需要实现第三方业务比如个推,地图定位,分享,支付之类会需要你在开发者平台中填写包名。注意:wap2app中如果首页有适配到css,也就是根目录下appid + 'append.css'文件是有内容的,需要在manifest.json中配置 “解压资源后运行”打包之后才会提前注入该css文件,默认是“不解压直接运行”,如下图所示
  4. 查看打包状态,菜单栏上发行 -> 查看打包状态,打开“查看App打包状态”对话框,可查看打包历史记录和状态
  5. 下载安装包,在“查看App打包状态”对话框中 “打开下载目录”可查看并下载安装包
  6. 安装到手机上,有很多手机和电脑的同步工具比如360手机助手,Android文件传输等等。

iOS

iOS打包分为两种:越狱包使用苹果证书 打包。

越狱包
只能安装在已越狱的设备上,只需填写AppID,即可打包。

使用苹果证书打包
可通过iDP证书打包提交到Appstore发布、或通过iEP证书打包在企业内部发布,请点击查看关于iDP和iEP的区别以及如何安装ipa包到手机上

点击菜单栏 发行 -> 打原生安装包,切换到ios ,使用自有证书打包,你会看到如下信息需要你填写,详细说明如下:

  • AppID:iOS应用标识,推荐使用反向域名风格的字符串,如“com.domainname.appname”,必须与profile文件绑定的App ID匹配。
  • 私钥证书:iOS Certificates文件(.p12);
  • 私钥密码:导入私钥证书的密码;
  • Profile文件:iOS Provisioning Profile文件(.mobileprovision),必须与苹果App ID和私钥证书区配;

步骤如下:

  1. 首先得申请证书,需要 profile(.mobileprovision)文件 和 私钥证书(.p12),详细申请证书教程可参考iOS证书(.p12)和描述文件(.mobileprovision)申请
  2. 配置打包信息,在上一步操作中你可以申请到开发(Development)证书和发布(Distribution)证书以及配套的描述文件,所以此时你可以打出测试包和正式包。两者的区别就是通过iTools安装到手机时,测试包能安装成功,正式包不行。当然,如果你需要在提交审核前测试正式包的话,也可以上传到appsotre上然后通过 testFlight 测试。
  3. 查看打包状态。菜单栏上发行 -> 查看打包状态,打开“查看App打包状态”对话框,可查看打包历史记录和状态
  4. 下载安装包,与 Android 的一样
  5. 安装到手机上,请点击查看如何安装ipa包到手机上

补充说明

  1. 真机运行时涉及第三方业务比如地图定位,分享,支付默认是支持的,但是打包成原生安装包时,因为需要绑定包名,所以需开发者到相应的开发者平台申请。
  2. 常见错误请参考App云端打包失败常见问题汇总
收起阅读 »

【重要】iOS平台HBuilder8.8.6真机无法运行的处理方法

iOS真机运行失败

非常抱歉,由于我们内部工作失误,没有及时更新iOS平台的调试基座打包证书,导致从2017.11.22下午开始,HBuilder8.8.6的iOS平台无法真机运行。
11月22日晚HBuilder已发布紧急更新本(8.8.7),已解决该问题
大家可以升级到最新版HBuilder。

如果不想升级8.8.7,以下是临时解决方案:

  1. 这里下载HBuilder调试基座
  2. 替换HBuilder真机调试安装包目录下的iPhone_base.ipa文件
    路径为“%HBuilder%\plugins\com.pandora.tools.android_1.0.0.201711151411\base\”,其中%HBuilder%为HBuilder安装根目录,“com.pandora.tools.android_1.0.0.201711151411”为调试安装包文件夹,后面数字是版本号,如果不存在此文件夹,找到最新的版本号的文件夹即可。
    注意:文件名称必须是“iPhone_base.ipa”。
  3. 删除手机上的HBuilder应用
  4. 重新真机运行

给开发者带来不便,深表歉意。

继续阅读 »

非常抱歉,由于我们内部工作失误,没有及时更新iOS平台的调试基座打包证书,导致从2017.11.22下午开始,HBuilder8.8.6的iOS平台无法真机运行。
11月22日晚HBuilder已发布紧急更新本(8.8.7),已解决该问题
大家可以升级到最新版HBuilder。

如果不想升级8.8.7,以下是临时解决方案:

  1. 这里下载HBuilder调试基座
  2. 替换HBuilder真机调试安装包目录下的iPhone_base.ipa文件
    路径为“%HBuilder%\plugins\com.pandora.tools.android_1.0.0.201711151411\base\”,其中%HBuilder%为HBuilder安装根目录,“com.pandora.tools.android_1.0.0.201711151411”为调试安装包文件夹,后面数字是版本号,如果不存在此文件夹,找到最新的版本号的文件夹即可。
    注意:文件名称必须是“iPhone_base.ipa”。
  3. 删除手机上的HBuilder应用
  4. 重新真机运行

给开发者带来不便,深表歉意。

收起阅读 »

推送开发指南

消息推送 推送

简介

推送服务是一项移动应用消息推送服务解决方案,支持Android和iOS两大平台,开发者可以借助该服务,快速构建稳定高效的消息推送系统,及时有效地将服务端消息推送到客户端上,为实时业务需求和产品运营提供技术支持,从而积极地保持与用户的连接,并提高用户活跃度和留存率。本文档帮助开发者理解推送服务的工作流程,手把手介绍所需的各项集成步骤,同时介绍了消息的不同类型特点,供应用开发者根据实际业务需求进行选择。

推送消息

推送消息总共分为通知消息和透传消息两大类。通知消息一般会在系统消息中心通知显示,满足日常的运营需求,而通知消息按照后续动作分类,又可分为启动应用消息(即普通通知消息),打开网页消息,下载链接消息三种;透传消息则会将消息下发到app,后续动作由app进行定制,从而满足业务相关的特定功能需求,注意透传消息需要满足json格式,并包含key分别为title,content,payload的键值对内容,三者缺一不可,如:

透传消息的格式为{title:"通知标题",content:"通知内容",payload:"通知去干嘛这里可以自定义"}

另外5+API提供了推送消息事件监听机制,app接收到消息的“receive”事件和用户点击消息的“click”事件,如当用户点击消息中心里的消息时会启动应用,并且在监听push事件的页面触发“click”事件。API详细介绍移步这里事件监听,并且两个事件根据推送消息类型和格式,手机操作系统,手机网络连接情况的不同,产生不同的触发情况。现总结如下:


推送配置

开发者向个推开放平台进行应用注册,得到appid,appkey,appsecret的值,然后在HBuilder中的项目进行配置,配置步骤参考如下文档:
HBuilder中推送消息模块配置
服务端也需要下载并集成个推相应服务器端SDK下载地址,同时我们提供用php写的服务端开源项目,仅供参考。
推送消息服务器开源项目Github地址

继续阅读 »

简介

推送服务是一项移动应用消息推送服务解决方案,支持Android和iOS两大平台,开发者可以借助该服务,快速构建稳定高效的消息推送系统,及时有效地将服务端消息推送到客户端上,为实时业务需求和产品运营提供技术支持,从而积极地保持与用户的连接,并提高用户活跃度和留存率。本文档帮助开发者理解推送服务的工作流程,手把手介绍所需的各项集成步骤,同时介绍了消息的不同类型特点,供应用开发者根据实际业务需求进行选择。

推送消息

推送消息总共分为通知消息和透传消息两大类。通知消息一般会在系统消息中心通知显示,满足日常的运营需求,而通知消息按照后续动作分类,又可分为启动应用消息(即普通通知消息),打开网页消息,下载链接消息三种;透传消息则会将消息下发到app,后续动作由app进行定制,从而满足业务相关的特定功能需求,注意透传消息需要满足json格式,并包含key分别为title,content,payload的键值对内容,三者缺一不可,如:

透传消息的格式为{title:"通知标题",content:"通知内容",payload:"通知去干嘛这里可以自定义"}

另外5+API提供了推送消息事件监听机制,app接收到消息的“receive”事件和用户点击消息的“click”事件,如当用户点击消息中心里的消息时会启动应用,并且在监听push事件的页面触发“click”事件。API详细介绍移步这里事件监听,并且两个事件根据推送消息类型和格式,手机操作系统,手机网络连接情况的不同,产生不同的触发情况。现总结如下:


推送配置

开发者向个推开放平台进行应用注册,得到appid,appkey,appsecret的值,然后在HBuilder中的项目进行配置,配置步骤参考如下文档:
HBuilder中推送消息模块配置
服务端也需要下载并集成个推相应服务器端SDK下载地址,同时我们提供用php写的服务端开源项目,仅供参考。
推送消息服务器开源项目Github地址

收起阅读 »

Android Studio环境进行离线打包

离线打包

1) 导入项目官网下载的HBuilder离线打包Android版SDK(5+ SDK下载)中项目\Android-SDK@1.9.9.38184_20171023\HBuilder-Hello
1-1) 出现“manifest merger failed with multiple errors,see logs”错误提示
则删除Hbuilder-Hello这个目录里将AndroidManIfest.xml配置了小米推送和小米登录的信息,这个不删掉一定会导致运行报错
1-2) 在真机运行,运行不了,但也不报错,可以考虑离线打包测试(这个错误在离线打包时才显示)
Error:(2) Error: "app_name" is not translated in "zh" (Chinese) [MissingTranslation]

   答:  在build.gradle文件中添加:  
            android{  
             ...  
             lintOptions{  
                  checkReleaseBuilds false  
                  abortOnError false  
                }  

             }  

此时,真机运行成功,替换HBuilder中的前端项目到As环境中
2) 替换\Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\src\main\assets\apps\HelloH5\www目录下内容为新项目NewProject前端内容
直接运行查看效果
3) 如果再次运行时会报错,此时将HBuilder-Hello下\assets\apps\HelloH5\www中的manifest.json替换成原项目中的manifest.json内容,再次运行查看
4) 修改启动图片和应用图标: \Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\build\intermediates\res\merged\release\
可通过drawable-XXXhdpi文件名查询对应尺寸(可参考: http://blog.csdn.net/gf771115/article/details/50323635)

5) 修改应用名称: \Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\src\main\res\values\strings.html
结束。

继续阅读 »

1) 导入项目官网下载的HBuilder离线打包Android版SDK(5+ SDK下载)中项目\Android-SDK@1.9.9.38184_20171023\HBuilder-Hello
1-1) 出现“manifest merger failed with multiple errors,see logs”错误提示
则删除Hbuilder-Hello这个目录里将AndroidManIfest.xml配置了小米推送和小米登录的信息,这个不删掉一定会导致运行报错
1-2) 在真机运行,运行不了,但也不报错,可以考虑离线打包测试(这个错误在离线打包时才显示)
Error:(2) Error: "app_name" is not translated in "zh" (Chinese) [MissingTranslation]

   答:  在build.gradle文件中添加:  
            android{  
             ...  
             lintOptions{  
                  checkReleaseBuilds false  
                  abortOnError false  
                }  

             }  

此时,真机运行成功,替换HBuilder中的前端项目到As环境中
2) 替换\Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\src\main\assets\apps\HelloH5\www目录下内容为新项目NewProject前端内容
直接运行查看效果
3) 如果再次运行时会报错,此时将HBuilder-Hello下\assets\apps\HelloH5\www中的manifest.json替换成原项目中的manifest.json内容,再次运行查看
4) 修改启动图片和应用图标: \Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\build\intermediates\res\merged\release\
可通过drawable-XXXhdpi文件名查询对应尺寸(可参考: http://blog.csdn.net/gf771115/article/details/50323635)

5) 修改应用名称: \Android-SDK@1.9.9.38184_20171023\HBuilder-gm\app\src\main\res\values\strings.html
结束。

收起阅读 »

Android7解决plus.runtime.openFile方法打开文件无响应问题(需本地打包并修改SDK)

离线打包 5+sdk

需修改的类:pdr.jar\io\dcloud\common\adapter\util\PlatformUtil.class

具体方法请参见:解决 Android N 7.0 上 报错:android.os.FileUriExposedException

另外调试中还发现一个问题:

** PLEASE READ ****

  • New versions of the Android SDK no longer support the Crypto provider.
  • If your app was relying on setSeed() to derive keys from strings, you
  • should switch to using SecretKeySpec to load raw key bytes directly OR
  • use a real key derivation function (KDF). See advice here :
  • http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html


此问题的解决请参见:Android:7.0 后加密库 Crypto 被废弃后的爬坑指南
需修改的类:pdr.jar\io\dcloud\common\adapter\util\DCloudTrustManager.class

希望dcloud团队能更新此类问题

继续阅读 »

需修改的类:pdr.jar\io\dcloud\common\adapter\util\PlatformUtil.class

具体方法请参见:解决 Android N 7.0 上 报错:android.os.FileUriExposedException

另外调试中还发现一个问题:

** PLEASE READ ****

  • New versions of the Android SDK no longer support the Crypto provider.
  • If your app was relying on setSeed() to derive keys from strings, you
  • should switch to using SecretKeySpec to load raw key bytes directly OR
  • use a real key derivation function (KDF). See advice here :
  • http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html


此问题的解决请参见:Android:7.0 后加密库 Crypto 被废弃后的爬坑指南
需修改的类:pdr.jar\io\dcloud\common\adapter\util\DCloudTrustManager.class

希望dcloud团队能更新此类问题

收起阅读 »

有偿找一个会做前端加PHP写后台外包

来一个会做前端加PHP写后台外包

一个前端加 PHP后台!联系QQ 1120094610

速度要快的,有经验的,

来一个会做前端加PHP写后台外包

一个前端加 PHP后台!联系QQ 1120094610

速度要快的,有经验的,

消息推送 - wap2app教程

推送 wap2app

wap2app应用目前支持集成个推平台,可以向用户发送推送消息。

wap2app的推送开发,分为三个部分:

  1. 个推平台申请账号及应用登记,获取应用的appid、appkey、appsecret参数;
  2. 本地manifest.json中配置推送权限及个推参数
  3. 本地app.js中编写推送消息监听代码

其中,前两项和5+ App的配置方法相同,参考推送插件开发指南即可,其中有推送原理的详细说明;为了便于理解,这里再次简述一下推送的相关概念。

推送概念简述

推送消息分为普通推送和透传推送,区别在于:

  • 普通推送只有消息标题和消息内容;
  • 透传消息除了消息标题、消息内容外,还有payload字段,payload是一个json对象,可以包含业务自定义参数,比如新闻ID等。

wap2app应用支持click、receive两种事件监听推送消息,主要区别在于:

  • 进入手机消息中心的推送,用户点击后触发click事件
  • 透传消息不符合规范或iOS应用正处于前台运行时收到推送,此时消息不会进入手机消息中心,而会直接触发receive事件。

Tips:Android平台的普通消息会进入消息中心,但用户点击后仅激活应用,不会触发click事件。

为了完整实现,需要在代码中同时监听click事件和receive事件。

wap2app中的推送监听

wap2app应用需要在app.js的onLaunch事件中监听推送消息,本示例接收透传消息,透传消息中包含新闻ID,用户点击推送消息后,直接打开新闻详情,实现消息直达的需求;推送内容如下:

{title:"推送标题",content:"推送内容",payload:{id:1001}}

示例代码如下:

/**  
 * 当wap2app初始化完成时,会触发 onLaunch  
 * @param {Object} options  
 */  
onLaunch: function (options) {  
  //应用初始化  

  /******推送消息监听代码开始******/  

  //监听click事件,用户从消息中心点击触发的  
  plus.push.addEventListener("click", function (msg) {  
    console.log("You clicked: " + msg.title); //推送消息标题  
    console.log("You clicked: " + msg.content); //推送消息内容  
    //根据payload传递过来的数据,打开一个详情  
    var payload = msg.payload;  
    if (payload) {  
      // payload 按照规范是 Object,但实际推送过来有可能是 String,需要多一步处理;  
      if (typeof payload === 'string') {  
        payload = JSON.parse(payload);  
      }  
      if (typeof payload === 'object') {  
        //payload是一个json对象,可以传递业务数据,开发者可以根据实际需求自定义参数  
        //本示例在payload中传入新闻id,wap2app接收到推送后,直接打开新闻详情  
        var detailId = payload.id;  
        //wap2app.open(url)可以直接打开对应的webview  
        //这里是示例,实际项目中开发者需根据M站的url拼接页面地址  
        wap2app.open('https://m.example.com/detial/' + detailId + '.html');  
      }  
    }  
  }, false);  

  //监听receive事件  
  plus.push.addEventListener("receive", function (msg) {  
    console.log("recieve title: " + msg.title); //推送消息标题  
    console.log("recieve content: " + msg.content); //推送消息内容  
    //根据payload传递过来的数据,打开一个详情  
    var payload;  
    if (msg.payload) {  
      //如透传消息不符合格式,则“payload”属性为string类型  
      //这里的示例以json字符串去解析,实际上也可以做字符串匹配  
      if (typeof (msg.payload) == "string") {  
        try {  
          payload = JSON.parse(msg.payload);  
        } catch (error) {  
          console.log(error);  
        }  
      } else if (typeof (msg.payload) == "object") {  
        //iOS应用正处于前台运行时收到推送,也触发receive事件,此时payload为json对象  
        payload = msg.payload;  
      }  

      if (payload) {  
        //本示例在payload中传入新闻id,wap2app接收到推送后,直接打开新闻详情  
        var detailId = payload.id;  
        //wap2app.open(url)可以直接打开对应的webview  
        //这里是示例,实际项目中开发者需根据M站的url拼接页面地址  
        wap2app.open('https://m.example.com/detial/' + detailId + '.html');  
      }  
    }  

  }, false);  

  /******推送消息监听代码结束******/  
}
继续阅读 »

wap2app应用目前支持集成个推平台,可以向用户发送推送消息。

wap2app的推送开发,分为三个部分:

  1. 个推平台申请账号及应用登记,获取应用的appid、appkey、appsecret参数;
  2. 本地manifest.json中配置推送权限及个推参数
  3. 本地app.js中编写推送消息监听代码

其中,前两项和5+ App的配置方法相同,参考推送插件开发指南即可,其中有推送原理的详细说明;为了便于理解,这里再次简述一下推送的相关概念。

推送概念简述

推送消息分为普通推送和透传推送,区别在于:

  • 普通推送只有消息标题和消息内容;
  • 透传消息除了消息标题、消息内容外,还有payload字段,payload是一个json对象,可以包含业务自定义参数,比如新闻ID等。

wap2app应用支持click、receive两种事件监听推送消息,主要区别在于:

  • 进入手机消息中心的推送,用户点击后触发click事件
  • 透传消息不符合规范或iOS应用正处于前台运行时收到推送,此时消息不会进入手机消息中心,而会直接触发receive事件。

Tips:Android平台的普通消息会进入消息中心,但用户点击后仅激活应用,不会触发click事件。

为了完整实现,需要在代码中同时监听click事件和receive事件。

wap2app中的推送监听

wap2app应用需要在app.js的onLaunch事件中监听推送消息,本示例接收透传消息,透传消息中包含新闻ID,用户点击推送消息后,直接打开新闻详情,实现消息直达的需求;推送内容如下:

{title:"推送标题",content:"推送内容",payload:{id:1001}}

示例代码如下:

/**  
 * 当wap2app初始化完成时,会触发 onLaunch  
 * @param {Object} options  
 */  
onLaunch: function (options) {  
  //应用初始化  

  /******推送消息监听代码开始******/  

  //监听click事件,用户从消息中心点击触发的  
  plus.push.addEventListener("click", function (msg) {  
    console.log("You clicked: " + msg.title); //推送消息标题  
    console.log("You clicked: " + msg.content); //推送消息内容  
    //根据payload传递过来的数据,打开一个详情  
    var payload = msg.payload;  
    if (payload) {  
      // payload 按照规范是 Object,但实际推送过来有可能是 String,需要多一步处理;  
      if (typeof payload === 'string') {  
        payload = JSON.parse(payload);  
      }  
      if (typeof payload === 'object') {  
        //payload是一个json对象,可以传递业务数据,开发者可以根据实际需求自定义参数  
        //本示例在payload中传入新闻id,wap2app接收到推送后,直接打开新闻详情  
        var detailId = payload.id;  
        //wap2app.open(url)可以直接打开对应的webview  
        //这里是示例,实际项目中开发者需根据M站的url拼接页面地址  
        wap2app.open('https://m.example.com/detial/' + detailId + '.html');  
      }  
    }  
  }, false);  

  //监听receive事件  
  plus.push.addEventListener("receive", function (msg) {  
    console.log("recieve title: " + msg.title); //推送消息标题  
    console.log("recieve content: " + msg.content); //推送消息内容  
    //根据payload传递过来的数据,打开一个详情  
    var payload;  
    if (msg.payload) {  
      //如透传消息不符合格式,则“payload”属性为string类型  
      //这里的示例以json字符串去解析,实际上也可以做字符串匹配  
      if (typeof (msg.payload) == "string") {  
        try {  
          payload = JSON.parse(msg.payload);  
        } catch (error) {  
          console.log(error);  
        }  
      } else if (typeof (msg.payload) == "object") {  
        //iOS应用正处于前台运行时收到推送,也触发receive事件,此时payload为json对象  
        payload = msg.payload;  
      }  

      if (payload) {  
        //本示例在payload中传入新闻id,wap2app接收到推送后,直接打开新闻详情  
        var detailId = payload.id;  
        //wap2app.open(url)可以直接打开对应的webview  
        //这里是示例,实际项目中开发者需根据M站的url拼接页面地址  
        wap2app.open('https://m.example.com/detial/' + detailId + '.html');  
      }  
    }  

  }, false);  

  /******推送消息监听代码结束******/  
}
收起阅读 »