HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

地图定位问题终于搞清楚了。。

定位 高德地图 HTML5+

不得不吐槽下mui的社区,问问题基本没人答复。小白经常被一个问题卡死,严重拖累进度和心情。

自己在qq群里反复询问,在高德社区发帖,一步步搜索问题。终于搞懂了大部分。下面进入正题:

自己的APP需要定位模块,类似滴滴打车的需求。

所以找了高德的JS API,用浏览器定位(小白注意:我们用mui开发的Hybrid APP不能用高德的原生Android API,下面会讲到怎么使用系统的原生能力)

所谓的浏览器定位实际上都是使用了HTML5的Geolocation功能。关于定位,分为GPS定位和网络定位2种。GPS定位,精度较高,可达到10米,但室内不可用,且超级费电。网络定位,分为wifi定位和基站定位,都是通过获取wifi或者基站信息,然后查询对应的wifi或者基站位置数据库,得到的定位地点。定位数据库可以不断完善不断补充,所以,越定位越准确。我们可以先判断浏览器是否支持geolocation, 如果不支持,可以提示错误,或者进入其他逻辑处理流程,现在移动端的智能手机浏览器绝大部分都是支持的。代码如下:

if( navigator.geolocation ){  
    alert('恭喜,您的浏览器支持HTML5 Geolocation API');  
    navigator.geolocation.getCurrentPosition( successCallback, handleLocationError,{maximumAge:15000, timeout:10000, enableHighAccuracy:true});  
}else{  
    alert( "对不起,您的浏览器不支持html5定位");  
}  

function successCallback (){  
    alert('成功获取到位置信息');  
};  

function handleLocationError(error) {  
    console.log(error);  
    switch(error.code){  
        case 0:  
          alert("获取位置信息出错!");  
          break;  
        case 1:  
          alert("您设置了阻止该页面获取位置信息!");  
          break;  
        case 2:  
          alert("浏览器无法确定您的位置!");  
          break;  
        case 3:  
          alert("获取位置信息超时!");  
          break;  
        default:  
          alert('不明原因');  
          break;  
    }  
}

当然浏览器定位不是那么好用,由于各种其他原因和我们的天朝的社会主义特色政策,国行Android手机“阉割”了谷歌GMS服务包,导致HTML5的geolocation无法使用wifi和基站定位服务。经常会定位失败。但是提供地图和定位相关服务的不止是google一家,还有百度、高德、搜狗啊。

