HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

【公告】关于HBuilder 7.6.3中Android4.4以下软键盘闪退,子webview切换异常,iOS关闭子窗口导致应用卡死等问题的解决办法

公告

Android

软键盘闪退

HBuilder 7.6.3版真机调试,Android4.4以下设备,表单元素如input,点击获取焦点后软键盘出现立刻收回,再次点击无法弹出。

子窗口切换异常

Android平台下,父子webview模式。子webview首次显示,先全屏显示然后styles变化。

控制台信息

控制太多出的信息,是底层的日志信息,并不是bug,新的apk不会再出现这些日志信息。

iOS

关闭子窗口导致应用卡死

iOS父子webview模式下,关闭子窗口导致应用卡死。

解决办法

Alpha版HBuilder已修复以上问题,请更新或下载最新版Alpha版HBuilder。
下载地址: http://pan.baidu.com/s/1hs0O4eS#list/path=%2F&parentPath=%2Falpha%3Fqq-pf-to

7.6.5.201612262256-alpha 版本更新日志:
【重要】更新高德地图、百度地图、微信等第三SDK,支持https连接
Android平台修复获取设备屏幕逻辑分辨率不准确的问题
Android平台修复Webview作为子窗口使用fade-in动画效果显示不正常的问题
Android平台修复调用微信登录可能无法触发回调的问题
iOS平台补齐讯飞语音支持设置识别语言、标点符号功能
iOS平台修复关闭子Webview窗口可能导致页面卡死的问题
iOS平台修复个推发送透传消息启动可能导致异常退出的问题

继续阅读 »

Android

软键盘闪退

HBuilder 7.6.3版真机调试,Android4.4以下设备,表单元素如input,点击获取焦点后软键盘出现立刻收回,再次点击无法弹出。

子窗口切换异常

Android平台下,父子webview模式。子webview首次显示,先全屏显示然后styles变化。

控制台信息

控制太多出的信息,是底层的日志信息,并不是bug,新的apk不会再出现这些日志信息。

iOS

关闭子窗口导致应用卡死

iOS父子webview模式下,关闭子窗口导致应用卡死。

解决办法

Alpha版HBuilder已修复以上问题,请更新或下载最新版Alpha版HBuilder。
下载地址: http://pan.baidu.com/s/1hs0O4eS#list/path=%2F&parentPath=%2Falpha%3Fqq-pf-to

7.6.5.201612262256-alpha 版本更新日志:
【重要】更新高德地图、百度地图、微信等第三SDK,支持https连接
Android平台修复获取设备屏幕逻辑分辨率不准确的问题
Android平台修复Webview作为子窗口使用fade-in动画效果显示不正常的问题
Android平台修复调用微信登录可能无法触发回调的问题
iOS平台补齐讯飞语音支持设置识别语言、标点符号功能
iOS平台修复关闭子Webview窗口可能导致页面卡死的问题
iOS平台修复个推发送透传消息启动可能导致异常退出的问题

收起阅读 »

解析XML文件

之前一直用json格式,后来接口边XML,发现解析也方便:

var xmlDoc=new DOMParser().parseFromString(jsonStr, "text/xml");
var desc = xmlDoc.getElementsByTagName("desc")[0].firstChild.nodeValue;
var flag = xmlDoc.getElementsByTagName("flag")[0].firstChild.nodeValue;

继续阅读 »

之前一直用json格式,后来接口边XML,发现解析也方便:

var xmlDoc=new DOMParser().parseFromString(jsonStr, "text/xml");
var desc = xmlDoc.getElementsByTagName("desc")[0].firstChild.nodeValue;
var flag = xmlDoc.getElementsByTagName("flag")[0].firstChild.nodeValue;

收起阅读 »

文字合成语音的实现

Native.JS 文字转语音 语音朗读 TTS

HBuilder版本号为7.6.3.201612161809及之后的用户请用如下Native.Js代码实现:

var receiver;  

                receiver = plus.android.implements('com.iflytek.cloud.SynthesizerListener', {  
                    onEvent: function(int eventType, int arg1, int arg2, Bundle obj) {  
                        console.log("onEvent");  
                    },  
                    onSpeakBegin: function() {  
                        console.log("开始阅读");  
                    },  
                    onSpeakPaused: function() {  
                        console.log(" 暂停播放 ");  
                    },  
                    onSpeakResumed: function() {  
                        console.log("继续播放");  
                    },  
                    onBufferProgress: function(percent, beginPos, endPos, info) {  
                        console.log("合成进度" + percent);  
                    },  
                    onSpeakProgress: function(percent, beginPos, endPos) {  
                        console.log("播放进度" + percent);  
                    },  
                    onCompleted: function(error) {  
                        console.log("播放完毕");  
                    }  
                });  

                var main = plus.android.runtimeMainActivity();  

                var SpeechUtility = plus.android.importClass('com.iflytek.cloud.SpeechUtility');  

                SpeechUtility.createUtility(main, "appid=53feacdd");  

                var SynthesizerPlayer = plus.android.importClass('com.iflytek.cloud.SpeechSynthesizer');  

                var play = SynthesizerPlayer.createSynthesizer(main, null);  
                 // 开始合成  
                play.startSpeaking('新年快乐', receiver);  
        // 取消合成  
        play.stopSpeaking();  
        // 暂停播放  
        play.pauseSpeaking();  
        // 继续播放  
        play.resumeSpeaking();

