
团队承接hbuilder,h5+,mui的外包
如题:有需要外包的请联系我,前端,后台都可以全包,QQ1046373779
如题:有需要外包的请联系我,前端,后台都可以全包,QQ1046373779

iOS平台设置应用访问白名单(LSApplicationQueriesSchemes)
此文档不再维护,请参考新文档地址:https://uniapp.dcloud.io/tutorial/app-ios-schemewhitelist
从iOS9开始系统策略更新,加入对用户隐私以及禁止扫描系统信息的控制,限制了scheme协议的访问。需要将其它App注册的scheme添加到应用访问白名单(LSApplicationQueriesSchemes)中才能实现以下功能:
- 通过scheme检查其它App是否安装,不添加到白名单则检测结果为未安装(即使应用已经安装)
- 通过scheme协议调用其它App,不添加到白名单则会弹出提示框,用户确认后才能启动应用,添加到白名单列表后则无需用户确认直接启动应用。
设置应用跳转白名单列表
打开项目的manifest.json文件,切换到“代码视图”
-
5+App项目
在manifest.json文件的"plus"->"distribute"->"apple"下添加urlschemewhitelist节点数据如下:"plus": { "distribute": { "apple": { "urlschemewhitelist": [ "BaiduSSO", "qqmusic" ], //... }, //... }, //... }, //...
-
uni-app项目
把上面的urlschemewhitelist节点数据放到manifest.json的"app-plus"->"distribute"->"ios"节点下
注意:保存后提交App云端打包后才能生效,列表最多可添加50个
App云端打包默认添加的白名单列表
为了方便开发者调用一些常用的第三方应用,云端打包默认已经添加以下白名单
lightsky
shark.video
bobo
snssdk32
pptv
bilibili
kugouURL
gaeagj
qqnews
zhihu
doubanradio
openApp.jdMobile
imeituan
tmall
dianping
vipshop
yanxuan
wccbyihaodian
taobao
suning
kaola
ctrip
kuaikanmanhua
gugutouchmanga
qrxs
mailmaster
jcnhers
wbmain
yixin
ydcourse
ntesopen
yddict
shanbay
tencentweiboSdkv2
weibosdk2.5
sinaweibo
sinaweibohd
cydia
weixin
wechat
weibosdk
mqq
mqqapi
mqzone
wtloginmqq2
mqqopensdkapiV3
mqqwpa
mqqopensdkapiV2
mqqOpensdkSSoL
hbuilder
streamapp
baidumap
iosamap
qqmap
iOS平台设置UrlSchemes参考:https://ask.dcloud.net.cn/article/64
此文档不再维护,请参考新文档地址:https://uniapp.dcloud.io/tutorial/app-ios-schemewhitelist
从iOS9开始系统策略更新,加入对用户隐私以及禁止扫描系统信息的控制,限制了scheme协议的访问。需要将其它App注册的scheme添加到应用访问白名单(LSApplicationQueriesSchemes)中才能实现以下功能:
- 通过scheme检查其它App是否安装,不添加到白名单则检测结果为未安装(即使应用已经安装)
- 通过scheme协议调用其它App,不添加到白名单则会弹出提示框,用户确认后才能启动应用,添加到白名单列表后则无需用户确认直接启动应用。
设置应用跳转白名单列表
打开项目的manifest.json文件,切换到“代码视图”
-
5+App项目
在manifest.json文件的"plus"->"distribute"->"apple"下添加urlschemewhitelist节点数据如下:"plus": { "distribute": { "apple": { "urlschemewhitelist": [ "BaiduSSO", "qqmusic" ], //... }, //... }, //... }, //...
-
uni-app项目
把上面的urlschemewhitelist节点数据放到manifest.json的"app-plus"->"distribute"->"ios"节点下
注意:保存后提交App云端打包后才能生效,列表最多可添加50个
App云端打包默认添加的白名单列表
为了方便开发者调用一些常用的第三方应用,云端打包默认已经添加以下白名单
lightsky
shark.video
bobo
snssdk32
pptv
bilibili
kugouURL
gaeagj
qqnews
zhihu
doubanradio
openApp.jdMobile
imeituan
tmall
dianping
vipshop
yanxuan
wccbyihaodian
taobao
suning
kaola
ctrip
kuaikanmanhua
gugutouchmanga
qrxs
mailmaster
jcnhers
wbmain
yixin
ydcourse
ntesopen
yddict
shanbay
tencentweiboSdkv2
weibosdk2.5
sinaweibo
sinaweibohd
cydia
weixin
wechat
weibosdk
mqq
mqqapi
mqzone
wtloginmqq2
mqqopensdkapiV3
mqqwpa
mqqopensdkapiV2
mqqOpensdkSSoL
hbuilder
streamapp
baidumap
iosamap
qqmap
iOS平台设置UrlSchemes参考:https://ask.dcloud.net.cn/article/64
收起阅读 »
Android插件,TTS语音合成(文字转化语音)。
相关介绍
概念介绍
语音合成是实现人机语音交互,建立一个有听和讲能力的交互系统所必需的关键技术。随着语音技术的发展,百度自主研发了语音合成系统(TTS),功能是接受用户发送的文本,生成语音发送给用户。
对本文中将提到的概念约定如下:
语音合成:将文本合成为语音,即声音文件。
合成引擎:将文本合成为语音的核心模块。
TTS:Text To Speech,即“从文本到语音”。
BDTTSClient:语音合成 SDK 简称,详见下条。
语音合成 SDK:即本开发包,文中简称为 BDTTSClient。BDTTSClient 是一个封装了网络收发、音频播放功能的语音合成解决方案。借助 BDTTSClient 可以快速地在应用程序中集成语音合成功能。
百度语音
合成方式
1.离在线语音合成
2.在线语音合成(本文使用方式)
应用场景
我们团队的应用场景是在推送消息后,需要播放推送消息。
准备事项
1.下载Android 平台 HTML5+ SDK 。
2.注册百度开发者,创建应用,开通服务,请参考集成指南。
3.下载在线语音合成SDK_Android版。
实现步骤
1.先导入5+SDK就不多说了,参考Android平台第三方插件开发指导。
2.添加BDTTSClient到工程(将开发包中的 libs 目录整体拷贝到工程目录,libs 目录包括了各平台的 SO 库,开发者视应用需要可以进行删减。galaxy_lite.jar 是百度 Android 公共基础库。)
3.权限声明(需要在 AndroidManifest.xml 文件,增加以上三个权限)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
4.集成java代码
import org.json.JSONArray;
import com.baidu.speechsynthesizer.SpeechSynthesizer;
import com.baidu.speechsynthesizer.SpeechSynthesizerListener;
import com.baidu.speechsynthesizer.publicutility.SpeechError;
import android.media.AudioManager;
import android.util.Log;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;
public class baidutts extends StandardFeature implements SpeechSynthesizerListener{
private IWebview iwv ;
private String text;
private SpeechSynthesizer speechSynthesizer;
private static final String TAG = "zlz";
public void speak(IWebview pWebview, JSONArray array)
{
iwv = pWebview;
String CallBackID = array.optString(0);
JSONArray newArray = new JSONArray();
newArray.put(array.optString(1));
//前台传过来的文本信息
text = array.optString(1);
//Log.i(TAG, text);
initialTts();
JSUtil.execCallback(pWebview, CallBackID, newArray, JSUtil.OK, false);
}
//百度TTS初始化
private void initialTts() {
speechSynthesizer = new SpeechSynthesizer(iwv.getContext(),
"holder", this);
// 此处需要将setApiKey方法的两个参数替换为你在百度开发者中心注册应用所得到的apiKey和secretKey
speechSynthesizer.setApiKey("your-apiKey", "your-secretKey");
speechSynthesizer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//setVolumeControlStream(AudioManager.STREAM_MUSIC);
new Thread(new Runnable() {
@Override
public void run() {
setParams();
int ret = speechSynthesizer.speak(text);
if (ret != 0) {
Log.i(TAG,"开始合成器失败" );
}
}
}).start();
}
private void setParams() {
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_ENCODE, SpeechSynthesizer.AUDIO_ENCODE_AMR);
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_RATE, SpeechSynthesizer.AUDIO_BITRATE_AMR_15K85);
}
@Override
public void onBufferProgressChanged(SpeechSynthesizer arg0, int arg1) {}
@Override
public void onCancel(SpeechSynthesizer arg0) {}
@Override
public void onError(SpeechSynthesizer arg0, SpeechError arg1) {}
@Override
public void onNewDataArrive(SpeechSynthesizer arg0, byte[] arg1, boolean arg2) {}
@Override
public void onSpeechFinish(SpeechSynthesizer arg0) {}
@Override
public void onSpeechPause(SpeechSynthesizer arg0) {}
@Override
public void onSpeechProgressChanged(SpeechSynthesizer arg0, int arg1) {}
@Override
public void onSpeechResume(SpeechSynthesizer arg0) {}
@Override
public void onSpeechStart(SpeechSynthesizer arg0) {}
@Override
public void onStartWorking(SpeechSynthesizer arg0) {}
@Override
public void onSynthesizeFinish(SpeechSynthesizer arg0) {}
}
5.前台javascript代码
document.addEventListener( "plusready", function()
{
var _BARCODE = 'kxdPlugins',
B = window.plus.bridge;
var kxdPlugins =
{
// 声明异步返回方法
speak : function (Argus, successCallback, errorCallback )
{
var success = typeof successCallback !== 'function' ? null : function(args)
{
successCallback(args);
},
fail = typeof errorCallback !== 'function' ? null : function(code)
{
errorCallback(code);
};
callbackID = B.callbackId(success, fail);
// 通知Native层plugintest扩展插件运行”speak”方法
return B.exec(_BARCODE, "speak", [callbackID, Argus]);
}
};
window.plus.kxdPlugins = kxdPlugins;
}, true );
使用方式
和普通的API调用方式一样:plus.kxdPlugins.speak("这是语音播放的文字内容");
注意事项
1.在/assets/data/properties.xml中添加插件权限。
2.在/assets/apps/appid/www/manifest.json 中添加对应插件权限。
3.在/AndroidManifest.xml 文件中添加对应的百度语音合成权限。
相关介绍
概念介绍
语音合成是实现人机语音交互,建立一个有听和讲能力的交互系统所必需的关键技术。随着语音技术的发展,百度自主研发了语音合成系统(TTS),功能是接受用户发送的文本,生成语音发送给用户。
对本文中将提到的概念约定如下:
语音合成:将文本合成为语音,即声音文件。
合成引擎:将文本合成为语音的核心模块。
TTS:Text To Speech,即“从文本到语音”。
BDTTSClient:语音合成 SDK 简称,详见下条。
语音合成 SDK:即本开发包,文中简称为 BDTTSClient。BDTTSClient 是一个封装了网络收发、音频播放功能的语音合成解决方案。借助 BDTTSClient 可以快速地在应用程序中集成语音合成功能。
百度语音
合成方式
1.离在线语音合成
2.在线语音合成(本文使用方式)
应用场景
我们团队的应用场景是在推送消息后,需要播放推送消息。
准备事项
1.下载Android 平台 HTML5+ SDK 。
2.注册百度开发者,创建应用,开通服务,请参考集成指南。
3.下载在线语音合成SDK_Android版。
实现步骤
1.先导入5+SDK就不多说了,参考Android平台第三方插件开发指导。
2.添加BDTTSClient到工程(将开发包中的 libs 目录整体拷贝到工程目录,libs 目录包括了各平台的 SO 库,开发者视应用需要可以进行删减。galaxy_lite.jar 是百度 Android 公共基础库。)
3.权限声明(需要在 AndroidManifest.xml 文件,增加以上三个权限)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
4.集成java代码
import org.json.JSONArray;
import com.baidu.speechsynthesizer.SpeechSynthesizer;
import com.baidu.speechsynthesizer.SpeechSynthesizerListener;
import com.baidu.speechsynthesizer.publicutility.SpeechError;
import android.media.AudioManager;
import android.util.Log;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;
public class baidutts extends StandardFeature implements SpeechSynthesizerListener{
private IWebview iwv ;
private String text;
private SpeechSynthesizer speechSynthesizer;
private static final String TAG = "zlz";
public void speak(IWebview pWebview, JSONArray array)
{
iwv = pWebview;
String CallBackID = array.optString(0);
JSONArray newArray = new JSONArray();
newArray.put(array.optString(1));
//前台传过来的文本信息
text = array.optString(1);
//Log.i(TAG, text);
initialTts();
JSUtil.execCallback(pWebview, CallBackID, newArray, JSUtil.OK, false);
}
//百度TTS初始化
private void initialTts() {
speechSynthesizer = new SpeechSynthesizer(iwv.getContext(),
"holder", this);
// 此处需要将setApiKey方法的两个参数替换为你在百度开发者中心注册应用所得到的apiKey和secretKey
speechSynthesizer.setApiKey("your-apiKey", "your-secretKey");
speechSynthesizer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//setVolumeControlStream(AudioManager.STREAM_MUSIC);
new Thread(new Runnable() {
@Override
public void run() {
setParams();
int ret = speechSynthesizer.speak(text);
if (ret != 0) {
Log.i(TAG,"开始合成器失败" );
}
}
}).start();
}
private void setParams() {
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_ENCODE, SpeechSynthesizer.AUDIO_ENCODE_AMR);
speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_RATE, SpeechSynthesizer.AUDIO_BITRATE_AMR_15K85);
}
@Override
public void onBufferProgressChanged(SpeechSynthesizer arg0, int arg1) {}
@Override
public void onCancel(SpeechSynthesizer arg0) {}
@Override
public void onError(SpeechSynthesizer arg0, SpeechError arg1) {}
@Override
public void onNewDataArrive(SpeechSynthesizer arg0, byte[] arg1, boolean arg2) {}
@Override
public void onSpeechFinish(SpeechSynthesizer arg0) {}
@Override
public void onSpeechPause(SpeechSynthesizer arg0) {}
@Override
public void onSpeechProgressChanged(SpeechSynthesizer arg0, int arg1) {}
@Override
public void onSpeechResume(SpeechSynthesizer arg0) {}
@Override
public void onSpeechStart(SpeechSynthesizer arg0) {}
@Override
public void onStartWorking(SpeechSynthesizer arg0) {}
@Override
public void onSynthesizeFinish(SpeechSynthesizer arg0) {}
}
5.前台javascript代码
document.addEventListener( "plusready", function()
{
var _BARCODE = 'kxdPlugins',
B = window.plus.bridge;
var kxdPlugins =
{
// 声明异步返回方法
speak : function (Argus, successCallback, errorCallback )
{
var success = typeof successCallback !== 'function' ? null : function(args)
{
successCallback(args);
},
fail = typeof errorCallback !== 'function' ? null : function(code)
{
errorCallback(code);
};
callbackID = B.callbackId(success, fail);
// 通知Native层plugintest扩展插件运行”speak”方法
return B.exec(_BARCODE, "speak", [callbackID, Argus]);
}
};
window.plus.kxdPlugins = kxdPlugins;
}, true );
使用方式
和普通的API调用方式一样:plus.kxdPlugins.speak("这是语音播放的文字内容");
注意事项
1.在/assets/data/properties.xml中添加插件权限。
2.在/assets/apps/appid/www/manifest.json 中添加对应插件权限。
3.在/AndroidManifest.xml 文件中添加对应的百度语音合成权限。

获取图片当前旋转状态
今日开发过程中遇见从相册选择或者自拍照片,显示时为横向。故封装如下代码,希望对大家有所帮助。
function getImgOrientation (filePath) {
var ExifInterface = plus.android.importClass("android.media.ExifInterface");
var exifInterface = new ExifInterface(filePath.replace("file:///", ""));
var orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
var degree = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
return degree;
}
今日开发过程中遇见从相册选择或者自拍照片,显示时为横向。故封装如下代码,希望对大家有所帮助。
function getImgOrientation (filePath) {
var ExifInterface = plus.android.importClass("android.media.ExifInterface");
var exifInterface = new ExifInterface(filePath.replace("file:///", ""));
var orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
var degree = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
return degree;
}
收起阅读 »

整包(apk/ipa)升级
官方已发布APP升级中心,支持原生APP整包升级和wgt资源包升级。详见
5+应用可使用以下方式进行升级
- 整包升级:适用于大版本更新,runtime发生变化时(模块、配置、版本等变化)必须使用此更新方法
- 应用资源升级:适用于小版本更新 。runtime不变,前端页面整体压缩包更新
- 应用资源差量升级:适用于小版本更新 。runtime不变,前端页面仅需要更新的部分更新。
本文重点描述5+应用整包升级,逻辑其实是非常简单,主要有三个步骤:
- 查询是否有新版本更新
- 下载新版本
- 安装新版本
而在实际应用的升级过程中则需要处理很多细节问题,下面就按照这个流程来简单说明在5+App中实现应用升级的逻辑。
查询是否有新版本更新
这个操作其实非常简单,就是客户端与升级服务器的一次交互操作,比较升级服务器上发布的最新客户端版本是否高于当前客户端版本号(5+ API中可以通过plus.runtime.version获取当前apk/ipa的版本号,注意打包方生效)?是的话则需要升级,否则无需升级。
从逻辑上来考虑有两种判断模式:
- 客户端判断是否有升级
客户端从服务器获取最新的版本号,本地js判断是否需要升级。 - 服务器判断是否有升级
客户端提交版本到服务器,有服务器判断返回是否需要升级。
前者的优点是否服务器压力小,静态返回最新客户端版本即可,后者的优点则升级控制会更灵活,可以根据其它条件动态控制部分用户先升级(灰度发布)等。有条件的情况推荐采用第二种方式进行判断。
可以使用Javascript中的标准XHR请求,如果存在跨域问题则使用5+ API的XMLHttpRequest。
下载新版本
如果判断到需要更新版本,则需要从服务器下载新版本,通常升级服务器应该返回下载新版本的地址(或者从固定的地址获取)。
有两种下载方法,一种调用Downloader API下载,示例如下:
var url=""; // 下载文件地址
var dtask = plus.downloader.createDownload( url, {}, function ( d, status ) {
if ( status == 200 ) { // 下载成功
var path = d.filename;
console.log(d.filename);
} else {//下载失败
alert( "Download failed: " + status );
}
});
dtask.start();
安装新版本
下载原生安装包apk后,可调用[plus.runtime.install]()方法安装,示例如下:
plus.runtime.install(path); // 安装下载的apk文件
注意
iOS平台的ipa无法安装,此时需要跳转到appstore,提示用户自动点击升级更新,跳转到appstore的方法为打开应用的appstore地址,示例如下:
var url='itms-apps://itunes.apple.com/cn/app/hello-h5+/id682211190?l=zh&mt=8';// HelloH5应用在appstore的地址
plus.runtime.openURL(url);
此处url是以"itms-apps://"开头,后面跟appstore上应用地址。
示例
在Hello H5+和Hello mui示例里,有2种不同的检查更新处理方式。
Hello H5+里的update.js比较复杂,在js里执行下载apk并安装的逻辑。
Hello mui里的update.js比较简单,弹出新包下载地址到浏览器,由浏览器执行下载逻辑。
如何选择看自己的要求。
官方已发布APP升级中心,支持原生APP整包升级和wgt资源包升级。详见
5+应用可使用以下方式进行升级
- 整包升级:适用于大版本更新,runtime发生变化时(模块、配置、版本等变化)必须使用此更新方法
- 应用资源升级:适用于小版本更新 。runtime不变,前端页面整体压缩包更新
- 应用资源差量升级:适用于小版本更新 。runtime不变,前端页面仅需要更新的部分更新。
本文重点描述5+应用整包升级,逻辑其实是非常简单,主要有三个步骤:
- 查询是否有新版本更新
- 下载新版本
- 安装新版本
而在实际应用的升级过程中则需要处理很多细节问题,下面就按照这个流程来简单说明在5+App中实现应用升级的逻辑。
查询是否有新版本更新
这个操作其实非常简单,就是客户端与升级服务器的一次交互操作,比较升级服务器上发布的最新客户端版本是否高于当前客户端版本号(5+ API中可以通过plus.runtime.version获取当前apk/ipa的版本号,注意打包方生效)?是的话则需要升级,否则无需升级。
从逻辑上来考虑有两种判断模式:
- 客户端判断是否有升级
客户端从服务器获取最新的版本号,本地js判断是否需要升级。 - 服务器判断是否有升级
客户端提交版本到服务器,有服务器判断返回是否需要升级。
前者的优点是否服务器压力小,静态返回最新客户端版本即可,后者的优点则升级控制会更灵活,可以根据其它条件动态控制部分用户先升级(灰度发布)等。有条件的情况推荐采用第二种方式进行判断。
可以使用Javascript中的标准XHR请求,如果存在跨域问题则使用5+ API的XMLHttpRequest。
下载新版本
如果判断到需要更新版本,则需要从服务器下载新版本,通常升级服务器应该返回下载新版本的地址(或者从固定的地址获取)。
有两种下载方法,一种调用Downloader API下载,示例如下:
var url=""; // 下载文件地址
var dtask = plus.downloader.createDownload( url, {}, function ( d, status ) {
if ( status == 200 ) { // 下载成功
var path = d.filename;
console.log(d.filename);
} else {//下载失败
alert( "Download failed: " + status );
}
});
dtask.start();
安装新版本
下载原生安装包apk后,可调用[plus.runtime.install]()方法安装,示例如下:
plus.runtime.install(path); // 安装下载的apk文件
注意
iOS平台的ipa无法安装,此时需要跳转到appstore,提示用户自动点击升级更新,跳转到appstore的方法为打开应用的appstore地址,示例如下:
var url='itms-apps://itunes.apple.com/cn/app/hello-h5+/id682211190?l=zh&mt=8';// HelloH5应用在appstore的地址
plus.runtime.openURL(url);
此处url是以"itms-apps://"开头,后面跟appstore上应用地址。
示例
在Hello H5+和Hello mui示例里,有2种不同的检查更新处理方式。
Hello H5+里的update.js比较复杂,在js里执行下载apk并安装的逻辑。
Hello mui里的update.js比较简单,弹出新包下载地址到浏览器,由浏览器执行下载逻辑。
如何选择看自己的要求。

如何在本地进行微信公众号的开发调试
在进行微信公众号开发时,以前必须要有外网域名才能收到微信服务器的推送,这给开发和调试带来很大的不便。
现在方便了,QQ浏览器提供了微信公众号调试工具,开发者可以在自己的开发机上进行开发和调试,不再需要外网IP和域名。不仅可以直观看到已接收和已发送的消息内容和事件,方便开发和问题定位,还可以重复发送已接收的微信报文,避免调试时频繁操作手机
原理
调试工具内置了一个server,监听你本地运行的程序,并为你生成一个外网的url,你只需要在公众号的开发信息中配置上这个url,公众号收到消息后,就会通过这个url转发到调试工具上,调试工具再转给你的本地运行程序。
使用方法
(1)在本机启动运行自己程序的server
(2)打开qq浏览器,在应用中心中安装“微信调试工具”,安装完成后,选择“服务器端调试”
(3)填写本地server的ip和端口号,调试工具会返回一个外部URL
(4)到公众号后台开发者配置信息中填写这个URL
(5)用微信向公众号发送消息测试
在进行微信公众号开发时,以前必须要有外网域名才能收到微信服务器的推送,这给开发和调试带来很大的不便。
现在方便了,QQ浏览器提供了微信公众号调试工具,开发者可以在自己的开发机上进行开发和调试,不再需要外网IP和域名。不仅可以直观看到已接收和已发送的消息内容和事件,方便开发和问题定位,还可以重复发送已接收的微信报文,避免调试时频繁操作手机
原理
调试工具内置了一个server,监听你本地运行的程序,并为你生成一个外网的url,你只需要在公众号的开发信息中配置上这个url,公众号收到消息后,就会通过这个url转发到调试工具上,调试工具再转给你的本地运行程序。
使用方法
(1)在本机启动运行自己程序的server
(2)打开qq浏览器,在应用中心中安装“微信调试工具”,安装完成后,选择“服务器端调试”
(3)填写本地server的ip和端口号,调试工具会返回一个外部URL
(4)到公众号后台开发者配置信息中填写这个URL
(5)用微信向公众号发送消息测试

IOS平台:如何在离线打包时配置 3D Touch图标快捷菜单
Apple最新发布的iPhone 6s (plus) 设备支持3D touch功能,用户可通过重按屏幕上的图标,打开设置的菜单。H5+ SDK已经支持添加应用的快捷菜单,显示效果如下:
离线工程配置的方法
打开离线打包工程的info.plist文件,在文件中添加UIApplicationShortcutItems节点,并在节点下添加item。
各字段值规范如下表 各值的关系请参考上图 |
节点名 | 节点类型 | 可选性 | 节点说明 | 备注 |
---|---|---|---|---|---|
UIApplicationShortcutItems | Array | 必选 | 图标快捷菜单节点声明 | ||
UIApplicationShortcutItemType | String | 必选 | 菜单类型 | ||
UIApplicationShortcutItemTitle | String | 必选 | 菜单项的标题 | ||
UIApplicationShortcutItemSubtitle | String | 可选 | 菜单项的副标题 | ||
UIApplicationShortcutItemIconFile | String | 可选 | 指定菜单项显示安装包内自带的图标,相对安装包的根目录位置 | 与UIApplicationShortcutItemIconType节点同时配置时优先级高于UIApplicationShortcutItemIconType | |
UIApplicationShortcutItemIconType | String | 可选 | 指定菜单项显示系统自带图标 | 取值可参考苹果官方文档 | |
UIApplicationShortcutItemUserInfo | String | 可选 | 用户自定义的菜单项附加信息 | 附带信息可在应用内通过plus.runtime.arguments获取 |
App中处理快捷菜单项
请参考文档iOS平台支持3D Touch快捷菜单项
Apple最新发布的iPhone 6s (plus) 设备支持3D touch功能,用户可通过重按屏幕上的图标,打开设置的菜单。H5+ SDK已经支持添加应用的快捷菜单,显示效果如下:
离线工程配置的方法
打开离线打包工程的info.plist文件,在文件中添加UIApplicationShortcutItems节点,并在节点下添加item。
各字段值规范如下表 各值的关系请参考上图 |
节点名 | 节点类型 | 可选性 | 节点说明 | 备注 |
---|---|---|---|---|---|
UIApplicationShortcutItems | Array | 必选 | 图标快捷菜单节点声明 | ||
UIApplicationShortcutItemType | String | 必选 | 菜单类型 | ||
UIApplicationShortcutItemTitle | String | 必选 | 菜单项的标题 | ||
UIApplicationShortcutItemSubtitle | String | 可选 | 菜单项的副标题 | ||
UIApplicationShortcutItemIconFile | String | 可选 | 指定菜单项显示安装包内自带的图标,相对安装包的根目录位置 | 与UIApplicationShortcutItemIconType节点同时配置时优先级高于UIApplicationShortcutItemIconType | |
UIApplicationShortcutItemIconType | String | 可选 | 指定菜单项显示系统自带图标 | 取值可参考苹果官方文档 | |
UIApplicationShortcutItemUserInfo | String | 可选 | 用户自定义的菜单项附加信息 | 附带信息可在应用内通过plus.runtime.arguments获取 |
App中处理快捷菜单项
请参考文档iOS平台支持3D Touch快捷菜单项
收起阅读 »
iOS平台支持3D Touch快捷菜单项
iPhone6s(plus)设备已经支持3D Touch屏幕,HBuilder已支持添加应用的快捷菜单,效果如下:
配置快捷菜单项
打开应用的manifest.json文件,切换到代码视图,在plus -> distribute -> apple 下添加shortcuts节点,并配置各菜单项,数组中每项对应一个快捷菜单项:
"shortcuts": [
{
"type": "share",
"title": "分 享",
"subtitle": "分享到微信、微博、QQ",
"icontype": "UIApplicationShortcutIconTypeShare"
},
{
"type": "about",
"title": "关 于",
"subtitle": "www.dcloud.io",
"iconfile": "sa.png",
"userinfo": {
"key3":"value3"
}
}
],
uni-app项目将以上数据添加到"app-plus"->"distribute"->"ios"节点下
其中各字段值规范如下:
- type: (必选)菜单项类型,字符串类型,用于标识菜单项
- title: (必选)菜单项上显示的标题,字符串类型
- subtitle: (可选)菜单项上显示的子标题,字符串类型
- icontype: (可选)菜单项上显示的图标类型,字符串类型,取值参考iOS官方文档UIApplicationShortcutIconType
- iconfile: (可选)菜单项上显示的图标文件,字符串类型,相对5+应用根目录路径,图标要求35x35分辨率,单色,参考Apple官方PS模板图
- userinfo: (可选)菜单项上的自定义数据,JSON格式
App中处理快捷菜单项
判断应用是否通过快捷菜单项启动
plus.runtime.launcher的值为"shortcut"表示应用从快捷菜单项启动,示例如下:
if(plus.runtime.launcher=='shortcut'){
// ...
}
判断快捷菜单项启动的参数
plus.runtime.arguments中保存所有快捷菜单项配置的值(JSON格式字符串),示例如下:
var cmd = JSON.parse(plus.runtime.arguments);
console.log("Shortcut-plus.runtime.arguments: "+plus.runtime.arguments)
var type=cmd&&cmd.type;
switch(type){
case 'share':
// 用户点击了‘share'菜单项
break;
case 'about':
// 用户点击了’about'菜单项
break;
default:
break;
}
plus.runtime.arguments的JSON格式字符串示例如下:
“{"type":"about","title":"关 于","subtitle": "www.dcloud.io","userinfo":{"key3":"value3"}}”
其中包括以下键值:
- type: 菜单项类型,字符串类型
- title: 菜单项上显示的标题,字符串类型
- subtitle: 菜单项上显示的子标题,字符串类型
- userinfo: 菜单项上的自定义数据
注:真机运行不生效,需提交App云端打包后才生效
实际用法参考HelloH5应用的“js/shortcut.js”
iOS平台5+SDK原生环境配置方法
uni-app网友经验分享:https://ask.dcloud.net.cn/article/36103
iPhone6s(plus)设备已经支持3D Touch屏幕,HBuilder已支持添加应用的快捷菜单,效果如下:
配置快捷菜单项
打开应用的manifest.json文件,切换到代码视图,在plus -> distribute -> apple 下添加shortcuts节点,并配置各菜单项,数组中每项对应一个快捷菜单项:
"shortcuts": [
{
"type": "share",
"title": "分 享",
"subtitle": "分享到微信、微博、QQ",
"icontype": "UIApplicationShortcutIconTypeShare"
},
{
"type": "about",
"title": "关 于",
"subtitle": "www.dcloud.io",
"iconfile": "sa.png",
"userinfo": {
"key3":"value3"
}
}
],
uni-app项目将以上数据添加到"app-plus"->"distribute"->"ios"节点下
其中各字段值规范如下:
- type: (必选)菜单项类型,字符串类型,用于标识菜单项
- title: (必选)菜单项上显示的标题,字符串类型
- subtitle: (可选)菜单项上显示的子标题,字符串类型
- icontype: (可选)菜单项上显示的图标类型,字符串类型,取值参考iOS官方文档UIApplicationShortcutIconType
- iconfile: (可选)菜单项上显示的图标文件,字符串类型,相对5+应用根目录路径,图标要求35x35分辨率,单色,参考Apple官方PS模板图
- userinfo: (可选)菜单项上的自定义数据,JSON格式
App中处理快捷菜单项
判断应用是否通过快捷菜单项启动
plus.runtime.launcher的值为"shortcut"表示应用从快捷菜单项启动,示例如下:
if(plus.runtime.launcher=='shortcut'){
// ...
}
判断快捷菜单项启动的参数
plus.runtime.arguments中保存所有快捷菜单项配置的值(JSON格式字符串),示例如下:
var cmd = JSON.parse(plus.runtime.arguments);
console.log("Shortcut-plus.runtime.arguments: "+plus.runtime.arguments)
var type=cmd&&cmd.type;
switch(type){
case 'share':
// 用户点击了‘share'菜单项
break;
case 'about':
// 用户点击了’about'菜单项
break;
default:
break;
}
plus.runtime.arguments的JSON格式字符串示例如下:
“{"type":"about","title":"关 于","subtitle": "www.dcloud.io","userinfo":{"key3":"value3"}}”
其中包括以下键值:
- type: 菜单项类型,字符串类型
- title: 菜单项上显示的标题,字符串类型
- subtitle: 菜单项上显示的子标题,字符串类型
- userinfo: 菜单项上的自定义数据
注:真机运行不生效,需提交App云端打包后才生效
实际用法参考HelloH5应用的“js/shortcut.js”
iOS平台5+SDK原生环境配置方法
uni-app网友经验分享:https://ask.dcloud.net.cn/article/36103
收起阅读 »
如何动态兼容沉浸式状态栏模式
HBuilder6.6.1版本已经完全支持沉浸式状态栏,可以下载最新版本HelloH5应用体验。
各平台配置参考:
由于各系统版本的限制,沉浸式状态栏对系统有要求(Android4.4及以上、iOS7.0及以上),如果要兼容各系统版本,需要动态判断当前环境是否支持沉浸式状态栏以及系统状态栏的高度:
使用5+API
- 判断当前环境是否支持沉浸式状态栏
plus.navigator.isImmersedStatusbar()
如果当前支持沉浸式状态栏则返回true,否则返回false。 - 获取当前系统状态栏高度
plus.navigator.getStatusbarHeight()
获取系统状态栏高度,Number类型。
其单位是逻辑像素值,即css中可直接使用的像素值,可能存在小数点。
实际用法参考HelloH5应用的“plus/doc.html”:
// 创建加载内容窗口
var topoffset='45px';
if(plus.navigator.isImmersedStatusbar()){// 兼容immersed状态栏模式
// 获取状态栏高度并根据业务需求处理,这里重新计算了子窗口的偏移位置
topoffset=(Math.round(plus.navigator.getStatusbarHeight())+45)+'px';
}
// 使用偏移位置创建子窗口
wc=plus.webview.create(null,'doccontent',{top:topoffset,bottom:'0px',bounce:'vertical',bounceBackground:'#FFFFFF'});
通过userAgent判断
5+API需要在plusready事件后才能调用,通常此事件在DOM加载渲染后才会触发,无法再渲染前根据不同的状态来设置css。
为了解决此问题,在支持5+API运行环境的userAgent中特定字段Html5Plus/1.0后添加Immersed标识,如下:
"Html5Plus/1.0 (Immersed/30)"
其中Immersed/后的30表示状态栏的高度,单位为逻辑像素值。
可以使用正则表达式进行获取:
var immersed = 0;
var ms=(/Html5Plus\/.+\s\(.*(Immersed\/(\d+\.?\d*).*)\)/gi).exec(navigator.userAgent);
if(ms&&ms.length>=3){ // 当前环境为沉浸式状态栏模式
immersed=parseFloat(ms[2]);// 获取状态栏的高度
}
immersed值如果大于0则表示当前环境支持沉浸式状态栏。
获取状态栏高度后,可以使用js动态修改DOM元素的css属性来设置样式,如设置界面头区域的顶部内边距为状态栏的高度(避免系统状态栏与界面头重叠),示例如下:
var t=document.getElementById('header');
t&&t.style.paddingTop=immersed+'px';
具体项目中可根据界面设计,灵活使用immersed值来动态适配各种效果。
完整用法可参考HelloH5应用中的“js/immersed.js”
HBuilder6.6.1版本已经完全支持沉浸式状态栏,可以下载最新版本HelloH5应用体验。
各平台配置参考:
由于各系统版本的限制,沉浸式状态栏对系统有要求(Android4.4及以上、iOS7.0及以上),如果要兼容各系统版本,需要动态判断当前环境是否支持沉浸式状态栏以及系统状态栏的高度:
使用5+API
- 判断当前环境是否支持沉浸式状态栏
plus.navigator.isImmersedStatusbar()
如果当前支持沉浸式状态栏则返回true,否则返回false。 - 获取当前系统状态栏高度
plus.navigator.getStatusbarHeight()
获取系统状态栏高度,Number类型。
其单位是逻辑像素值,即css中可直接使用的像素值,可能存在小数点。
实际用法参考HelloH5应用的“plus/doc.html”:
// 创建加载内容窗口
var topoffset='45px';
if(plus.navigator.isImmersedStatusbar()){// 兼容immersed状态栏模式
// 获取状态栏高度并根据业务需求处理,这里重新计算了子窗口的偏移位置
topoffset=(Math.round(plus.navigator.getStatusbarHeight())+45)+'px';
}
// 使用偏移位置创建子窗口
wc=plus.webview.create(null,'doccontent',{top:topoffset,bottom:'0px',bounce:'vertical',bounceBackground:'#FFFFFF'});
通过userAgent判断
5+API需要在plusready事件后才能调用,通常此事件在DOM加载渲染后才会触发,无法再渲染前根据不同的状态来设置css。
为了解决此问题,在支持5+API运行环境的userAgent中特定字段Html5Plus/1.0后添加Immersed标识,如下:
"Html5Plus/1.0 (Immersed/30)"
其中Immersed/后的30表示状态栏的高度,单位为逻辑像素值。
可以使用正则表达式进行获取:
var immersed = 0;
var ms=(/Html5Plus\/.+\s\(.*(Immersed\/(\d+\.?\d*).*)\)/gi).exec(navigator.userAgent);
if(ms&&ms.length>=3){ // 当前环境为沉浸式状态栏模式
immersed=parseFloat(ms[2]);// 获取状态栏的高度
}
immersed值如果大于0则表示当前环境支持沉浸式状态栏。
获取状态栏高度后,可以使用js动态修改DOM元素的css属性来设置样式,如设置界面头区域的顶部内边距为状态栏的高度(避免系统状态栏与界面头重叠),示例如下:
var t=document.getElementById('header');
t&&t.style.paddingTop=immersed+'px';
具体项目中可根据界面设计,灵活使用immersed值来动态适配各种效果。
完整用法可参考HelloH5应用中的“js/immersed.js”

Android平台设置沉浸式状态栏显示效果
系列文章导航:
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台设置沉浸式状态栏显示效果
iOS平台设置沉浸式状态栏显示效果
正文:
应用可视区域到系统状态栏下透明显示效果,如下图所示:
此模式下应用占用全屏区域,而系统状态栏会拦截用户操作事件,此时需要预留出系统状态栏高度。
获取系统状态栏高度及沉浸式状态判断参考:如何动态判断沉浸式状态栏模式。
HBuilder创建的应用默认不使用沉浸式状态栏样式,需要进行如下配置开启:
打开应用的manifest.json文件,切换到代码视图,在plus -> statusbar 下添加immersed节点并设置值为true。
"plus": {
"statusbar": {
"immersed": true
}
}
如下图所示:
保存后提交App云端打包
注意:
- 真机运行不生效,需提交App云端打包后才生效;
- 此功能仅在Android4.4及以上系统有效。
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台5+SDK原生环境配置方法
iOS平台设置沉浸式状态栏显示效果
系列文章导航:
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台设置沉浸式状态栏显示效果
iOS平台设置沉浸式状态栏显示效果
正文:
应用可视区域到系统状态栏下透明显示效果,如下图所示:
此模式下应用占用全屏区域,而系统状态栏会拦截用户操作事件,此时需要预留出系统状态栏高度。
获取系统状态栏高度及沉浸式状态判断参考:如何动态判断沉浸式状态栏模式。
HBuilder创建的应用默认不使用沉浸式状态栏样式,需要进行如下配置开启:
打开应用的manifest.json文件,切换到代码视图,在plus -> statusbar 下添加immersed节点并设置值为true。
"plus": {
"statusbar": {
"immersed": true
}
}
如下图所示:
保存后提交App云端打包
注意:
- 真机运行不生效,需提交App云端打包后才生效;
- 此功能仅在Android4.4及以上系统有效。
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台5+SDK原生环境配置方法
iOS平台设置沉浸式状态栏显示效果