咋一看,百度js api也有自己的geolocation(http://developer.baidu.com/map/reference/index.php?title=Class:%E6%9C%8D%E5%8A%A1%E7%B1%BB/Geolocation) 这个取代html5自带的不就可以了么,经过实验,真是图样图森破了,原来所有的javascript API都还是调用的浏览器自身的geolocation进行封装实现的,也就是说如果原本不能wifi+基站定位,用百度、高德的javascript api的效果是一样的。

由于我人在北京,每次都把我定位到了一个叫“军诚水果超市”的地方。开始因为我听说高德的浏览器有很大偏差,以为是定位偏差的问题。但直到我注意到这里:(http://lbs.amap.com/api/javascript-api/reference/plugin/) 在AMap.Geolocation 插件中有这样一句话:当浏览器原生定位接口定位失败后,系统会调用IP定位,返回定位点所在城市中心点。此时,定位精度范围返回“null”。使用高德JS API浏览器定位,精度如果返回null就说明定位失败了,而不是定位偏差。(国内的文档太不规范,着实把我骗到了)

最后要说明的是,如果是开发Android原生软件的话,可以在APP里封装百度地图定位的SDK,这个是可以解决没有谷歌GMS服务包无法定位的问题的,因为百度地图定位SDK实际上是起到和谷歌服务包里面的定位模块一样的作用,由这里也可以看到HTML5 Webapp和原生APP的一个差别,不是一个层面的解决方案。

记得项目目录里的menifest.json文件里可以配置百度和高德的SDK么?这就是HTML5+API赋予你的强大能力!如果你配置正确的话,即可使用系统原生的定位,不需要坑爹的浏览器定位了。这就是Hybrid APP相对Web APP的一个优势。

最终解决方案是:配置好百度或高德的SDK,使用HTML5+API的plus.geolocation.getCurrentPosition()利用原生定位获取到坐标点后,再用百度或高德的JS API去实现其他的地图模块功能。

参考的文章:

http://www.html5col.com/getcurrentposition/

http://blog.csdn.net/albert528108/article/details/39213419

继续阅读 »

不得不吐槽下mui的社区,问问题基本没人答复。小白经常被一个问题卡死,严重拖累进度和心情。

自己在qq群里反复询问,在高德社区发帖,一步步搜索问题。终于搞懂了大部分。下面进入正题:

自己的APP需要定位模块,类似滴滴打车的需求。

所以找了高德的JS API,用浏览器定位(小白注意:我们用mui开发的Hybrid APP不能用高德的原生Android API,下面会讲到怎么使用系统的原生能力)

所谓的浏览器定位实际上都是使用了HTML5的Geolocation功能。关于定位,分为GPS定位和网络定位2种。GPS定位,精度较高,可达到10米,但室内不可用,且超级费电。网络定位,分为wifi定位和基站定位,都是通过获取wifi或者基站信息,然后查询对应的wifi或者基站位置数据库,得到的定位地点。定位数据库可以不断完善不断补充,所以,越定位越准确。我们可以先判断浏览器是否支持geolocation, 如果不支持,可以提示错误,或者进入其他逻辑处理流程,现在移动端的智能手机浏览器绝大部分都是支持的。代码如下:

if( navigator.geolocation ){  
    alert('恭喜,您的浏览器支持HTML5 Geolocation API');  
    navigator.geolocation.getCurrentPosition( successCallback, handleLocationError,{maximumAge:15000, timeout:10000, enableHighAccuracy:true});  
}else{  
    alert( "对不起,您的浏览器不支持html5定位");  
}  

function successCallback (){  
    alert('成功获取到位置信息');  
};  

function handleLocationError(error) {  
    console.log(error);  
    switch(error.code){  
        case 0:  
          alert("获取位置信息出错!");  
          break;  
        case 1:  
          alert("您设置了阻止该页面获取位置信息!");  
          break;  
        case 2:  
          alert("浏览器无法确定您的位置!");  
          break;  
        case 3:  
          alert("获取位置信息超时!");  
          break;  
        default:  
          alert('不明原因');  
          break;  
    }  
}

当然浏览器定位不是那么好用,由于各种其他原因和我们的天朝的社会主义特色政策,国行Android手机“阉割”了谷歌GMS服务包,导致HTML5的geolocation无法使用wifi和基站定位服务。经常会定位失败。但是提供地图和定位相关服务的不止是google一家,还有百度、高德、搜狗啊。

咋一看,百度js api也有自己的geolocation(http://developer.baidu.com/map/reference/index.php?title=Class:%E6%9C%8D%E5%8A%A1%E7%B1%BB/Geolocation) 这个取代html5自带的不就可以了么,经过实验,真是图样图森破了,原来所有的javascript API都还是调用的浏览器自身的geolocation进行封装实现的,也就是说如果原本不能wifi+基站定位,用百度、高德的javascript api的效果是一样的。

由于我人在北京,每次都把我定位到了一个叫“军诚水果超市”的地方。开始因为我听说高德的浏览器有很大偏差,以为是定位偏差的问题。但直到我注意到这里:(http://lbs.amap.com/api/javascript-api/reference/plugin/) 在AMap.Geolocation 插件中有这样一句话:当浏览器原生定位接口定位失败后,系统会调用IP定位,返回定位点所在城市中心点。此时,定位精度范围返回“null”。使用高德JS API浏览器定位,精度如果返回null就说明定位失败了,而不是定位偏差。(国内的文档太不规范,着实把我骗到了)

最后要说明的是,如果是开发Android原生软件的话,可以在APP里封装百度地图定位的SDK,这个是可以解决没有谷歌GMS服务包无法定位的问题的,因为百度地图定位SDK实际上是起到和谷歌服务包里面的定位模块一样的作用,由这里也可以看到HTML5 Webapp和原生APP的一个差别,不是一个层面的解决方案。

记得项目目录里的menifest.json文件里可以配置百度和高德的SDK么?这就是HTML5+API赋予你的强大能力!如果你配置正确的话,即可使用系统原生的定位,不需要坑爹的浏览器定位了。这就是Hybrid APP相对Web APP的一个优势。

最终解决方案是:配置好百度或高德的SDK,使用HTML5+API的plus.geolocation.getCurrentPosition()利用原生定位获取到坐标点后,再用百度或高德的JS API去实现其他的地图模块功能。

参考的文章:

http://www.html5col.com/getcurrentposition/

http://blog.csdn.net/albert528108/article/details/39213419

收起阅读 »

解决使用Mui索引列表“indexed-list-select” 动态加载数据后搜索失效问题

记得前不久刚用上Mui,感觉很赞,后来在开发中遇到一个问题,是关于使用Mui的索引列表的一个问题,因为官方示例数据都是纯静态演示数据,而我实际项目中的数据是需要根据不同的条件来动态加载数据,开发过程中发现动态加载进来的数据在搜索中失效,后来也在官网上提问过,当时问题的链接mui.indexedlist搜索功能失效问题,也有很多热心的网友给了回复,但都没有解决这个问题,后来自己利用空闲的时间去捣腾了一下,然后达到了效果,现在把他分享出来,希望能给遇到同样问题的人一点帮助,下载附件打开即可

继续阅读 »

记得前不久刚用上Mui,感觉很赞,后来在开发中遇到一个问题,是关于使用Mui的索引列表的一个问题,因为官方示例数据都是纯静态演示数据,而我实际项目中的数据是需要根据不同的条件来动态加载数据,开发过程中发现动态加载进来的数据在搜索中失效,后来也在官网上提问过,当时问题的链接mui.indexedlist搜索功能失效问题,也有很多热心的网友给了回复,但都没有解决这个问题,后来自己利用空闲的时间去捣腾了一下,然后达到了效果,现在把他分享出来,希望能给遇到同样问题的人一点帮助,下载附件打开即可

收起阅读 »

Android平台本地(离线)打包指南 - Android Studio

Android SDK App离线打包

新版离线sdk文档已发布,离线打包请参考最新文档

<!--

预备环境

  • AndroidStudio开发环境,要求安装Android4.0或以上(API 14)SDK。
  • 下载HBuilder离线打包Android版SDK(5+ SDK下载)。

离线打包SDK目录说明

  • HBuilder-Hello:离线打包演示应用;
  • HBuilder-Integrate: 5+ SDK 集成和插件开发示例
  • libs:SDK库文件目录;
  • Feature列表.xls:Android平台各扩展Feature API对应的permission;
  • Readme.txt:版本说明文件。

配置编译工程

  • 导入演示应用HBuilder-Hello工程
    启动AndroidStudio 点击导入工程“import project”


    选中工程所在目录点击“OK”

    选择生成的AndroidStudio工程的保存路径,然后点击“next”,

    在演示工程中已经配置好HelloH5应用相关资源,完成导入后,可Shift F10直接编译运行:

    从SDK目录中拷贝要使用的feature库到工程app/libs目录
    参考“Feature列表.xls”文档确定应用中使用到的扩展API,拷贝libs目录中对应的“jar”文件拷贝到工程的app->libs目录下,如果有引用“so”文件需要拷贝到工程的app->src->main->jniLibs下对应目录中。如使用分享功能(新浪微博分享、腾讯微博分享,微信分享),则需要拷贝以下文件:

    拷贝完成后在工程中刷新可在工程的libs目录下显示:

  • 配置应用的权限
    参考“Feature列表.xls”文档确定应用中使用到的扩展API,在AndroidManifest.xml文件中删除不用到API的权限。如不使用音频(plus.audio.*)相关5+ API,则可删除Audio相关的权限:

  • 配置其它第三方库的数据
    由于第三方库需要使用一些特定的数据,所以在使用时需要将相关参数配置到AndroidManifest.xml文件中。如使用分享功能,则需要配置各分享平台的申请应用的相关参数:


    如果不使用此类API,则可将此数据删除。
    插件的配置方法请参考以下文档
    Android离线打包插件配置
    推送插件配置
    分享插件配置
    登陆鉴权插件配置
    地图插件配置
    支付插件配置
    定位插件配置

  • <a id="version">配置应用的包名及版本号</a>
    打开AndroidManifest.xml文件,在代码视图中修改根节点的package属性值,如下:


    其中package为应用的包名,采用反向域名格式,为应用的标识;versionCode为应用的版本号(整数值),用于各应用市场的升级判断,建议与manifest.json中version -> code值一致;versionName为应用的版本名称(字符串),在系统应用管理程序中显示的版本号,建议与manifest.json中version -> name值一致。

  • <a id="name">配置应用名称</a>
    打开app->res -> values -> strings.xml文件,修改“app_name”字段值,该值为安装到手机上桌面显示的应用名称,建议与manifest.json中name(基础配置中的应用名称)对应:

  • <a id="channel">配置离线打包广告支持及渠道打包配置</a>
    新版本SDK简化了离线打包支持DCloud广告联盟功能。
    AndroidManifest.xml文件中添加如下节点到<application>节点中,并配置替换其中5+应用appid、广告联盟会员adid的值和渠道标识,因为涉及到开屏广告业务,项目工程必须以io.dcloud.PandoraEntry作为5+应用的入口Activity。该activity已包含在lib.5plus.base-release中,开发者无需实现

    <meta-data android:name="DCLOUD_AD_ID" android:value="广告标识"/>  
    <meta-data android:name="DCLOUD_AD_SPLASH" android:value="true"/><!--如果不开启开屏广告则不设置此字段或者值设置为false  
    <meta-data android:name="DCLOUD_STREAMAPP_CHANNEL" android:value="包名|应用标识|广告标识|渠道,如io.dcloud.appid|appid|adid|google" /><!--为了保证广告统计的有效性,请正确设置此值
    • 包名:对应Android项目中build.gradle中的applicationId,如io.dcloud.HBuilder
    • 应用标识:对应对应5+或uni-app项目manifest.json中appid
    • 广告标识:DCloud的广告标识,开通广告后可在dev.dcloud.net.cn获取,如果没有开通广告,设置值为空即可
    • 渠道:渠道包制作指南
      注意:提交谷歌应用市场(Google Play)时一定要将渠道标识设置为google!!!
      注意:以上操作只是配置5+应用具备广告能力,实际开通需要在manifest.json配置开关,具体参考DCloud广告联盟
      如果不需要支持广告,仍然可以使用WidgetWebView方式集成。
  • 配置应用图标和启动界面
    将应用的图标(文件名为icon.png)启动图片按照对应的尺寸拷贝到工程的app->src->main->res -> drawable-XXX目录下:

  • 更新应用资源
    打开app->src->main->assets -> apps 目录,将下面“HelloH5”目录名称修改为应用manifest.json中的id名称(这步非常重要,否则会导致应用无法正常启动),并将所有应用资源拷贝到其下的www目录中:

  • 配置应用信息
    打开app->src->main->assets -> data下的control.xml文件,修改appid和appver的值:


    其中appid值为HBuilder应用的appid,必须与应用manifest.json中的id值完全一致;appver为应用的版本号,用于应用资源的升级,必须保持与manifest.json中的version -> name值完全一致;version值为应用基座版本号(plus.runtime.innerVersion返回的值),不要随意修改。

  • 配置完成编译运行
    应用配置完毕,按Shift F10编译运行应用
    在弹出的设备列表对话框中选择要运行的设备:


    点击OK后启动应用:

常见问题

Q: 打包后页面中无法调用5+API
A: 修改app->build.gradle文件defaultConfig节点下miniSdkVersion和targetSdkVersion属性指定版本号为8

注意(新版已不需要添加):打包时如果修改APK的包名,则同时需要修改Rinfomation.java文件import的包名,
同时需要修改AndroidManifest.xml文件中引用包名的插件有
推送插件
微信(登陆,分享 ,支付),微信同时需要修改引入的WXEntryActivity.java和WXPayEntryActivity.java文件所在的包名

Q :使用Android Studio编译时如果提示如下错误

A:
下载附件并解压

点击下载
点击 Android Studio 菜单 File->Settings->Build,Execution,Development->Build Tools->Gradle选择Use local gradle distribution,选择附件解压后的目录点击OK即可

-->

继续阅读 »

新版离线sdk文档已发布,离线打包请参考最新文档

<!--

预备环境

  • AndroidStudio开发环境,要求安装Android4.0或以上(API 14)SDK。
  • 下载HBuilder离线打包Android版SDK(5+ SDK下载)。

离线打包SDK目录说明

  • HBuilder-Hello:离线打包演示应用;
  • HBuilder-Integrate: 5+ SDK 集成和插件开发示例
  • libs:SDK库文件目录;
  • Feature列表.xls:Android平台各扩展Feature API对应的permission;
  • Readme.txt:版本说明文件。

配置编译工程

  • 导入演示应用HBuilder-Hello工程
    启动AndroidStudio 点击导入工程“import project”


    选中工程所在目录点击“OK”

    选择生成的AndroidStudio工程的保存路径,然后点击“next”,

    在演示工程中已经配置好HelloH5应用相关资源,完成导入后,可Shift F10直接编译运行:

    从SDK目录中拷贝要使用的feature库到工程app/libs目录
    参考“Feature列表.xls”文档确定应用中使用到的扩展API,拷贝libs目录中对应的“jar”文件拷贝到工程的app->libs目录下,如果有引用“so”文件需要拷贝到工程的app->src->main->jniLibs下对应目录中。如使用分享功能(新浪微博分享、腾讯微博分享,微信分享),则需要拷贝以下文件:

    拷贝完成后在工程中刷新可在工程的libs目录下显示:

  • 配置应用的权限
    参考“Feature列表.xls”文档确定应用中使用到的扩展API,在AndroidManifest.xml文件中删除不用到API的权限。如不使用音频(plus.audio.*)相关5+ API,则可删除Audio相关的权限:

  • 配置其它第三方库的数据
    由于第三方库需要使用一些特定的数据,所以在使用时需要将相关参数配置到AndroidManifest.xml文件中。如使用分享功能,则需要配置各分享平台的申请应用的相关参数:


    如果不使用此类API,则可将此数据删除。
    插件的配置方法请参考以下文档
    Android离线打包插件配置
    推送插件配置
    分享插件配置
    登陆鉴权插件配置
    地图插件配置
    支付插件配置
    定位插件配置

  • <a id="version">配置应用的包名及版本号</a>
    打开AndroidManifest.xml文件,在代码视图中修改根节点的package属性值,如下:


    其中package为应用的包名,采用反向域名格式,为应用的标识;versionCode为应用的版本号(整数值),用于各应用市场的升级判断,建议与manifest.json中version -> code值一致;versionName为应用的版本名称(字符串),在系统应用管理程序中显示的版本号,建议与manifest.json中version -> name值一致。

  • <a id="name">配置应用名称</a>
    打开app->res -> values -> strings.xml文件,修改“app_name”字段值,该值为安装到手机上桌面显示的应用名称,建议与manifest.json中name(基础配置中的应用名称)对应:

  • <a id="channel">配置离线打包广告支持及渠道打包配置</a>
    新版本SDK简化了离线打包支持DCloud广告联盟功能。
    AndroidManifest.xml文件中添加如下节点到<application>节点中,并配置替换其中5+应用appid、广告联盟会员adid的值和渠道标识,因为涉及到开屏广告业务,项目工程必须以io.dcloud.PandoraEntry作为5+应用的入口Activity。该activity已包含在lib.5plus.base-release中,开发者无需实现

    <meta-data android:name="DCLOUD_AD_ID" android:value="广告标识"/>  
    <meta-data android:name="DCLOUD_AD_SPLASH" android:value="true"/><!--如果不开启开屏广告则不设置此字段或者值设置为false  
    <meta-data android:name="DCLOUD_STREAMAPP_CHANNEL" android:value="包名|应用标识|广告标识|渠道,如io.dcloud.appid|appid|adid|google" /><!--为了保证广告统计的有效性,请正确设置此值
    • 包名:对应Android项目中build.gradle中的applicationId,如io.dcloud.HBuilder
    • 应用标识:对应对应5+或uni-app项目manifest.json中appid
    • 广告标识:DCloud的广告标识,开通广告后可在dev.dcloud.net.cn获取,如果没有开通广告,设置值为空即可
    • 渠道:渠道包制作指南
      注意:提交谷歌应用市场(Google Play)时一定要将渠道标识设置为google!!!
      注意:以上操作只是配置5+应用具备广告能力,实际开通需要在manifest.json配置开关,具体参考DCloud广告联盟
      如果不需要支持广告,仍然可以使用WidgetWebView方式集成。
  • 配置应用图标和启动界面
    将应用的图标(文件名为icon.png)启动图片按照对应的尺寸拷贝到工程的app->src->main->res -> drawable-XXX目录下:

  • 更新应用资源
    打开app->src->main->assets -> apps 目录,将下面“HelloH5”目录名称修改为应用manifest.json中的id名称(这步非常重要,否则会导致应用无法正常启动),并将所有应用资源拷贝到其下的www目录中:

  • 配置应用信息
    打开app->src->main->assets -> data下的control.xml文件,修改appid和appver的值:


    其中appid值为HBuilder应用的appid,必须与应用manifest.json中的id值完全一致;appver为应用的版本号,用于应用资源的升级,必须保持与manifest.json中的version -> name值完全一致;version值为应用基座版本号(plus.runtime.innerVersion返回的值),不要随意修改。

  • 配置完成编译运行
    应用配置完毕,按Shift F10编译运行应用
    在弹出的设备列表对话框中选择要运行的设备:


    点击OK后启动应用:

常见问题

Q: 打包后页面中无法调用5+API
A: 修改app->build.gradle文件defaultConfig节点下miniSdkVersion和targetSdkVersion属性指定版本号为8

注意(新版已不需要添加):打包时如果修改APK的包名,则同时需要修改Rinfomation.java文件import的包名,
同时需要修改AndroidManifest.xml文件中引用包名的插件有
推送插件
微信(登陆,分享 ,支付),微信同时需要修改引入的WXEntryActivity.java和WXPayEntryActivity.java文件所在的包名

Q :使用Android Studio编译时如果提示如下错误

A:
下载附件并解压

点击下载
点击 Android Studio 菜单 File->Settings->Build,Execution,Development->Build Tools->Gradle选择Use local gradle distribution,选择附件解压后的目录点击OK即可

-->

收起阅读 »

首届流应用开发大赛名单揭晓,大众点评、京东、有道等获奖

流应用

由DCloud、36氪、CSDN联合举办的首届中国流应用开发大赛,经过一个月的选拨和评选,获奖名单正式揭晓。活动期间,数百人报名参赛,无论是一线互联网公司如大众点评、京东、网易,还是创业公司,如挑食火锅、艺人捧场,都积极开发流应用,流应用在营销、用户和订单获取、开发成本节约等方面的价值成功的吸引了App厂商。

本次大赛的中奖名单如下:

一、优秀应用奖
获奖名单(4名):
大众点评外卖、大众点评爱美丽、有道词典、京东秒杀
奖励:应用商店价值5万元的推广资源

二、优秀创业奖
获奖名单(4名):
挑食火锅、宝贝租车、艺人捧场,弈客围棋
奖励:知名创业媒体36氪提供的融资平台三天banner展示位广告资源,知名投资人约见机会。

提示:体验获奖流应用的方式:使用安装360手机助手的安卓手机,点击下面的图片链接,根据提示在外部浏览器中打开,即可体验。

1.大众点评外卖

流应用体验二维码

2.大众点评爱美丽

流应用体验二维码

3.有道词典

流应用体验二维码

4.京东秒杀

流应用体验二维码

5.挑食火锅

流应用体验二维码

6.宝贝租车

流应用体验二维码

7.艺人捧场

流应用体验二维码

8.弈客围棋

除了上述获奖的App,还有很多创业者开发了体验优质的流应用,如HiMall、枫桥居花卉等。

优秀创业者获得36Kr融资频道Banner宣传:

关于流应用:流应用是DCloud公司开发的一种可以让手机App安装包实现边用边下的技术。利用js的动态语言特点,把手机端App的安装包拆解,流式下载到手机端。类似流媒体边看边下一样,流应用也可以边用边下。再辅以特殊的压缩解码技术,使得流应用可以在5秒内完成App的下载-安装-启动全过程。流应用使用的js经过了强化,可以调用原生40多万API,使得流应用的功能和体验都达到了原生水准。
本次流应用大赛之所以受到众多开发者如此关注,主要得益于流应用具有的开发者优势和用户优势。

在开发者优势方面:

1.降低App的开发成本和人员数量,原来App厂商需要iOS、Android、前端等三个开发团队,流应用只需要1个前端开发即可完成,并且还能打包成原生App以及发布为wap网站和公众号。高效率本就是世界进步发展趋势,在资本寒冬的今天,尤其需要这种高效率开发方案。

2.降低推广成本提高转化率,推广成本降低50-80%。原生App由于安装包比较大,从下载、到安装、到启动,使得推广成本非常高,而流应用从下载到安装启动一步到位,5秒内即可完成,使得App的推广成本降低,转化率提升50%-80%。

3.多端发布,方便测试。流应用基于mui开发App,生成流应用的同时,iOS、Android原生版、浏览器版、微信App和百度直达号版也随之生成,开发一次,多端发布,效率大幅提升,成本大幅下降。

在用户优势方面,流应用具有如下五大特点:

1.秒装秒开:流应用具有秒装秒开的功能,使得用户在下载安装的时候,5秒内即可安装启动,速度非常快。
2.差量实时更新:流应用采用自动差量更新技术,每次更新只需要2-3K流量,使得用户永远使用的都是最新版本的流应用,和原生应用更新相比,每次更新都需要重新下载安装包,启动一次来说,用户体验非常好。
3.省流量:流应用具有很多缩小应用包的专利技术,能大幅减少应用包体积,但毫不影响应用功能体验。。

  1. 省空间:流应用的安装包只有几百K,和原生App几十M,几百M的App相比,非常小,装一个原生App的空间可以装几十个流应用,流应用更加节省空间。
    5.省电更流畅:流应用采用了包体压缩技术、差量更新技术,使得流应用对手机的内存、空间占用率非常少,非常省电,同时也更加流畅。

虽然本次大赛结束了,但流应用发展还在继续。后续提交流应用的开发者还有机会获得由DCloud提供的应用商店推广资源和机械键盘等奖励礼品,欢迎大家继续提交流应用。流应用交流QQ群:471285299。

继续阅读 »

由DCloud、36氪、CSDN联合举办的首届中国流应用开发大赛,经过一个月的选拨和评选,获奖名单正式揭晓。活动期间,数百人报名参赛,无论是一线互联网公司如大众点评、京东、网易,还是创业公司,如挑食火锅、艺人捧场,都积极开发流应用,流应用在营销、用户和订单获取、开发成本节约等方面的价值成功的吸引了App厂商。

本次大赛的中奖名单如下:

一、优秀应用奖
获奖名单(4名):
大众点评外卖、大众点评爱美丽、有道词典、京东秒杀
奖励:应用商店价值5万元的推广资源

二、优秀创业奖
获奖名单(4名):
挑食火锅、宝贝租车、艺人捧场,弈客围棋
奖励:知名创业媒体36氪提供的融资平台三天banner展示位广告资源,知名投资人约见机会。

提示:体验获奖流应用的方式:使用安装360手机助手的安卓手机,点击下面的图片链接,根据提示在外部浏览器中打开,即可体验。

1.大众点评外卖

流应用体验二维码

2.大众点评爱美丽

流应用体验二维码

3.有道词典

流应用体验二维码

4.京东秒杀

流应用体验二维码

5.挑食火锅

流应用体验二维码

6.宝贝租车

流应用体验二维码

7.艺人捧场

流应用体验二维码

8.弈客围棋

除了上述获奖的App,还有很多创业者开发了体验优质的流应用,如HiMall、枫桥居花卉等。

优秀创业者获得36Kr融资频道Banner宣传:

关于流应用:流应用是DCloud公司开发的一种可以让手机App安装包实现边用边下的技术。利用js的动态语言特点,把手机端App的安装包拆解,流式下载到手机端。类似流媒体边看边下一样,流应用也可以边用边下。再辅以特殊的压缩解码技术,使得流应用可以在5秒内完成App的下载-安装-启动全过程。流应用使用的js经过了强化,可以调用原生40多万API,使得流应用的功能和体验都达到了原生水准。
本次流应用大赛之所以受到众多开发者如此关注,主要得益于流应用具有的开发者优势和用户优势。

在开发者优势方面:

1.降低App的开发成本和人员数量,原来App厂商需要iOS、Android、前端等三个开发团队,流应用只需要1个前端开发即可完成,并且还能打包成原生App以及发布为wap网站和公众号。高效率本就是世界进步发展趋势,在资本寒冬的今天,尤其需要这种高效率开发方案。

2.降低推广成本提高转化率,推广成本降低50-80%。原生App由于安装包比较大,从下载、到安装、到启动,使得推广成本非常高,而流应用从下载到安装启动一步到位,5秒内即可完成,使得App的推广成本降低,转化率提升50%-80%。

3.多端发布,方便测试。流应用基于mui开发App,生成流应用的同时,iOS、Android原生版、浏览器版、微信App和百度直达号版也随之生成,开发一次,多端发布,效率大幅提升,成本大幅下降。

在用户优势方面,流应用具有如下五大特点:

1.秒装秒开:流应用具有秒装秒开的功能,使得用户在下载安装的时候,5秒内即可安装启动,速度非常快。
2.差量实时更新:流应用采用自动差量更新技术,每次更新只需要2-3K流量,使得用户永远使用的都是最新版本的流应用,和原生应用更新相比,每次更新都需要重新下载安装包,启动一次来说,用户体验非常好。
3.省流量:流应用具有很多缩小应用包的专利技术,能大幅减少应用包体积,但毫不影响应用功能体验。。

  1. 省空间:流应用的安装包只有几百K,和原生App几十M,几百M的App相比,非常小,装一个原生App的空间可以装几十个流应用,流应用更加节省空间。
    5.省电更流畅:流应用采用了包体压缩技术、差量更新技术,使得流应用对手机的内存、空间占用率非常少,非常省电,同时也更加流畅。

虽然本次大赛结束了,但流应用发展还在继续。后续提交流应用的开发者还有机会获得由DCloud提供的应用商店推广资源和机械键盘等奖励礼品,欢迎大家继续提交流应用。流应用交流QQ群:471285299。

收起阅读 »

Android 平台5+SDK接口说明

集成 Android SDK

查看Android平台5+SDK API参考手册请点击

初始化SDK

initSDK(ICore core)

说明:
初始化SDK, SDK所有接口必须在初始化之后才可以调用
参数:

  • core(ICore ) 5+内核对象

示例

    @Override  
    public void onCoreReady(ICore coreHandler) {  
        try {  
            SDK.initSDK(coreHandler);  
            SDK.requestAllFeature();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

SDK集成使用方法

IApp startWebApp(Activity activity,String appBasePath,String startArgs,IWebviewStateListener listener,IOnCreateSplashView ocs)

说明:
创建并启动5+WebApp对象
参数:

  • activity(Activity) Activity对象
  • appBasePath(String) 移动应用所在的目录
  • startArgs(String) 应用启动时传递的参数
  • listener(IWebviewStateListener) Webview事件监听对象,用来监听应用的首页面加载状态
  • ocs(IOnCreateSplashView) Splash事件监听对象,用来监听splash页面的加载和关闭事件

示例

    public void onCoreInitEnd(ICore coreHandler) {  

        //创建默认webapp,  
        String appBasePath = "/apps/HelloH5";//表示 file:///android_asset/apps/HBuilder  
        String args = "{url:'http://www.baidu.com'}";//设置启动参数  

        app = SDK.startWebApp(activity,appBasePath, args, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  

                switch (pType) {  
                case IWebviewStateListener.ON_WEBVIEW_READY:  
                    //准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                    View view = ((IWebview)pArgs).obtainApp().obtainWebAppRootView().obtainMainView();  
                    view.setVisibility(View.INVISIBLE);  
                    rootView.addView(view, 0);  
                    break;  
                case IWebviewStateListener.ON_PAGE_STARTED:  
                    break;  
                case IWebviewStateListener.ON_PROGRESS_CHANGED:  
                    break;  
                case IWebviewStateListener.ON_PAGE_FINISHED:  
                    //页面加载完毕,设置显示webview  
                    app.obtainWebAppRootView().obtainMainView().setVisibility(View.VISIBLE);  
                    break;  
                }  
                return null;  
            }  
        },this);  
    }

IWebview createWebview(Activity activity,String pagePath,String basePath,String docPath,String appid, String appName,IWebviewStateListener listener)

说明:
创建一个支持5+API的Webview对象
参数:

  • activity(Activity) Activity对象
  • pagePath(String) 页面路径
  • basePath(String) 应用的默认路径
  • docPath(String) 应用的doc目录路径
  • appid(String) 应用的appid
  • appName(String) 应用名称
  • listener(IWebviewStateListener) 加载事件监听器

示例:

public void onCoreInitEnd(ICore coreHandler) {  
        //设置单页面集成的appid  
        String appid = "test1";  
        // 单页面集成时要加载页面的路径,可以是本地文件路径也可以是网络路径  
        String url = "file:///android_asset/apps/H5Plugin/www/index.html";  
        webview = SDK.createWebview(activity, url, appid, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  
                switch (pType) {  
                case IWebviewStateListener.ON_WEBVIEW_READY:  
                    // 准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                    ((IWebview) pArgs).obtainFrameView().obtainMainView().setVisibility(View.INVISIBLE);  
                    SDK.attach(mRootView, ((IWebview) pArgs));  
                    break;  
                case IWebviewStateListener.ON_PAGE_STARTED:                   
                    break;  
                case IWebviewStateListener.ON_PROGRESS_CHANGED:                   
                    break;  
                case IWebviewStateListener.ON_PAGE_FINISHED:                      
                    // 页面加载完毕,设置显示webview  
                    webview.obtainFrameView().obtainMainView().setVisibility(View.VISIBLE);  
                    break;  
                }  
                return null;  
            }  
        });  

    }

IWebview createWebview(Activity activity,String pagePath,String appid,IWebviewStateListener listener)

说明:
创建一个支持5+API的Webview对象
参数:

  • activity(Activity) Activity对象
  • pagePath(String) HTML页面的路径
  • appid(String) 默认应用的APPID
  • listener(IWebviewStateListener) 页面加载事件监听器

WebApp相关方法

void stopWebApp(IApp app)

说明:
停止一个正在运行的5+WebApp
参数:
app(IApp) 正在运行的WebAPP对象

String obtainCurrentRunnbingAppId()

说明:
获取当前正在运行的5+WebApp的APPID

IApp obtainCurrentApp ()

说明:
获取到当前在前台运行的5+Webapp对象

页面相关方法

ArrayList<IWebview> obtainAllIWebview()

说明:
获取运行应用的Webview对象的集合

IWebview obtainWebview(String appid,String webviewId)

说明:
根据APPID和WebviewID获取到指定的Webview对象
参数:

  • appid(String) 要获取应用的APPID
  • webviewId(String) 获取应用内页面的ID

IWebview obatinFirstPage(IApp app,IWebviewStateListener listener)

说明:
获取指定应用app的首页面Iwebview对象
参数:

  • app(IApp) IApp对象
  • listener(IWebviewStateListener) 应用首页面的加载状态的监听

void closeWebView(IWebview webview)

说明:
关闭指定IWebview页面
参数:

  • webview(IWebview)

设置可使用的5+API权限

void requestAllFeature()

说明:
向5+基座申请全部扩展API调用能力
示例

public void onCoreReady(ICore coreHandler) {  
        try {  
            SDK.initSDK(coreHandler);  
            SDK.requestAllFeature();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

void requestFeature(String mainFeatureName,String subFeatrureName,boolean autoBoot)

说明
单独设置可以使用的API特征名
参数

  • mainFeatureName(String) JS 特征名称
  • subFeatrureName(String) JS特征二级名称
  • autoBoot(boolean) 是否基座自动启动

示例

requestFeature("Share","share-weixin",false);

注册新扩展插件

void registerJsApi(String featureName,String className,String jsContent)

说明:
向5+SDK注册一个新的扩展API
参数:

  • featureName(String) 扩展插件的JS功能名称
  • className(String) 扩展插件的原生类名
  • jsContent(String) 扩展插件的JS代码

示例

    // 注册新的5+扩展API  
    private void regNewJsAPI() {  
        // 扩展插件的JS特征名称  
        String featureName = "T";  
        // 为处理扩展Feature的接收类全名称  
        String className = "com.HBuilder.integrate.webview.WebViewMode_FeatureImpl";  
        // content 为扩展Feature而创建的js代码  
        String content = "(function(plus){function test(){return plus.bridge.execSync('T','test',[arguments]);}plus.T = {test:test};})(window.plus);";  
        // 注册新的扩展方法  
        SDK.registerJsApi(featureName, className, content);  
    }  
继续阅读 »

查看Android平台5+SDK API参考手册请点击

初始化SDK

initSDK(ICore core)

说明:
初始化SDK, SDK所有接口必须在初始化之后才可以调用
参数:

  • core(ICore ) 5+内核对象

示例

    @Override  
    public void onCoreReady(ICore coreHandler) {  
        try {  
            SDK.initSDK(coreHandler);  
            SDK.requestAllFeature();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

SDK集成使用方法

IApp startWebApp(Activity activity,String appBasePath,String startArgs,IWebviewStateListener listener,IOnCreateSplashView ocs)

说明:
创建并启动5+WebApp对象
参数:

  • activity(Activity) Activity对象
  • appBasePath(String) 移动应用所在的目录
  • startArgs(String) 应用启动时传递的参数
  • listener(IWebviewStateListener) Webview事件监听对象,用来监听应用的首页面加载状态
  • ocs(IOnCreateSplashView) Splash事件监听对象,用来监听splash页面的加载和关闭事件

示例

    public void onCoreInitEnd(ICore coreHandler) {  

        //创建默认webapp,  
        String appBasePath = "/apps/HelloH5";//表示 file:///android_asset/apps/HBuilder  
        String args = "{url:'http://www.baidu.com'}";//设置启动参数  

        app = SDK.startWebApp(activity,appBasePath, args, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  

                switch (pType) {  
                case IWebviewStateListener.ON_WEBVIEW_READY:  
                    //准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                    View view = ((IWebview)pArgs).obtainApp().obtainWebAppRootView().obtainMainView();  
                    view.setVisibility(View.INVISIBLE);  
                    rootView.addView(view, 0);  
                    break;  
                case IWebviewStateListener.ON_PAGE_STARTED:  
                    break;  
                case IWebviewStateListener.ON_PROGRESS_CHANGED:  
                    break;  
                case IWebviewStateListener.ON_PAGE_FINISHED:  
                    //页面加载完毕,设置显示webview  
                    app.obtainWebAppRootView().obtainMainView().setVisibility(View.VISIBLE);  
                    break;  
                }  
                return null;  
            }  
        },this);  
    }

IWebview createWebview(Activity activity,String pagePath,String basePath,String docPath,String appid, String appName,IWebviewStateListener listener)

说明:
创建一个支持5+API的Webview对象
参数:

  • activity(Activity) Activity对象
  • pagePath(String) 页面路径
  • basePath(String) 应用的默认路径
  • docPath(String) 应用的doc目录路径
  • appid(String) 应用的appid
  • appName(String) 应用名称
  • listener(IWebviewStateListener) 加载事件监听器

示例:

public void onCoreInitEnd(ICore coreHandler) {  
        //设置单页面集成的appid  
        String appid = "test1";  
        // 单页面集成时要加载页面的路径,可以是本地文件路径也可以是网络路径  
        String url = "file:///android_asset/apps/H5Plugin/www/index.html";  
        webview = SDK.createWebview(activity, url, appid, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  
                switch (pType) {  
                case IWebviewStateListener.ON_WEBVIEW_READY:  
                    // 准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                    ((IWebview) pArgs).obtainFrameView().obtainMainView().setVisibility(View.INVISIBLE);  
                    SDK.attach(mRootView, ((IWebview) pArgs));  
                    break;  
                case IWebviewStateListener.ON_PAGE_STARTED:                   
                    break;  
                case IWebviewStateListener.ON_PROGRESS_CHANGED:                   
                    break;  
                case IWebviewStateListener.ON_PAGE_FINISHED:                      
                    // 页面加载完毕,设置显示webview  
                    webview.obtainFrameView().obtainMainView().setVisibility(View.VISIBLE);  
                    break;  
                }  
                return null;  
            }  
        });  

    }

IWebview createWebview(Activity activity,String pagePath,String appid,IWebviewStateListener listener)

说明:
创建一个支持5+API的Webview对象
参数:

  • activity(Activity) Activity对象
  • pagePath(String) HTML页面的路径
  • appid(String) 默认应用的APPID
  • listener(IWebviewStateListener) 页面加载事件监听器

WebApp相关方法

void stopWebApp(IApp app)

说明:
停止一个正在运行的5+WebApp
参数:
app(IApp) 正在运行的WebAPP对象

String obtainCurrentRunnbingAppId()

说明:
获取当前正在运行的5+WebApp的APPID

IApp obtainCurrentApp ()

说明:
获取到当前在前台运行的5+Webapp对象

页面相关方法

ArrayList<IWebview> obtainAllIWebview()

说明:
获取运行应用的Webview对象的集合

IWebview obtainWebview(String appid,String webviewId)

说明:
根据APPID和WebviewID获取到指定的Webview对象
参数:

  • appid(String) 要获取应用的APPID
  • webviewId(String) 获取应用内页面的ID

IWebview obatinFirstPage(IApp app,IWebviewStateListener listener)

说明:
获取指定应用app的首页面Iwebview对象
参数:

  • app(IApp) IApp对象
  • listener(IWebviewStateListener) 应用首页面的加载状态的监听

void closeWebView(IWebview webview)

说明:
关闭指定IWebview页面
参数:

  • webview(IWebview)

设置可使用的5+API权限

void requestAllFeature()

说明:
向5+基座申请全部扩展API调用能力
示例

public void onCoreReady(ICore coreHandler) {  
        try {  
            SDK.initSDK(coreHandler);  
            SDK.requestAllFeature();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

void requestFeature(String mainFeatureName,String subFeatrureName,boolean autoBoot)

说明
单独设置可以使用的API特征名
参数

  • mainFeatureName(String) JS 特征名称
  • subFeatrureName(String) JS特征二级名称
  • autoBoot(boolean) 是否基座自动启动

示例

requestFeature("Share","share-weixin",false);

注册新扩展插件

void registerJsApi(String featureName,String className,String jsContent)

说明:
向5+SDK注册一个新的扩展API
参数:

  • featureName(String) 扩展插件的JS功能名称
  • className(String) 扩展插件的原生类名
  • jsContent(String) 扩展插件的JS代码

示例

    // 注册新的5+扩展API  
    private void regNewJsAPI() {  
        // 扩展插件的JS特征名称  
        String featureName = "T";  
        // 为处理扩展Feature的接收类全名称  
        String className = "com.HBuilder.integrate.webview.WebViewMode_FeatureImpl";  
        // content 为扩展Feature而创建的js代码  
        String content = "(function(plus){function test(){return plus.bridge.execSync('T','test',[arguments]);}plus.T = {test:test};})(window.plus);";  
        // 注册新的扩展方法  
        SDK.registerJsApi(featureName, className, content);  
    }  
收起阅读 »

chrome://inspect调试html页面空白,DOM无法加载的解决方案

控制台调试 chrome

chrome://inspect调试html页面空白,DOM无法加载的解决方案

先描述一下问题

有一段时间没碰huilder hybird app 开发了,今天调试的时候  
chrome://inspect/#devices  
可以发现页面,但是打开后空白  

解决方案

翻墙后就可以了,下次就不需要翻墙了  

估计原因

1.chrome升级后原有配置失效  
2.浏览器缓存被软件管家清掉了
继续阅读 »

chrome://inspect调试html页面空白,DOM无法加载的解决方案

先描述一下问题

有一段时间没碰huilder hybird app 开发了,今天调试的时候  
chrome://inspect/#devices  
可以发现页面,但是打开后空白  

解决方案

翻墙后就可以了,下次就不需要翻墙了  

估计原因

1.chrome升级后原有配置失效  
2.浏览器缓存被软件管家清掉了
收起阅读 »

android studio 的离线打包指南在哪里?不会只有 eclipse ADT 吧?

能不能请官方出个 android studio 的离线打包指南?

android studio 都已经出几年了,也是 google 官方指定的使用的 IDE
没道理只有 eclipse ADT bundle 离线打包 的指南吧?

能不能请官方出个 android studio 的离线打包指南?

android studio 都已经出几年了,也是 google 官方指定的使用的 IDE
没道理只有 eclipse ADT bundle 离线打包 的指南吧?

【分享】一个Notification 进度条插件(android,NJS实现,直接就可使用)

NJS 通知栏显示进度 通知栏 通知栏进度条

如题,分享一个Notification 进度条插件(android,用js调用原生api实现,直接就可以使用).
参考1: http://ask.dcloud.net.cn/article/155
参考2:http://ask.dcloud.net.cn/question/2464

详细介绍: 最近有一个需求是,android更新资源包时,需要在通知栏里显示下载进度条,于是就搜索了下已有的解决方案
发现并没有现成的解决方案,于是参考了以上两个解决方案,结合了下,实现了直接能调用的js插件.

第一步(分析以上两种方案的缺陷):
第一种:功能上能实现需求,但是使用起来太麻烦,而且也不方便调试(需要离线打包后才能看到效果),
而且,我这里还遇到了一个问题,在 hbuild 6.9.2 中,我明明已经添加了自定义模块权限,但是却一直提示我 ***权限没有添加, 真的是把我弄的吐血了, 所以没办法,只能另谋他路.

第二种:使用起来很方便,但是却没有完全达到功能要求(只显示了普通通知,但没有显示进度条),而且在api <16 的机子上会报错.
于是在这个基础上,结合第一种方法.写了一个 工具类,实现android的通知栏控制(兼容了api11-16的通知显示)

源码:

/**  
 * @description njs实现android原生功能   
 * 1.通知栏消息  
 * @see http://ask.dcloud.net.cn/article/503  
 *   
 * @author dailc  
 * @version 1.0  
 * @time 2016-01-08 08:38:20  
 */  
(function(obj) {  
    var defaultTitle = '通知栏标题';  
    var defaultContent = '通知内容';  
    var defaultTicker = '通知提示';  
    var defaultNotifyId = 1000;  
    var defaultNumber = 1;  
    /**  
     * plusReady  
     * @param {type} callback  
     * @returns {Window}  
     */  
    obj.plusReady = function(callback) {  
        if (window.plus) {  
            setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)  
                callback();  
            }, 0);  
        } else {  
            document.addEventListener("plusready", function() {  
                callback();  
            }, false);  
        }  
        return this;  
    };  
    /**  
     * @description 比较两个版本大小  
     * 比较版本大小,如果新版本nowVersion大于旧版本OldResourceVersion则返回true,否则返回false  
     */  
    function compareVersion(OldVersion, nowVersion) {  
        if (!OldVersion || !nowVersion || OldVersion == '' || nowVersion == '') {  

            return false;  
        }  
        //第二份参数 是 数组的最大长度  
        var OldVersionA = OldVersion.split(".", 4);  
        var nowVersionA = nowVersion.split(".", 4);  
        for (var i = 0; i < OldVersionA.length && i < nowVersionA.length; i++) {  
            var strOld = OldVersionA[i];  
            var numOld = parseInt(strOld);  
            var strNow = nowVersionA[i];  
            var numNow = parseInt(strNow);  
            //小版本到高版本  
            if (numNow > numOld  
                //||strNow.length>strOld.length  
            ) {  
                return true;  
            } else if (numNow < numOld) {  
                return false;  
            }  
        }  
        //如果是版本  如 1.6 - 1.6.1  
        if (nowVersionA.length > OldVersionA.length && 0 == nowVersion.indexOf(OldVersion)) {  
            return true;  
        }  
    };  
    /**  
     * @description 通过push功能来推送消息  
     */  
    obj.sendNotificationByPush = function() {  
        var options = {  
            cover: false  
        };  
        var str = ": 欢迎使用Html5 Plus创建本地消息!";  
        plus.push.createMessage(str, "LocalMSG", options);  
    };  
    (function() {  
        /**  
         * @constructor 创建通知栏进度条构造函数  
         */  
        function NotificationCustom() {  
            if (plus.os.name != 'Android') {  
                return;  
            }  
            //当前版本号  
            var SystemVersion = plus.os.version;  
            var Context = plus.android.importClass("android.content.Context");  
            var main = plus.android.runtimeMainActivity();  
            var NotificationManager = plus.android.importClass("android.app.NotificationManager");  
            var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)  
                // Notification build 要android api16以上才能使用(4.1.2以上)  
            var Notification = null;  
            if (compareVersion('4.1.1', SystemVersion) == true) {  
                Notification = plus.android.importClass("android.app.Notification");  
            } else {  
                Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");  
            }  
            if (Notification) {  
                this.notifyManager = nm;  
                this.mNotificationBuild = new Notification.Builder(main);  
                //设为true代表常驻状态栏  
                this.mNotificationBuild.setOngoing(false);  
                this.mNotificationBuild.setContentTitle(defaultTitle);  
                this.mNotificationBuild.setContentText(defaultContent);  
                this.mNotificationBuild.setTicker(defaultTicker);  
                //默认的push图标  
                this.mNotificationBuild.setSmallIcon(17301620);  
                //设置默认声音  
                //console.log('默认:'+plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
                this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
                //this.mNotificationBuild.setNumber(defaultNumber)  
            }  
        };  
        /**  
         * @description 给android通知栏发送通知  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.setNotification = function(title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || defaultTitle;  
            content = content || defaultContent;  
            tickerTips = tickerTips || defaultTicker;  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            //默认有声音  
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 设置进度条  
         * @param {Number} progress  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.setProgress = function(progress, title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || '正在下载';  
            content = content || '正在下载';  
            tickerTips = tickerTips || '进度提示';  
            //          tickerTips = tickerTips || defaultTicker;  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            //进度条显示时,默认无声音  
            this.mNotificationBuild.setDefaults(0);  
            this.mNotificationBuild.setProgress(100, progress, false);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 完成进度条  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.compProgressNotification = function(title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || '进度条显示完毕';  
            content = content || '进度条显示完毕';  
            tickerTips = tickerTips || '进度提示';  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            this.mNotificationBuild.setProgress(0, 0, false);  
            //默认有声音  
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 清除通知栏信息  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.clearNotification = function(notifyId) {  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            if(this.notifyManager){  
                this.notifyManager.cancel(notifyId);  
            }         
        };  
        /**  
         * @description 清除所有通知栏信息  
         */  
        NotificationCustom.prototype.clearAllNotification = function() {  
            if(this.notifyManager){  
                this.notifyManager.cancelAll();  
            }         
        };  
        obj.plusReady(function() {  
            obj.NotificationUtil = new NotificationCustom();  
        });  
    })();  

})(window.NjsPhoneApi = {});