该版本之前的用户请参考下面的写法:
由于Android系统tts不支持中文,使用科大讯飞文字转语音功能,使用如此功能时,需要保证manifest.json中permissions节点含有speech节点(如"Speech": {"description": "管理语音识别插件" })。

var main = plus.android.runtimeMainActivity();  
var SynthesizerPlayer = plus.android.importClass('com.iflytek.speech.SynthesizerPlayer');  
var play = SynthesizerPlayer.createSynthesizerPlayer(main,'appid=53feacdd');  
play.playText('水果',null,null);

iOS平台参考[http://ask.dcloud.net.cn/question/4175)(http://ask.dcloud.net.cn/question/4175)

继续阅读 »

HBuilder版本号为7.6.3.201612161809及之后的用户请用如下Native.Js代码实现:

var receiver;  

                receiver = plus.android.implements('com.iflytek.cloud.SynthesizerListener', {  
                    onEvent: function(int eventType, int arg1, int arg2, Bundle obj) {  
                        console.log("onEvent");  
                    },  
                    onSpeakBegin: function() {  
                        console.log("开始阅读");  
                    },  
                    onSpeakPaused: function() {  
                        console.log(" 暂停播放 ");  
                    },  
                    onSpeakResumed: function() {  
                        console.log("继续播放");  
                    },  
                    onBufferProgress: function(percent, beginPos, endPos, info) {  
                        console.log("合成进度" + percent);  
                    },  
                    onSpeakProgress: function(percent, beginPos, endPos) {  
                        console.log("播放进度" + percent);  
                    },  
                    onCompleted: function(error) {  
                        console.log("播放完毕");  
                    }  
                });  

                var main = plus.android.runtimeMainActivity();  

                var SpeechUtility = plus.android.importClass('com.iflytek.cloud.SpeechUtility');  

                SpeechUtility.createUtility(main, "appid=53feacdd");  

                var SynthesizerPlayer = plus.android.importClass('com.iflytek.cloud.SpeechSynthesizer');  

                var play = SynthesizerPlayer.createSynthesizer(main, null);  
                 // 开始合成  
                play.startSpeaking('新年快乐', receiver);  
        // 取消合成  
        play.stopSpeaking();  
        // 暂停播放  
        play.pauseSpeaking();  
        // 继续播放  
        play.resumeSpeaking();

该版本之前的用户请参考下面的写法:
由于Android系统tts不支持中文,使用科大讯飞文字转语音功能,使用如此功能时,需要保证manifest.json中permissions节点含有speech节点(如"Speech": {"description": "管理语音识别插件" })。

var main = plus.android.runtimeMainActivity();  
var SynthesizerPlayer = plus.android.importClass('com.iflytek.speech.SynthesizerPlayer');  
var play = SynthesizerPlayer.createSynthesizerPlayer(main,'appid=53feacdd');  
play.playText('水果',null,null);

iOS平台参考[http://ask.dcloud.net.cn/question/4175)(http://ask.dcloud.net.cn/question/4175)

收起阅读 »

app开发视频教程 - 用户注册、登录、微信登录(完全免费 精细讲解 欢迎 学习) 还有mui、h5+教程都是免费的 快来学习吧

移动APP

《app开发教程-用户注册、登录、微信登录》视频教程已经更新完毕,涵盖了用户注册、登录、微信登录等相关知识点的详细讲解,欢迎观看学习!观看地址
http://www.hcoder.net/course

交流qq群 335126794 欢迎加入

继续阅读 »

《app开发教程-用户注册、登录、微信登录》视频教程已经更新完毕,涵盖了用户注册、登录、微信登录等相关知识点的详细讲解,欢迎观看学习!观看地址
http://www.hcoder.net/course

交流qq群 335126794 欢迎加入

收起阅读 »

7.6.3.201612161809版本更新后Android多数机器出现输入法弹出后消失问题

输入法 Android

7.6.3.201612161809更新后
测试多个机型同时出现,点击文本框之后输入法弹出,马上又消失的问题,只存在于Android机型
新建空白项目或者新建MUI的demo项目问题同样存在,所以猜测云端打包是否更新后有问题,
如果确定存在问题,希望可以快一点更新解决, 0.0

继续阅读 »

7.6.3.201612161809更新后
测试多个机型同时出现,点击文本框之后输入法弹出,马上又消失的问题,只存在于Android机型
新建空白项目或者新建MUI的demo项目问题同样存在,所以猜测云端打包是否更新后有问题,
如果确定存在问题,希望可以快一点更新解决, 0.0

收起阅读 »

分享一个多页面倒计时60秒防止刷新的按钮+沉浸式状态栏js

沉浸式状态栏
var DA = {  
    navStyle:function (color){//状态栏样式,参数(颜色),在ios7和android4.0以上有效  

        plus.navigator.setStatusBarBackground(color);  
        plus.navigator.setStatusBarStyle('UIStatusBarStyleBlackOpaque')  

   },  
    timeInit:function(btn_name){//初始化验证码按钮倒计时状态和设置当前页面的本地存储name  
        var countdown = localStorage.getItem(''+btn_name+'');  

        if(countdown == null||countdown == "0"){  
            $("#code_btn").html("获取验证码");  
            $("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'});  
            localStorage.removeItem(''+btn_name+'');  
        }else if(countdown !== "0"){  

            $("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})  
            $("#code_btn").html("重新发送 ( " + countdown + " )");  

            this.timedown(''+btn_name+'');  
        }  
    },  

    timedown:function(btn_name){//倒计时定时器  
        var countdowns;  
        countdown = localStorage.getItem(''+btn_name+'');  

        if (countdown == '0') {  
            $("#code_btn").html("获取验证码");  
            $("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'})  
            return clearTimeout();//清除定时,没有的话会导致后面每次减一越来越快  
        } else {  
            $("#code_btn").html("重新发送 ( " + countdown + " )");  
            $("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})  
            countdown = countdown - 1;  
            localStorage.setItem(''+btn_name+'',countdown);  
        }  
        setTimeout(function() {  

            DA.timedown(''+btn_name+'')  

        }, 1000);//定时每秒减一  
    },  

    settime:function (btn_name){//点击获取手机号码,判断手机号码,执行此函数  
        var phone = document.getElementById("phone");//判断是否是input,根据自己的逻辑来玩  
        if(phone.tagName.toLocaleLowerCase() == 'input'){  
            var check_phone_number = /^1[3458]\d{9}$/;  
            if (phone.value.length == '') {  
                DA.X_toast("手机号不能为空",'error.png',1000)  
                return;  
            }  
            if (phone.value.length != 11) {  
                DA.X_toast("请输入有效的手机号!",'error.png',1000)  
                return;  
            }  
            if (!phone.value.match(check_phone_number)) {  
                DA.X_toast("请输入有效的手机号",'error.png',1000)  
                return;  
            } else {  
                //短信发送,根据自己逻辑异步获取验证码  
                localStorage.setItem(''+btn_name+'','10');  
                this.timedown(''+btn_name+'');  
            }  
        }else{  
        //短信发送,根据自己逻辑异步获取验证码  

            localStorage.setItem(''+btn_name+'','10');  
            this.timedown(''+btn_name+'');  
        }  
    }  

}  

  function plusReady(){  
        // 设置系统状态栏样式为浅色文字  
        DA.navStyle('#000000');  
        //localStorage.removeItem('LoginToken')//清除键值对  
        //localStorage.setItem('LoginToken','123456')//设置键值对  
        var LoginToken;   

        //console.log(LoginToken);  

        $('.content_divs').on('tap',function(){  
                LoginToken = localStorage.getItem("LoginToken");  
                var _self = $(this);  
                var url = _self.attr('data-url');  
                switch(url)  
                    {  
                    case 'Pay_record_head.html':  
                        DA.open(url,'right');  
                      break;  
                    case 'my_assets_head.html':  
                      DA.open(url,'right');  
                      break;  
                    default:  
                        LoginToken == null?(url = 'login.html',DA.open(url,'right')):DA.open(url,'right');  
                    }  
            })  
    }  
    if(window.plus){  
        plusReady();  
    }else{  
        document.addEventListener("plusready",plusReady,false);  
    }
继续阅读 »
var DA = {  
    navStyle:function (color){//状态栏样式,参数(颜色),在ios7和android4.0以上有效  

        plus.navigator.setStatusBarBackground(color);  
        plus.navigator.setStatusBarStyle('UIStatusBarStyleBlackOpaque')  

   },  
    timeInit:function(btn_name){//初始化验证码按钮倒计时状态和设置当前页面的本地存储name  
        var countdown = localStorage.getItem(''+btn_name+'');  

        if(countdown == null||countdown == "0"){  
            $("#code_btn").html("获取验证码");  
            $("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'});  
            localStorage.removeItem(''+btn_name+'');  
        }else if(countdown !== "0"){  

            $("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})  
            $("#code_btn").html("重新发送 ( " + countdown + " )");  

            this.timedown(''+btn_name+'');  
        }  
    },  

    timedown:function(btn_name){//倒计时定时器  
        var countdowns;  
        countdown = localStorage.getItem(''+btn_name+'');  

        if (countdown == '0') {  
            $("#code_btn").html("获取验证码");  
            $("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'})  
            return clearTimeout();//清除定时,没有的话会导致后面每次减一越来越快  
        } else {  
            $("#code_btn").html("重新发送 ( " + countdown + " )");  
            $("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})  
            countdown = countdown - 1;  
            localStorage.setItem(''+btn_name+'',countdown);  
        }  
        setTimeout(function() {  

            DA.timedown(''+btn_name+'')  

        }, 1000);//定时每秒减一  
    },  

    settime:function (btn_name){//点击获取手机号码,判断手机号码,执行此函数  
        var phone = document.getElementById("phone");//判断是否是input,根据自己的逻辑来玩  
        if(phone.tagName.toLocaleLowerCase() == 'input'){  
            var check_phone_number = /^1[3458]\d{9}$/;  
            if (phone.value.length == '') {  
                DA.X_toast("手机号不能为空",'error.png',1000)  
                return;  
            }  
            if (phone.value.length != 11) {  
                DA.X_toast("请输入有效的手机号!",'error.png',1000)  
                return;  
            }  
            if (!phone.value.match(check_phone_number)) {  
                DA.X_toast("请输入有效的手机号",'error.png',1000)  
                return;  
            } else {  
                //短信发送,根据自己逻辑异步获取验证码  
                localStorage.setItem(''+btn_name+'','10');  
                this.timedown(''+btn_name+'');  
            }  
        }else{  
        //短信发送,根据自己逻辑异步获取验证码  

            localStorage.setItem(''+btn_name+'','10');  
            this.timedown(''+btn_name+'');  
        }  
    }  

}  

  function plusReady(){  
        // 设置系统状态栏样式为浅色文字  
        DA.navStyle('#000000');  
        //localStorage.removeItem('LoginToken')//清除键值对  
        //localStorage.setItem('LoginToken','123456')//设置键值对  
        var LoginToken;   

        //console.log(LoginToken);  

        $('.content_divs').on('tap',function(){  
                LoginToken = localStorage.getItem("LoginToken");  
                var _self = $(this);  
                var url = _self.attr('data-url');  
                switch(url)  
                    {  
                    case 'Pay_record_head.html':  
                        DA.open(url,'right');  
                      break;  
                    case 'my_assets_head.html':  
                      DA.open(url,'right');  
                      break;  
                    default:  
                        LoginToken == null?(url = 'login.html',DA.open(url,'right')):DA.open(url,'right');  
                    }  
            })  
    }  
    if(window.plus){  
        plusReady();  
    }else{  
        document.addEventListener("plusready",plusReady,false);  
    }
收起阅读 »

【示例】Android及iOS平台下视频全屏播放时自动横屏的实现

技术分享 Webview 5+sdk 5+App开发 HTML5+ video

需求明确

视频全屏播放时,屏幕自动旋转为横屏。
此类功能,手机内置浏览器以及UC浏览器等,均有不同的实现。
若需要更多功能的定制,需自行扩展插件。

思路

首先,明确不同平台下的全屏事件,也就是所需监听的全屏变化的事件。
Android和iOS平台下,事件存在较大的差异。

其次,根据实际业务需求,对屏幕方向做出相应的调整。
此例中的处理方式为:
视频全屏,即锁定屏幕为横屏。
视频恢复,则解除屏幕方向的锁定。

具体实现

Android

1.常规处理
监听webkitfullscreenchange事件,并且读取全屏元素,对屏幕方向做出调整。

document.addEventListener('webkitfullscreenchange', function() {  
    var el = document.webkitFullscreenElement; //获取全屏元素  
    if(el) {  
        plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏  
    } else {  
        plus.screen.unlockOrientation(); //解除屏幕方向的锁定  
    }  
});

2.WebviewStyles.videoFullscreen
HBuilder7.6.3.201612161809更新日志的App项中:
“Android平台优化视频全屏旋转效果,增加WebviewStyles.videoFullscreen控制”
意味着我们可以使用更加方便和性能更高的方法实现该功能

var self = plus.webview.currentWebview();  
self.setStyle({  
    videoFullscreen: 'landscape'  
});

iOS

监听video元素的webkitbeginfullscreen与webkitendfullscreen事件,在全屏开始和结束时,对屏幕方向做相应的调整。

// 监听的事件与Android平台有很大区别  
videoElem.addEventListener('webkitbeginfullscreen', function() {  
    plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏  
});  
videoElem.addEventListener('webkitendfullscreen', function() {  
//  plus.screen.unlockOrientation(); //解除屏幕方向的锁定,但是不一定是竖屏;  
    plus.screen.lockOrientation('portrait'); //锁死屏幕方向为竖屏  
});

相关API

设备屏幕信息
原生窗口设置参数的对象
HTML 5+ SDK 更新日志

涉及全屏播放并且需要打包成原生安装包的开发者请注意:

全屏播放涉及屏幕旋转,在iOS上实现此效果则需要在manifest.json中plus -> distribute -> orientation 节点配置应用支持的方向,默认是只支持竖屏正方向。

"orientation": [  
                "portrait-primary"  
            ],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/

源码

附上源码,解压后放在App工程中,运行即可。

继续阅读 »

需求明确

视频全屏播放时,屏幕自动旋转为横屏。
此类功能,手机内置浏览器以及UC浏览器等,均有不同的实现。
若需要更多功能的定制,需自行扩展插件。

思路

首先,明确不同平台下的全屏事件,也就是所需监听的全屏变化的事件。
Android和iOS平台下,事件存在较大的差异。

其次,根据实际业务需求,对屏幕方向做出相应的调整。
此例中的处理方式为:
视频全屏,即锁定屏幕为横屏。
视频恢复,则解除屏幕方向的锁定。

具体实现

Android

1.常规处理
监听webkitfullscreenchange事件,并且读取全屏元素,对屏幕方向做出调整。

document.addEventListener('webkitfullscreenchange', function() {  
    var el = document.webkitFullscreenElement; //获取全屏元素  
    if(el) {  
        plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏  
    } else {  
        plus.screen.unlockOrientation(); //解除屏幕方向的锁定  
    }  
});

2.WebviewStyles.videoFullscreen
HBuilder7.6.3.201612161809更新日志的App项中:
“Android平台优化视频全屏旋转效果,增加WebviewStyles.videoFullscreen控制”
意味着我们可以使用更加方便和性能更高的方法实现该功能

var self = plus.webview.currentWebview();  
self.setStyle({  
    videoFullscreen: 'landscape'  
});

iOS

监听video元素的webkitbeginfullscreen与webkitendfullscreen事件,在全屏开始和结束时,对屏幕方向做相应的调整。

// 监听的事件与Android平台有很大区别  
videoElem.addEventListener('webkitbeginfullscreen', function() {  
    plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏  
});  
videoElem.addEventListener('webkitendfullscreen', function() {  
//  plus.screen.unlockOrientation(); //解除屏幕方向的锁定,但是不一定是竖屏;  
    plus.screen.lockOrientation('portrait'); //锁死屏幕方向为竖屏  
});

相关API

设备屏幕信息
原生窗口设置参数的对象
HTML 5+ SDK 更新日志

涉及全屏播放并且需要打包成原生安装包的开发者请注意:

全屏播放涉及屏幕旋转,在iOS上实现此效果则需要在manifest.json中plus -> distribute -> orientation 节点配置应用支持的方向,默认是只支持竖屏正方向。

"orientation": [  
                "portrait-primary"  
            ],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/

源码

附上源码,解压后放在App工程中,运行即可。

收起阅读 »

app开发实战 - 《用户注册、登录》视频教程发布!

5+App开发

app开发实战视频教程 - 《用户注册、登录》视频教程已经发布,持续更新(本周内完结)。完结后发布第三方登录教程。
教程完全免费!观看地址
http://www.hcoder.net/course

还有mui、h5+、新闻客户端实战教程 都在这个页面上,欢迎观看!

继续阅读 »

app开发实战视频教程 - 《用户注册、登录》视频教程已经发布,持续更新(本周内完结)。完结后发布第三方登录教程。
教程完全免费!观看地址
http://www.hcoder.net/course

还有mui、h5+、新闻客户端实战教程 都在这个页面上,欢迎观看!

收起阅读 »

流应用引擎SDK

SDK 流应用

流应用引擎SDK是为流应用的发行渠道,如应用市场、浏览器、桌面、语音助手、扫码工具、清理替换、广告sdk、推送sdk等,通过集成DCloud的流应用引擎SDK,可在自己的产品中发行流应用。

每个流应用都有一个唯一的appid,发行渠道集成了流应用引擎SDK后,调起流应用引擎SDK时传入指定的appid,即可启动该流应用。

Android平台流应用引擎SDK

下载流应用引擎SDK集成文档
下载最新版本流应用引擎SDK

2017-11-30发布

更新日志

  1. 适配全面屏手机。
  2. 支持辅助输入。
  3. 修复在Android7上启动应用闪一下桌面的问题(需将io.dcloud.appstream.StreamAppMainActivity的主题样式设置为"@android:style/Theme.NoDisplay")。
  4. 同步更新流应用内核:修复一些已知的BUG等。
    下载流应用引擎SDK

2017-11-20发布

更新日志

  1. 修复部分手机沉浸式离线集成无效的问题。
  2. 修复单页面集成模式下,无法加载远程网页的问题。
  3. 修复已存在地图页面的情况下,创建打开另一个webview页面只显示空白的问题
  4. 同步更新流应用内核:修复一些已知的BUG等
    下载流应用引擎SDK

下载流应用引擎SDK集成文档
下载最新版本流应用引擎SDK

继续阅读 »

流应用引擎SDK是为流应用的发行渠道,如应用市场、浏览器、桌面、语音助手、扫码工具、清理替换、广告sdk、推送sdk等,通过集成DCloud的流应用引擎SDK,可在自己的产品中发行流应用。

每个流应用都有一个唯一的appid,发行渠道集成了流应用引擎SDK后,调起流应用引擎SDK时传入指定的appid,即可启动该流应用。

Android平台流应用引擎SDK

下载流应用引擎SDK集成文档
下载最新版本流应用引擎SDK

2017-11-30发布

更新日志

  1. 适配全面屏手机。
  2. 支持辅助输入。
  3. 修复在Android7上启动应用闪一下桌面的问题(需将io.dcloud.appstream.StreamAppMainActivity的主题样式设置为"@android:style/Theme.NoDisplay")。
  4. 同步更新流应用内核:修复一些已知的BUG等。
    下载流应用引擎SDK

2017-11-20发布

更新日志

  1. 修复部分手机沉浸式离线集成无效的问题。
  2. 修复单页面集成模式下,无法加载远程网页的问题。
  3. 修复已存在地图页面的情况下,创建打开另一个webview页面只显示空白的问题
  4. 同步更新流应用内核:修复一些已知的BUG等
    下载流应用引擎SDK

下载流应用引擎SDK集成文档
下载最新版本流应用引擎SDK

收起阅读 »

通讯录获取指定的多人信息

mui HTML5+ Contacts 通讯录

首先我要在这里吐槽一下官方文档和问答!!

官方文档实在是太简陋了,要自己做复杂一点点都要自己去摸索,比如获取到了phoneNumbe之后根本没有说还要写value;birthday出来的是number而不是官网上写的Date类型!文档太多槽点不说了。

问答搜索的时候几乎没有我要的信息!!!几乎没有!!!好吧,没有就算了吧,我发表一下提问,然而没几个人可以回复我,发过四个问题,一个解决了,两个没人回答,一个回答还是让我自己解决了。好吧,没人回答就算了,那我百度一下,没什么内容,几乎都是官网的东西,那我google一下吧,还是一个样!!细节内容实在太少了!!做一些简单的app可以,要说复杂的真的是摸着石头过河啊!!!!

吐槽完毕,希望官方可以好好发展一下资料问题,要是没有很好的一份文档以及社区搜索,真的好难吸引太多人,而且用到一半都快要弃用了。。。性能问题我目前还没用遇到过,性能目前来说还是不错的。

正文如下:

一、获取多个人的信息:要解决通讯录导入多个人的信息之前,要解决获取多个人的信息。我通过plus.contacts.getAddressBook和address.find的套用把通讯录里面的所有联系人的id和displayName获取出来,然后通过自己写的通讯录获取页面显示出来。

1、解决这个问题首先你要自己写一个js通讯录,这样可以把你所有联系人首字母分离出来,并且旁边可以跳转到你要的首字母。
资料可以参考我自己写的JS:http://www.cnblogs.com/claireyu1219/p/6131314.html
也可以参考官方的:http://dcloud.io/hellomui/examples/indexed-list.html

2、解决获取所有联系人信息

plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息  
                // 可通过addressbook进行通讯录操作  
                addressbook.find(null, function(contacts) {  
                    var username = new Array();  
                    var LinkList = new LinkedList();  
                    if(contacts.length > 0) { //获取当前通讯录里面所有人  
                        for(var i = 0; i < contacts.length; i  ) {  
                            username[i] = contacts[i].displayName   "-"   contacts[i].id; //连接id和username,为后面筛选最准备  
                        }  
                        //这下面的代码是把所有联系人的信息分类,这就涉及到了自己写的JS页面代码  
                        LinkList = sortPY(username); //把联系人数组分类  
                        //LinkList.show();  
                        createLiCheckBox(LinkList); //分类信息显示至页面,我使用checkBox进行多个联系人选择  
                    }  

                }, function(e) {  
                    alert("Find contact error: "   e.message);  
                });  

            }, function(e) {  

    });

二、从通讯录导入多个选定的个人信息:解决这个问题在先前创建通讯录页面的时候就一定要把联系人的id放在在页面上(使用display隐藏),这样我获取被选中的checkBox的时候就可以直接获取id,并且把这些id放到一个数组里面。再通过plus.contacts.getAddressBook和address.find的套用把这些id的联系人信息筛选出来。

1、解决使用checkBox获取联系人id,这里我使用了JQuery。

//筛选已经被选中的checkbox  
    $("input:checked").each(function() {  
            var index = $(this).parent().prev().children('label').text(); //获取id  
            var name = $(this).parent().prev().children('p').text(); //获取姓名  
            username.push(name);  
            usernameIndex.push(index);  
    });

2、解决把这些index放到find里面进行筛选信息,把特定id下面的联系人信息拿出来

plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息  
            for(var j = 0; j < username.length; j  ) {//循环所选取的联系人,记得循环一定要放在这里,一开始我放在        plus.contacts.getAddressBook外面是错误  
                        addressbook.find(null, function(contacts) {  
                            console.log("进入查询");  
                            for(var i = 0; i < contacts.length; i  ) {//无论是否为多个信息,一定要循环数组  
                                console.log("进入循环");  
                                //var id = contacts[i].id;  
                                var displayname = contacts[i].displayName;  
                                var phone = "";  
                                var emails = "";  
                                var dates = "";  
                                var remark = "";  
                                if(contacts[i].phoneNumbers.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;  
                                    phone = contacts[i].phoneNumbers[0].value;  
                                } else {  
                                    phone = contacts[i].phoneNumbers;  
                                }  

                                if(contacts[i].emails.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;  
                                    emails = contacts[i].emails[0].value;  
                                } else {  
                                    emails = contacts[i].emails;  
                                }  

                                var dateNum = new Date(contacts[i].birthday);//这里的birthday是number类型!!!官方手册坑爹?  
                                dates = dateNum.getFullYear()   "."   (dateNum.getMonth()   1)   "."   dateNum.getDate();  
                                remark = contacts[i].note;  

                                var getContact = {//把所有信息放到一个json里面  
                                    contactName: displayname,  
                                    sex: "",  
                                    department: "",  
                                    positions: "",  
                                    tel: "",  
                                    phone: phone,  
                                    eMail: emails,  
                                    birthday: dates,  
                                    hobby: "",  
                                    remark: remark  
                                };  

                                //这下面是我的业务代码了,这里大家可以写自己的信息  
                                //createContactTable(db);  
                                //InsertContact(db, getContact); //多个信息插入有线程安全的问题出现!!!!!!!  
                            }  
                            //console.log(username.length);                           
                        }, function(e) {  
                            console.log("查询错误");  
                        }, {    
                                                         //这里面的筛选非常重要!!!这样才能选出匹配的信息  
                            filter: [{  
                                logic: "or",  
                                field: "id",  
                                value: usernameIndex[j]  
                            }],  
                            multi: false  
                        });  
                    }  
                }, function(e) {  
                    console.log("打开通讯录错误");  
                });

通过以上代码就可以获取到了多个联系人的信息,大家可以尝试一下。

继续阅读 »

首先我要在这里吐槽一下官方文档和问答!!

官方文档实在是太简陋了,要自己做复杂一点点都要自己去摸索,比如获取到了phoneNumbe之后根本没有说还要写value;birthday出来的是number而不是官网上写的Date类型!文档太多槽点不说了。

问答搜索的时候几乎没有我要的信息!!!几乎没有!!!好吧,没有就算了吧,我发表一下提问,然而没几个人可以回复我,发过四个问题,一个解决了,两个没人回答,一个回答还是让我自己解决了。好吧,没人回答就算了,那我百度一下,没什么内容,几乎都是官网的东西,那我google一下吧,还是一个样!!细节内容实在太少了!!做一些简单的app可以,要说复杂的真的是摸着石头过河啊!!!!

吐槽完毕,希望官方可以好好发展一下资料问题,要是没有很好的一份文档以及社区搜索,真的好难吸引太多人,而且用到一半都快要弃用了。。。性能问题我目前还没用遇到过,性能目前来说还是不错的。

正文如下:

一、获取多个人的信息:要解决通讯录导入多个人的信息之前,要解决获取多个人的信息。我通过plus.contacts.getAddressBook和address.find的套用把通讯录里面的所有联系人的id和displayName获取出来,然后通过自己写的通讯录获取页面显示出来。

1、解决这个问题首先你要自己写一个js通讯录,这样可以把你所有联系人首字母分离出来,并且旁边可以跳转到你要的首字母。
资料可以参考我自己写的JS:http://www.cnblogs.com/claireyu1219/p/6131314.html
也可以参考官方的:http://dcloud.io/hellomui/examples/indexed-list.html

2、解决获取所有联系人信息

plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息  
                // 可通过addressbook进行通讯录操作  
                addressbook.find(null, function(contacts) {  
                    var username = new Array();  
                    var LinkList = new LinkedList();  
                    if(contacts.length > 0) { //获取当前通讯录里面所有人  
                        for(var i = 0; i < contacts.length; i  ) {  
                            username[i] = contacts[i].displayName   "-"   contacts[i].id; //连接id和username,为后面筛选最准备  
                        }  
                        //这下面的代码是把所有联系人的信息分类,这就涉及到了自己写的JS页面代码  
                        LinkList = sortPY(username); //把联系人数组分类  
                        //LinkList.show();  
                        createLiCheckBox(LinkList); //分类信息显示至页面,我使用checkBox进行多个联系人选择  
                    }  

                }, function(e) {  
                    alert("Find contact error: "   e.message);  
                });  

            }, function(e) {  

    });

二、从通讯录导入多个选定的个人信息:解决这个问题在先前创建通讯录页面的时候就一定要把联系人的id放在在页面上(使用display隐藏),这样我获取被选中的checkBox的时候就可以直接获取id,并且把这些id放到一个数组里面。再通过plus.contacts.getAddressBook和address.find的套用把这些id的联系人信息筛选出来。

1、解决使用checkBox获取联系人id,这里我使用了JQuery。

//筛选已经被选中的checkbox  
    $("input:checked").each(function() {  
            var index = $(this).parent().prev().children('label').text(); //获取id  
            var name = $(this).parent().prev().children('p').text(); //获取姓名  
            username.push(name);  
            usernameIndex.push(index);  
    });

2、解决把这些index放到find里面进行筛选信息,把特定id下面的联系人信息拿出来

plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息  
            for(var j = 0; j < username.length; j  ) {//循环所选取的联系人,记得循环一定要放在这里,一开始我放在        plus.contacts.getAddressBook外面是错误  
                        addressbook.find(null, function(contacts) {  
                            console.log("进入查询");  
                            for(var i = 0; i < contacts.length; i  ) {//无论是否为多个信息,一定要循环数组  
                                console.log("进入循环");  
                                //var id = contacts[i].id;  
                                var displayname = contacts[i].displayName;  
                                var phone = "";  
                                var emails = "";  
                                var dates = "";  
                                var remark = "";  
                                if(contacts[i].phoneNumbers.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;  
                                    phone = contacts[i].phoneNumbers[0].value;  
                                } else {  
                                    phone = contacts[i].phoneNumbers;  
                                }  

                                if(contacts[i].emails.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;  
                                    emails = contacts[i].emails[0].value;  
                                } else {  
                                    emails = contacts[i].emails;  
                                }  

                                var dateNum = new Date(contacts[i].birthday);//这里的birthday是number类型!!!官方手册坑爹?  
                                dates = dateNum.getFullYear()   "."   (dateNum.getMonth()   1)   "."   dateNum.getDate();  
                                remark = contacts[i].note;  

                                var getContact = {//把所有信息放到一个json里面  
                                    contactName: displayname,  
                                    sex: "",  
                                    department: "",  
                                    positions: "",  
                                    tel: "",  
                                    phone: phone,  
                                    eMail: emails,  
                                    birthday: dates,  
                                    hobby: "",  
                                    remark: remark  
                                };  

                                //这下面是我的业务代码了,这里大家可以写自己的信息  
                                //createContactTable(db);  
                                //InsertContact(db, getContact); //多个信息插入有线程安全的问题出现!!!!!!!  
                            }  
                            //console.log(username.length);                           
                        }, function(e) {  
                            console.log("查询错误");  
                        }, {    
                                                         //这里面的筛选非常重要!!!这样才能选出匹配的信息  
                            filter: [{  
                                logic: "or",  
                                field: "id",  
                                value: usernameIndex[j]  
                            }],  
                            multi: false  
                        });  
                    }  
                }, function(e) {  
                    console.log("打开通讯录错误");  
                });

通过以上代码就可以获取到了多个联系人的信息,大家可以尝试一下。

收起阅读 »

图片组件 : 单选 多选 预览 删除 数量限制;录音组件 :录音展示 删除 数量限制

demo

媒体列表组件
图片:单选 多选 预览 删除 数量限制
录音:录音展示 删除 数量限制

<body>  
        <div id="imgList"></div>  
        <div id="audioList"></div>  
        <script src="js/mui.min.js"></script>  
        <script type="text/javascript" src="js/md5.min.js" ></script>  
        <script src="js/mui.zoom.js"></script>  
        <script src="js/mui.previewimage.js"></script>  
        <script type="text/javascript" src="js/media_components.js" ></script>  

        <script type="text/javascript">  
            mui.init({  
                gestureConfig: {  
                    longtap: true, //默认为false  
                    hold: true, //默认为false,不监听  
                    release: true //默认为false,不监听  
                }  
            });  
            mui.plusReady(function() {  
                mui('#imgList').imageListInit({  
                    size:5  
                });  
                mui('#audioList').audioListInit({  
                    size:5  
                });  
            });  
        </script>  
    </body>

详细案例见附件

继续阅读 »

demo

媒体列表组件
图片:单选 多选 预览 删除 数量限制
录音:录音展示 删除 数量限制

<body>  
        <div id="imgList"></div>  
        <div id="audioList"></div>  
        <script src="js/mui.min.js"></script>  
        <script type="text/javascript" src="js/md5.min.js" ></script>  
        <script src="js/mui.zoom.js"></script>  
        <script src="js/mui.previewimage.js"></script>  
        <script type="text/javascript" src="js/media_components.js" ></script>  

        <script type="text/javascript">  
            mui.init({  
                gestureConfig: {  
                    longtap: true, //默认为false  
                    hold: true, //默认为false,不监听  
                    release: true //默认为false,不监听  
                }  
            });  
            mui.plusReady(function() {  
                mui('#imgList').imageListInit({  
                    size:5  
                });  
                mui('#audioList').audioListInit({  
                    size:5  
                });  
            });  
        </script>  
    </body>

详细案例见附件

收起阅读 »

app开发视频教程汇总 另感谢dcloud送的显示器

移动APP

hui 最新版本 1.1.9已经发布
更新内容:
1、优化基础css
2、改进轮播组件(更灵活的配置)
3、改进tab选项卡
4、增加popoverMsg组件
5、修正animate动画
6、增加picker 组件
非常好用 越来越完善的 ui框架(ui组件30+, dom操作方法 20+),更新及时,反馈迅速,欢迎使用!
http://www.hcoder.net/hui

app开发学习资料汇总:
mui、h5+教程、app新闻客户端实战教程、iconfont使用教程、开放数据源尽在hcoder
http://www.hcoder.net
本周内完成app开发用户登录、注册视频教程录制并发布敬请关注!

hcoder在的dcloud官方举报的比赛中获得一等奖(三星曲面显示器)目前已经收到奖品,并在qq群内发了红包!
感谢dcloud!提供给我们国内最优秀的编辑器,最便捷的app开发方式。

继续阅读 »

hui 最新版本 1.1.9已经发布
更新内容:
1、优化基础css
2、改进轮播组件(更灵活的配置)
3、改进tab选项卡
4、增加popoverMsg组件
5、修正animate动画
6、增加picker 组件
非常好用 越来越完善的 ui框架(ui组件30+, dom操作方法 20+),更新及时,反馈迅速,欢迎使用!
http://www.hcoder.net/hui

app开发学习资料汇总:
mui、h5+教程、app新闻客户端实战教程、iconfont使用教程、开放数据源尽在hcoder
http://www.hcoder.net
本周内完成app开发用户登录、注册视频教程录制并发布敬请关注!

hcoder在的dcloud官方举报的比赛中获得一等奖(三星曲面显示器)目前已经收到奖品,并在qq群内发了红包!
感谢dcloud!提供给我们国内最优秀的编辑器,最便捷的app开发方式。

收起阅读 »