调用方法示例:
显示普通通知:

NjsPhoneApi.NotificationUtil.setNotification('测试标题'+staticI,'测试内容');

显示进度条代码:

function testProgress() {  
        //插件调用  
        NjsPhoneApi.NotificationUtil.setNotification("新版下载", "开始下载");  
        var current = 0;  
        NjsPhoneApi.NotificationUtil.setProgress(current); //插件调用  
        function progress() {  
            setTimeout(function() {  
                current += 1;  
                NjsPhoneApi.NotificationUtil.setProgress(current);  
                if(current>=100){  
                     NjsPhoneApi.NotificationUtil.compProgressNotification("下载完成");  
                }else{  
                    progress();  
                }  
            }, 100);  
        };  
        progress();  
    };  
testProgress();//调用显示进度条

取消单条通知:(传入参数为id,不传采用默认id)

NjsPhoneApi.NotificationUtil.clearNotification();

取消所有通知:

NjsPhoneApi.NotificationUtil.clearAllNotification();

另外: 支持自定义id的通知,也就是说可以通过传入不同的id,同时显示不同的通知

效果图1:
效果图2:
示例源码:鉴于有一些朋友会有各式各样的奇怪错误,所以这里单独写了一个示例,测试了android机型(华为,联想)都是可以正常使用的.
示例源码中采用的是默认id

继续阅读 »

如题,分享一个Notification 进度条插件(android,用js调用原生api实现,直接就可以使用).
参考1: http://ask.dcloud.net.cn/article/155
参考2:http://ask.dcloud.net.cn/question/2464

详细介绍: 最近有一个需求是,android更新资源包时,需要在通知栏里显示下载进度条,于是就搜索了下已有的解决方案
发现并没有现成的解决方案,于是参考了以上两个解决方案,结合了下,实现了直接能调用的js插件.

第一步(分析以上两种方案的缺陷):
第一种:功能上能实现需求,但是使用起来太麻烦,而且也不方便调试(需要离线打包后才能看到效果),
而且,我这里还遇到了一个问题,在 hbuild 6.9.2 中,我明明已经添加了自定义模块权限,但是却一直提示我 ***权限没有添加, 真的是把我弄的吐血了, 所以没办法,只能另谋他路.

第二种:使用起来很方便,但是却没有完全达到功能要求(只显示了普通通知,但没有显示进度条),而且在api <16 的机子上会报错.
于是在这个基础上,结合第一种方法.写了一个 工具类,实现android的通知栏控制(兼容了api11-16的通知显示)

源码:

/**  
 * @description njs实现android原生功能   
 * 1.通知栏消息  
 * @see http://ask.dcloud.net.cn/article/503  
 *   
 * @author dailc  
 * @version 1.0  
 * @time 2016-01-08 08:38:20  
 */  
(function(obj) {  
    var defaultTitle = '通知栏标题';  
    var defaultContent = '通知内容';  
    var defaultTicker = '通知提示';  
    var defaultNotifyId = 1000;  
    var defaultNumber = 1;  
    /**  
     * plusReady  
     * @param {type} callback  
     * @returns {Window}  
     */  
    obj.plusReady = function(callback) {  
        if (window.plus) {  
            setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)  
                callback();  
            }, 0);  
        } else {  
            document.addEventListener("plusready", function() {  
                callback();  
            }, false);  
        }  
        return this;  
    };  
    /**  
     * @description 比较两个版本大小  
     * 比较版本大小,如果新版本nowVersion大于旧版本OldResourceVersion则返回true,否则返回false  
     */  
    function compareVersion(OldVersion, nowVersion) {  
        if (!OldVersion || !nowVersion || OldVersion == '' || nowVersion == '') {  

            return false;  
        }  
        //第二份参数 是 数组的最大长度  
        var OldVersionA = OldVersion.split(".", 4);  
        var nowVersionA = nowVersion.split(".", 4);  
        for (var i = 0; i < OldVersionA.length && i < nowVersionA.length; i++) {  
            var strOld = OldVersionA[i];  
            var numOld = parseInt(strOld);  
            var strNow = nowVersionA[i];  
            var numNow = parseInt(strNow);  
            //小版本到高版本  
            if (numNow > numOld  
                //||strNow.length>strOld.length  
            ) {  
                return true;  
            } else if (numNow < numOld) {  
                return false;  
            }  
        }  
        //如果是版本  如 1.6 - 1.6.1  
        if (nowVersionA.length > OldVersionA.length && 0 == nowVersion.indexOf(OldVersion)) {  
            return true;  
        }  
    };  
    /**  
     * @description 通过push功能来推送消息  
     */  
    obj.sendNotificationByPush = function() {  
        var options = {  
            cover: false  
        };  
        var str = ": 欢迎使用Html5 Plus创建本地消息!";  
        plus.push.createMessage(str, "LocalMSG", options);  
    };  
    (function() {  
        /**  
         * @constructor 创建通知栏进度条构造函数  
         */  
        function NotificationCustom() {  
            if (plus.os.name != 'Android') {  
                return;  
            }  
            //当前版本号  
            var SystemVersion = plus.os.version;  
            var Context = plus.android.importClass("android.content.Context");  
            var main = plus.android.runtimeMainActivity();  
            var NotificationManager = plus.android.importClass("android.app.NotificationManager");  
            var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)  
                // Notification build 要android api16以上才能使用(4.1.2以上)  
            var Notification = null;  
            if (compareVersion('4.1.1', SystemVersion) == true) {  
                Notification = plus.android.importClass("android.app.Notification");  
            } else {  
                Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");  
            }  
            if (Notification) {  
                this.notifyManager = nm;  
                this.mNotificationBuild = new Notification.Builder(main);  
                //设为true代表常驻状态栏  
                this.mNotificationBuild.setOngoing(false);  
                this.mNotificationBuild.setContentTitle(defaultTitle);  
                this.mNotificationBuild.setContentText(defaultContent);  
                this.mNotificationBuild.setTicker(defaultTicker);  
                //默认的push图标  
                this.mNotificationBuild.setSmallIcon(17301620);  
                //设置默认声音  
                //console.log('默认:'+plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
                this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
                //this.mNotificationBuild.setNumber(defaultNumber)  
            }  
        };  
        /**  
         * @description 给android通知栏发送通知  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.setNotification = function(title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || defaultTitle;  
            content = content || defaultContent;  
            tickerTips = tickerTips || defaultTicker;  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            //默认有声音  
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 设置进度条  
         * @param {Number} progress  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.setProgress = function(progress, title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || '正在下载';  
            content = content || '正在下载';  
            tickerTips = tickerTips || '进度提示';  
            //          tickerTips = tickerTips || defaultTicker;  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            //进度条显示时,默认无声音  
            this.mNotificationBuild.setDefaults(0);  
            this.mNotificationBuild.setProgress(100, progress, false);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 完成进度条  
         * @param {String} title 标题  
         * @param {String} content  内容  
         * @param {String} tickerTips  提示  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.compProgressNotification = function(title, content, tickerTips,notifyId) {  
            if (this.mNotificationBuild == null ||  
                this.notifyManager == null) {  
                return;  
            }  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            title = title || '进度条显示完毕';  
            content = content || '进度条显示完毕';  
            tickerTips = tickerTips || '进度提示';  
            this.mNotificationBuild.setContentTitle(title);  
            this.mNotificationBuild.setContentText(content);  
            this.mNotificationBuild.setTicker(tickerTips);  
            this.mNotificationBuild.setProgress(0, 0, false);  
            //默认有声音  
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);  
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());  
        };  
        /**  
         * @description 清除通知栏信息  
         * @param {Number} notifyId id,默认为1000  
         */  
        NotificationCustom.prototype.clearNotification = function(notifyId) {  
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;  
            if(this.notifyManager){  
                this.notifyManager.cancel(notifyId);  
            }         
        };  
        /**  
         * @description 清除所有通知栏信息  
         */  
        NotificationCustom.prototype.clearAllNotification = function() {  
            if(this.notifyManager){  
                this.notifyManager.cancelAll();  
            }         
        };  
        obj.plusReady(function() {  
            obj.NotificationUtil = new NotificationCustom();  
        });  
    })();  

})(window.NjsPhoneApi = {});

调用方法示例:
显示普通通知:

NjsPhoneApi.NotificationUtil.setNotification('测试标题'+staticI,'测试内容');

显示进度条代码:

function testProgress() {  
        //插件调用  
        NjsPhoneApi.NotificationUtil.setNotification("新版下载", "开始下载");  
        var current = 0;  
        NjsPhoneApi.NotificationUtil.setProgress(current); //插件调用  
        function progress() {  
            setTimeout(function() {  
                current += 1;  
                NjsPhoneApi.NotificationUtil.setProgress(current);  
                if(current>=100){  
                     NjsPhoneApi.NotificationUtil.compProgressNotification("下载完成");  
                }else{  
                    progress();  
                }  
            }, 100);  
        };  
        progress();  
    };  
testProgress();//调用显示进度条

取消单条通知:(传入参数为id,不传采用默认id)

NjsPhoneApi.NotificationUtil.clearNotification();

取消所有通知:

NjsPhoneApi.NotificationUtil.clearAllNotification();

另外: 支持自定义id的通知,也就是说可以通过传入不同的id,同时显示不同的通知

效果图1:
效果图2:
示例源码:鉴于有一些朋友会有各式各样的奇怪错误,所以这里单独写了一个示例,测试了android机型(华为,联想)都是可以正常使用的.
示例源码中采用的是默认id

收起阅读 »

判断手机已安装某APP的方法(Android,Native.js)

原生实现

private boolean isInstalledApp(Context context, String packageName){   
          //获取packagemanager   
          final PackageManager packageManager = context.getPackageManager();  
          //获取所有已安装程序的包信息   
          List< packageInfo> pinfo = packageManager.getInstalledPackages(0);  
          //用于存储所有已安装程序的包名   
          List<String> pName = new ArrayList<String>();  
         //从pinfo中将包名字逐一取出,压入pName list中   
         if(pinfo != null){   
              for(int i = 0; i < pinfo.size(); i++){   
                  String pn = pinfo.get(i).packageName;   
                  pName.add(pn);   
              }   
          }   
          //判断pName中是否有目标程序的包名,有TRUE,没有FALSE   
          return pName.contains(packageName);  
    } 

Native.js

var isInstalledApp = function(pkgname) {  
        plus.android.importClass('java.util.ArrayList');  
        plus.android.importClass('android.content.pm.PackageInfo');  
        plus.android.importClass('android.content.pm.PackageManager');  
        var MainActivity = plus.android.runtimeMainActivity();  
        var PackageManager = MainActivity.getPackageManager();  
        var pinfo = plus.android.invoke(PackageManager, 'getInstalledPackages', 0)  
        if (pinfo != null) {  
            for (i = 0; i < pinfo.size(); i++) {  
                //PackageInfo{4b45699f9d  com.tencent.mobileqq}  
                if (pinfo.get(i).toString().indexOf(pkgname) !== -1) {  
                    return true;  
                }  
            }  
        }  
        return false;  
    }  

## 使用  isInstalledApp('com.tencent.mm')

注意个别手机如华为有权限问题,如果不给权限,无法获取本机应用列表。

方式二:

var getIntentByPackageName = function(pkgname) {  
    plus.android.importClass('android.content.pm.PackageManager');  
    var MainActivity = plus.android.runtimeMainActivity();  
    var PackageManager = MainActivity.getPackageManager();  
    return plus.android.invoke(PackageManager, 'getLaunchIntentForPackage', pkgname);  
}  
var isInstalledApp = function(pkgname) {  
    return getIntentByPackageName(pkgname) != null;  
}  
## 使用  isInstalledApp('com.tencent.mm')
继续阅读 »

原生实现

private boolean isInstalledApp(Context context, String packageName){   
          //获取packagemanager   
          final PackageManager packageManager = context.getPackageManager();  
          //获取所有已安装程序的包信息   
          List< packageInfo> pinfo = packageManager.getInstalledPackages(0);  
          //用于存储所有已安装程序的包名   
          List<String> pName = new ArrayList<String>();  
         //从pinfo中将包名字逐一取出,压入pName list中   
         if(pinfo != null){   
              for(int i = 0; i < pinfo.size(); i++){   
                  String pn = pinfo.get(i).packageName;   
                  pName.add(pn);   
              }   
          }   
          //判断pName中是否有目标程序的包名,有TRUE,没有FALSE   
          return pName.contains(packageName);  
    } 

Native.js

var isInstalledApp = function(pkgname) {  
        plus.android.importClass('java.util.ArrayList');  
        plus.android.importClass('android.content.pm.PackageInfo');  
        plus.android.importClass('android.content.pm.PackageManager');  
        var MainActivity = plus.android.runtimeMainActivity();  
        var PackageManager = MainActivity.getPackageManager();  
        var pinfo = plus.android.invoke(PackageManager, 'getInstalledPackages', 0)  
        if (pinfo != null) {  
            for (i = 0; i < pinfo.size(); i++) {  
                //PackageInfo{4b45699f9d  com.tencent.mobileqq}  
                if (pinfo.get(i).toString().indexOf(pkgname) !== -1) {  
                    return true;  
                }  
            }  
        }  
        return false;  
    }  

## 使用  isInstalledApp('com.tencent.mm')

注意个别手机如华为有权限问题,如果不给权限,无法获取本机应用列表。

方式二:

var getIntentByPackageName = function(pkgname) {  
    plus.android.importClass('android.content.pm.PackageManager');  
    var MainActivity = plus.android.runtimeMainActivity();  
    var PackageManager = MainActivity.getPackageManager();  
    return plus.android.invoke(PackageManager, 'getLaunchIntentForPackage', pkgname);  
}  
var isInstalledApp = function(pkgname) {  
    return getIntentByPackageName(pkgname) != null;  
}  
## 使用  isInstalledApp('com.tencent.mm')
收起阅读 »

HBuilder6.8.x版本后,升级进度不消失的解决办法

升级更新 检查更新 HBuilder

1.关闭HBuilder(或强制终止进程)

  1. 重启HBuilder,等待HBuilder弹出升级提示的消息框(如下图)
  2. 点击立即更新、查看详情、暂不更新均可(请不要点击x关闭此提示框,也不要不点击等待这个提示框消失)
  3. 6.9.1将修复这个问题(但需要后续版本才会生效)
继续阅读 »

1.关闭HBuilder(或强制终止进程)

  1. 重启HBuilder,等待HBuilder弹出升级提示的消息框(如下图)
  2. 点击立即更新、查看详情、暂不更新均可(请不要点击x关闭此提示框,也不要不点击等待这个提示框消失)
  3. 6.9.1将修复这个问题(但需要后续版本才会生效)
收起阅读 »

Mac版HBuilder使用SVN连接https地址报错的解决办法

SVN Mac版 HBuilder

Mac版HBuilder安装svn插件后,连接https的svn地址可能会报

svn: E175002: Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
svn: E175002: OPTIONS request failed on '/svn/ifeedback_web'  
    svn: E175002: Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
svn: E175002: OPTIONS request failed on '/svn/ifeedback_web'  
    Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
    handshake alert:  unrecognized_name

的错误,解决办法如下
打开HBuilder.app/Contents/MacOS/HBuilder.ini文件,在最后添加如下三行代码重启HBuilder即可

-Dsvnkit.http.sslProtocols="SSLv3"   
-Djsse.enableSNIExtension=false  
-Dhudson.spool-svn=true

参考附件HBuilder.ini.zip中的HBuilder.ini(可备份下原来的覆盖本地的)

继续阅读 »

Mac版HBuilder安装svn插件后,连接https的svn地址可能会报

svn: E175002: Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
svn: E175002: OPTIONS request failed on '/svn/ifeedback_web'  
    svn: E175002: Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
svn: E175002: OPTIONS request failed on '/svn/ifeedback_web'  
    Connection has been shutdown: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name  
    handshake alert:  unrecognized_name

的错误,解决办法如下
打开HBuilder.app/Contents/MacOS/HBuilder.ini文件,在最后添加如下三行代码重启HBuilder即可

-Dsvnkit.http.sslProtocols="SSLv3"   
-Djsse.enableSNIExtension=false  
-Dhudson.spool-svn=true

参考附件HBuilder.ini.zip中的HBuilder.ini(可备份下原来的覆盖本地的)

收起阅读 »

DCloud-BeeCloud Pay 无后端开发的支付服务

beecloud 支付

DCloud-BeeCloud Pay
==============

DCloud和BeeCloud合作的支付业务,与普通的三方支付不同。
它仅需要工程师写前端App的js代码,调用Plus的原生支付接口进行支付宝和微信的原生支付,不需要服务器编写代码,即可收款到开发商自己的微信或支付宝的账户里。
需要注意钱并不流经DCloud或beecloud的服务器,开发商向微信和支付宝申请账户,最终用户支付的钱直接到达开发商在微信或支付宝里申请的账户。

BeeCloud同样支持银联在线支付渠道,银联在线在WAP及流应用环境下同样可用。

体验DEMO的方式:HBuilder 7.0版本后新建的Hello mui项目含有cloud pay模板。

准备工作

注册

创建APP

配置支付参数

test

开始支付

manifest.json配置

模块权限配置
  • 勾选payment模块
SDK配置
  • 需要在plus.payment-支付中配置scheme

    • 支付宝支付
      自定义填写,推荐使用小写字符串,不能填写alipay,AliPay等关键字

    • 微信支付
      固定填写,微信开放平台创建应用的APPID

这些配置都是云打包之后生效,所以测试微信支付,必须云打包之后,在手机上运行,才能正常调起微信客户端支付。否则在数据正常的情况下,调起微信客户端后,会出现异常(只显示一个确定按钮)
真机运行使用的是DCloud公司的支付配置信息,此时付款会付给DCloud。

代码实现

  • 在页面中引入beecloud.js
    ( 在Hello mui里含有本文件)

    <script src="beecloud.js"></script>  
  • 构建支付参数发起支付

<script src="beecloud.js"></script>  
<script type="text/javascript">  
    function beecloudPay(bcChannel) {  
        /*  
         * 构建支付参数  
         *   
         * app_id: BeeCloud控制台上创建的APP的appid,必填   
         * title: 订单标题,32个字节,最长支持16个汉字;必填  
         * total_fee: 支付金额,以分为单位,大于0的整数,必填  
         * bill_no: 订单号,8~32位数字和/或字母组合,确保在商户系统中唯一,必填  
         * optional: 扩展参数,可以传入任意数量的key/value对来补充对业务逻辑的需求;此参数会在webhook回调中返回; 选填  
         * bill_timeout: 订单失效时间,必须为非零正整数,单位为秒,必须大于360。选填   
         */  
        var payData = {  
            app_id: "c37d661d-7e61-49ea-96a5-68c34e83db3b",  
            channel: bcChannel,    
            title: "DCloud",   
            total_fee: 1,   
            bill_no: beecloud.genBillNo(),      
            optional: {'uerId':'beecloud','phone':'4006280728'},    
            bill_timeout: 360   
        };  
        /*  
         *  发起支付  
         *  payData: 支付参数  
         *  cbsuccess: 支付成功回调  
         *  cberror: 支付失败回调  
         */  
        beecloud.payReq(payData, function(result) {  
            mui.alert("----- 支付成功 -----" + str);  
        }, function(e) {  
            mui.alert("----- 支付失败 -----\n" +"错误码:"+ e.code + '\n' + e.message);  
        });  
    }  
</script>

</br>

联系Beecloud

如果您遇到问题,有以下方式可以联系到Beecloud:
① 请致电 40062807281
② 加入我们的开发者交流群:429506653
③ 在我们的FAQ页寻找答案

继续阅读 »

DCloud-BeeCloud Pay
==============

DCloud和BeeCloud合作的支付业务,与普通的三方支付不同。
它仅需要工程师写前端App的js代码,调用Plus的原生支付接口进行支付宝和微信的原生支付,不需要服务器编写代码,即可收款到开发商自己的微信或支付宝的账户里。
需要注意钱并不流经DCloud或beecloud的服务器,开发商向微信和支付宝申请账户,最终用户支付的钱直接到达开发商在微信或支付宝里申请的账户。

BeeCloud同样支持银联在线支付渠道,银联在线在WAP及流应用环境下同样可用。

体验DEMO的方式:HBuilder 7.0版本后新建的Hello mui项目含有cloud pay模板。

准备工作

注册

创建APP

配置支付参数

test

开始支付

manifest.json配置

模块权限配置
  • 勾选payment模块
SDK配置
  • 需要在plus.payment-支付中配置scheme

    • 支付宝支付
      自定义填写,推荐使用小写字符串,不能填写alipay,AliPay等关键字

    • 微信支付
      固定填写,微信开放平台创建应用的APPID

这些配置都是云打包之后生效,所以测试微信支付,必须云打包之后,在手机上运行,才能正常调起微信客户端支付。否则在数据正常的情况下,调起微信客户端后,会出现异常(只显示一个确定按钮)
真机运行使用的是DCloud公司的支付配置信息,此时付款会付给DCloud。

代码实现

  • 在页面中引入beecloud.js
    ( 在Hello mui里含有本文件)

    <script src="beecloud.js"></script>  
  • 构建支付参数发起支付

<script src="beecloud.js"></script>  
<script type="text/javascript">  
    function beecloudPay(bcChannel) {  
        /*  
         * 构建支付参数  
         *   
         * app_id: BeeCloud控制台上创建的APP的appid,必填   
         * title: 订单标题,32个字节,最长支持16个汉字;必填  
         * total_fee: 支付金额,以分为单位,大于0的整数,必填  
         * bill_no: 订单号,8~32位数字和/或字母组合,确保在商户系统中唯一,必填  
         * optional: 扩展参数,可以传入任意数量的key/value对来补充对业务逻辑的需求;此参数会在webhook回调中返回; 选填  
         * bill_timeout: 订单失效时间,必须为非零正整数,单位为秒,必须大于360。选填   
         */  
        var payData = {  
            app_id: "c37d661d-7e61-49ea-96a5-68c34e83db3b",  
            channel: bcChannel,    
            title: "DCloud",   
            total_fee: 1,   
            bill_no: beecloud.genBillNo(),      
            optional: {'uerId':'beecloud','phone':'4006280728'},    
            bill_timeout: 360   
        };  
        /*  
         *  发起支付  
         *  payData: 支付参数  
         *  cbsuccess: 支付成功回调  
         *  cberror: 支付失败回调  
         */  
        beecloud.payReq(payData, function(result) {  
            mui.alert("----- 支付成功 -----" + str);  
        }, function(e) {  
            mui.alert("----- 支付失败 -----\n" +"错误码:"+ e.code + '\n' + e.message);  
        });  
    }  
</script>

</br>

联系Beecloud

如果您遇到问题,有以下方式可以联系到Beecloud:
① 请致电 40062807281
② 加入我们的开发者交流群:429506653
③ 在我们的FAQ页寻找答案

收起阅读 »