HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

uni-app 中配置 navigateToMiniProgramAppIdList 报错

我也是找了很久的解决方案才发现,不是在page.json中配置,是在manifest.json的源码视图中添加,如图

我也是找了很久的解决方案才发现,不是在page.json中配置,是在manifest.json的源码视图中添加,如图

rich-text渲染富文本 图片在APP上显示溢出问题

rich_text

this.$http.httpTokenRequest(url,data).then(res=>{
if(res.data.success){
res.data.result.content=res.data.result.content.replace(/<img/g,"<img style='width:100%'")
this.info=res.data.result;
}
})

继续阅读 »

this.$http.httpTokenRequest(url,data).then(res=>{
if(res.data.success){
res.data.result.content=res.data.result.content.replace(/<img/g,"<img style='width:100%'")
this.info=res.data.result;
}
})

收起阅读 »

原生Android制作精简打包SDK项目(Android Studio-V3.5)

因为之前已经开发了原生的Android项目,所以现在要集成uniapp开发的应用到原生里面,为了方便处理,只能自己制作一个可打包的SDK项目(语言表达不好,见谅哈)
我这边的Android Studio版本是3.5的,我用的是MacMini电脑,所以Android模拟器用的是网页MuMu。

1、按照正常的流程,我们新建一个基于Java语言开发的Android原生项目(可以正常运行起来的项目);

2、从uniapp官网下载最新的Android官方SDK项目
https://ask.dcloud.net.cn/article/103

3、然后我们打开官方SDK项目压缩包,项目列表如下:

4、我们打开SDK,里面的资源库和文件全在这里面,所以从这里面找文件即可;

5、我们把SDK->libs下面的lib.5plus.base-release.aar和uniapp-release.aar拖进我们Android原生项目的libs路径下

6、然后我们配置Android原生项目下的build.gradle(我这里直接是copy官方SDK->HBuilder-Integrate-AS项目下的build.gradle)

7、在build.gradle加入需要的一些第三方库
implementation 'com.android.support:appcompat-v7:29.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
/uniapp所需库-----------------------开始/
implementation 'com.android.support:recyclerview-v7:29.1.0'
implementation 'com.alibaba.android:bindingx-core:1.0.3'
implementation 'com.alibaba.android:bindingx_weex_plugin:1.0.3'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation "com.facebook.fresco:animated-gif:1.13.0"
/uniapp所需库-----------------------结束/
// 基座需要,必须添加
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'

8、接来下就是配置AndroidManifest.xml文件了;我们不需要添加什么特殊的东西,只要记住application的name要设置成android:name="io.dcloud.application.DCloudApplication"

9、然后设置启动页面就可以了

10、接下来就是重点了,把自己的uniapp导入到项目中;
(1)在原生Android项目的main下面创建assets文件夹,里面添加apps(注意是apps,不是app)和data两个子文件夹
(2)去官网的SDK项目中把data下面的全部文件copy到自己项目下的data文件夹下
(3)把uniapp生成的本地包项目导入到apps下面
(4)切记,一定要把data下面的dcloud_control.xml的appid改成项目id。否则是启动不了项目的

11、按照官方文档的提示,在drawable下面添加好icon、push和splash三张图片

12、运行项目就可以正常运行起来了。

因为我这里用的模板不是很多,所以添加的第三方库没有,这个按自己的需求去添加,我这边只是告诉如何自己创建SDK打包项目。
写的不算很好,高手勿喷。

继续阅读 »

因为之前已经开发了原生的Android项目,所以现在要集成uniapp开发的应用到原生里面,为了方便处理,只能自己制作一个可打包的SDK项目(语言表达不好,见谅哈)
我这边的Android Studio版本是3.5的,我用的是MacMini电脑,所以Android模拟器用的是网页MuMu。

1、按照正常的流程,我们新建一个基于Java语言开发的Android原生项目(可以正常运行起来的项目);

2、从uniapp官网下载最新的Android官方SDK项目
https://ask.dcloud.net.cn/article/103

3、然后我们打开官方SDK项目压缩包,项目列表如下:

4、我们打开SDK,里面的资源库和文件全在这里面,所以从这里面找文件即可;

5、我们把SDK->libs下面的lib.5plus.base-release.aar和uniapp-release.aar拖进我们Android原生项目的libs路径下

6、然后我们配置Android原生项目下的build.gradle(我这里直接是copy官方SDK->HBuilder-Integrate-AS项目下的build.gradle)

7、在build.gradle加入需要的一些第三方库
implementation 'com.android.support:appcompat-v7:29.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
/uniapp所需库-----------------------开始/
implementation 'com.android.support:recyclerview-v7:29.1.0'
implementation 'com.alibaba.android:bindingx-core:1.0.3'
implementation 'com.alibaba.android:bindingx_weex_plugin:1.0.3'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation "com.facebook.fresco:animated-gif:1.13.0"
/uniapp所需库-----------------------结束/
// 基座需要,必须添加
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'

8、接来下就是配置AndroidManifest.xml文件了;我们不需要添加什么特殊的东西,只要记住application的name要设置成android:name="io.dcloud.application.DCloudApplication"

9、然后设置启动页面就可以了

10、接下来就是重点了,把自己的uniapp导入到项目中;
(1)在原生Android项目的main下面创建assets文件夹,里面添加apps(注意是apps,不是app)和data两个子文件夹
(2)去官网的SDK项目中把data下面的全部文件copy到自己项目下的data文件夹下
(3)把uniapp生成的本地包项目导入到apps下面
(4)切记,一定要把data下面的dcloud_control.xml的appid改成项目id。否则是启动不了项目的

11、按照官方文档的提示,在drawable下面添加好icon、push和splash三张图片

12、运行项目就可以正常运行起来了。

因为我这里用的模板不是很多,所以添加的第三方库没有,这个按自己的需求去添加,我这边只是告诉如何自己创建SDK打包项目。
写的不算很好,高手勿喷。

收起阅读 »

android中NJS方式使用原生录制视频

安卓 原生 视频 NJS

我们公司有业务要需要做限制拍摄时间的视频录制功能,官方提供的API太坑 太坑 太坑 太坑,压根不能用

感谢这位同行分享的代码:
https://ask.dcloud.net.cn/question/25816?item_id=108332&rf=false

我基于该分享的代码进行改进,成功在本地存储了mp4文件,望对大家有帮助

var Camera = plus.android.importClass('android.hardware.Camera')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceView = plus.android.importClass('android.view.SurfaceView')
,LinearLayout = plus.android.importClass('android.widget.LinearLayout')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceHolder = plus.android.implements('android.view.SurfaceHolder');

var mainActivity = plus.android.runtimeMainActivity()
,cameraView = new LinearLayout(mainActivity)
,surfaceView = new SurfaceView(mainActivity)
,cameraCount = Camera.getNumberOfCameras()
,cameraInfo = new Camera.CameraInfo()
,mediaRecorder = new MediaRecorder()
,cameraId = null
,camera = null
,surfaceHolder = null
,videoFilePath = plus.io.convertLocalFileSystemURL('_downloads/') + Date.now() + '.mp4';

//查询可用摄像头
for (var i = 0;i < cameraCount;i++) {
Camera.getCameraInfo(i, cameraInfo);

if(plus.android.getAttribute(cameraInfo, 'facing') !== cameraInfo.CAMERA_FACING_BACK) continue;  
cameraId = i;  
break;  

}

if(cameraId === null) throw Error('无后置摄像头');

cameraView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
cameraView.addView(surfaceView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mainActivity.setContentView(cameraView);

camera = Camera.open(cameraId);
camera.setDisplayOrientation(90);
camera.unlock();
surfaceHolder = surfaceView.getHolder();
mediaRecorder.setCamera(camera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(1280, 720);
mediaRecorder.setVideoFrameRate(20);
mediaRecorder.setPreviewDisplay(plus.android.invoke(surfaceHolder, 'getSurface'));
mediaRecorder.setOutputFile(videoFilePath);
mediaRecorder.prepare();
mediaRecorder.start();
//camera.release();
setTimeout(function(){
mediaRecorder.stop();
camera.release();
}, 3e3);

继续阅读 »

我们公司有业务要需要做限制拍摄时间的视频录制功能,官方提供的API太坑 太坑 太坑 太坑,压根不能用

感谢这位同行分享的代码:
https://ask.dcloud.net.cn/question/25816?item_id=108332&rf=false

我基于该分享的代码进行改进,成功在本地存储了mp4文件,望对大家有帮助

var Camera = plus.android.importClass('android.hardware.Camera')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceView = plus.android.importClass('android.view.SurfaceView')
,LinearLayout = plus.android.importClass('android.widget.LinearLayout')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceHolder = plus.android.implements('android.view.SurfaceHolder');

var mainActivity = plus.android.runtimeMainActivity()
,cameraView = new LinearLayout(mainActivity)
,surfaceView = new SurfaceView(mainActivity)
,cameraCount = Camera.getNumberOfCameras()
,cameraInfo = new Camera.CameraInfo()
,mediaRecorder = new MediaRecorder()
,cameraId = null
,camera = null
,surfaceHolder = null
,videoFilePath = plus.io.convertLocalFileSystemURL('_downloads/') + Date.now() + '.mp4';

//查询可用摄像头
for (var i = 0;i < cameraCount;i++) {
Camera.getCameraInfo(i, cameraInfo);

if(plus.android.getAttribute(cameraInfo, 'facing') !== cameraInfo.CAMERA_FACING_BACK) continue;  
cameraId = i;  
break;  

}

if(cameraId === null) throw Error('无后置摄像头');

cameraView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
cameraView.addView(surfaceView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mainActivity.setContentView(cameraView);

camera = Camera.open(cameraId);
camera.setDisplayOrientation(90);
camera.unlock();
surfaceHolder = surfaceView.getHolder();
mediaRecorder.setCamera(camera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(1280, 720);
mediaRecorder.setVideoFrameRate(20);
mediaRecorder.setPreviewDisplay(plus.android.invoke(surfaceHolder, 'getSurface'));
mediaRecorder.setOutputFile(videoFilePath);
mediaRecorder.prepare();
mediaRecorder.start();
//camera.release();
setTimeout(function(){
mediaRecorder.stop();
camera.release();
}, 3e3);

收起阅读 »

rich-text在h5下丢失样式解决办法

richtext uniapp

跟vue的v-html丢失样式解决办法一样,在css中用 .xxx >>> .xxx 解决 (样式穿透),在less中用 .xxx /deep/ .xxxx

跟vue的v-html丢失样式解决办法一样,在css中用 .xxx >>> .xxx 解决 (样式穿透),在less中用 .xxx /deep/ .xxxx

uniapp开发小程序,全局应用websocket

微信小程序 WEBSOCKET

以前写vue页面的时候写过聊天室,这次用uniapp开发小程序,用到了websocket,记录下心得体会

前言:
后台使用了nodejs的express-ws模块,分享一篇介绍express-ws非常好的帖子https://www.jianshu.com/p/136da96d3d48
对于前端人员,不用管后台socket如何实现的,用的什么模块,因为socket只是个协议
在uniapp中,也不用纠结用框架自带的websocket的api,还是引入socket.io.js。
既然框架已经给我们集成这个功能了,直接用就对了,非常方便

首先在app.vue中建立连接
注:在任意组件下建立socket连接均可,框架提供的api是全局的

        onShow: function() {  
            console.log('App Show')  
            uni.connectSocket({  
                url: 'wss://localhost', //仅为示例,并非真实接口地址。  
                success: () => {  
                    console.log('socket success');  
                },  
                fail: (err) => {  
                    console.log(err)  
                },  
                complete: () => {}  
            });  
        },  
        onHide: function() {  
            console.log('App Hide')  
            uni.closeSocket({  
                code:1000,  
                reason:'App Hide'  
            })  
        }

建立连接后,在任意组件中调用相关api即可,实在是简单得不能简单了

以下是测试结果

ps:也可以用uni.connectSocket() 接口创建SocketTask 对象,在main.js中全局注册,优点是使用更方便,缺点是关闭连接后,需在代码中实现重新打开连接!

继续阅读 »

以前写vue页面的时候写过聊天室,这次用uniapp开发小程序,用到了websocket,记录下心得体会

前言:
后台使用了nodejs的express-ws模块,分享一篇介绍express-ws非常好的帖子https://www.jianshu.com/p/136da96d3d48
对于前端人员,不用管后台socket如何实现的,用的什么模块,因为socket只是个协议
在uniapp中,也不用纠结用框架自带的websocket的api,还是引入socket.io.js。
既然框架已经给我们集成这个功能了,直接用就对了,非常方便

首先在app.vue中建立连接
注:在任意组件下建立socket连接均可,框架提供的api是全局的

        onShow: function() {  
            console.log('App Show')  
            uni.connectSocket({  
                url: 'wss://localhost', //仅为示例,并非真实接口地址。  
                success: () => {  
                    console.log('socket success');  
                },  
                fail: (err) => {  
                    console.log(err)  
                },  
                complete: () => {}  
            });  
        },  
        onHide: function() {  
            console.log('App Hide')  
            uni.closeSocket({  
                code:1000,  
                reason:'App Hide'  
            })  
        }

建立连接后,在任意组件中调用相关api即可,实在是简单得不能简单了

以下是测试结果

ps:也可以用uni.connectSocket() 接口创建SocketTask 对象,在main.js中全局注册,优点是使用更方便,缺点是关闭连接后,需在代码中实现重新打开连接!

收起阅读 »

5+app调用第三方地图导航 android版

/**  
     * 调用第三方导航  高德优先  百度  
     * @param lon  
     * @param lat  
     * @returns {boolean}  
     */  
    // com.baidu.BaiduMap  

    // com.autonavi.minimap  

    function dh(lon,lat){  

        if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap'})){  
                //用户已安装高德地图  
                plus.runtime.openURL('androidamap://navi?sourceApplication=com.knssshy.sj&lat='+lat+'&lon='+lon+'&dev=0',function(e) {  
                    plus.nativeUI.confirm( "检查到您未安装\"高德地图\".");  
                } );  
            }else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap'})){  
                //用户已安装百度地图  
                plus.runtime.openURL('bdapp://map/direction?destination='+lat+','+lon+'&coord_type=gcj02&mode=driving&src=com.knssshy.sj',function(e) {  
                    plus.nativeUI.confirm( "检查到您未安装\"百度地图\".");  
                } );  
            }else{  
                alert('你没有安装导航软件(高德/百度).')  
            }  
    }

在JS中直接调用函数dh(lon,lat)就能打开第三方地图进行导航了,lon lat为坐标值。

继续阅读 »
/**  
     * 调用第三方导航  高德优先  百度  
     * @param lon  
     * @param lat  
     * @returns {boolean}  
     */  
    // com.baidu.BaiduMap  

    // com.autonavi.minimap  

    function dh(lon,lat){  

        if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap'})){  
                //用户已安装高德地图  
                plus.runtime.openURL('androidamap://navi?sourceApplication=com.knssshy.sj&lat='+lat+'&lon='+lon+'&dev=0',function(e) {  
                    plus.nativeUI.confirm( "检查到您未安装\"高德地图\".");  
                } );  
            }else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap'})){  
                //用户已安装百度地图  
                plus.runtime.openURL('bdapp://map/direction?destination='+lat+','+lon+'&coord_type=gcj02&mode=driving&src=com.knssshy.sj',function(e) {  
                    plus.nativeUI.confirm( "检查到您未安装\"百度地图\".");  
                } );  
            }else{  
                alert('你没有安装导航软件(高德/百度).')  
            }  
    }

在JS中直接调用函数dh(lon,lat)就能打开第三方地图进行导航了,lon lat为坐标值。

收起阅读 »

在uniapp h5中在线引入高德地图js api的方法分享

高德文档:https://lbs.amap.com/api/javascript-api/guide/abc/load
查询了好久都没有找到解决方法,弄好了分享一下.

//这里要加window., loadScrpit的callback才会执行  
window.mapInit = function(){  
  let mapObj = new AMap.Map('iCenter');  
  mapObj.plugin('AMap.Geolocation', function () {  
      let geolocation = new AMap.Geolocation({  
          enableHighAccuracy: false,//是否使用高精度定位,默认:true  
          timeout: 5000,          //超过5秒后停止定位,默认:无穷大  
      });  
      mapObj.addControl(geolocation);  
      geolocation.getCurrentPosition();  
      //返回定位信息  
      AMap.event.addListener(geolocation, 'complete', function (res) {  
          console.log(res);  
      });  
      //返回定位出错信息  
      AMap.event.addListener(geolocation, 'error', function (err) {  
          console.log(err);  
      });  
  });  
}  
// 页面onload调用此方法  
function loadScrpit(){  
  var script = document.createElement('script');  
  script.src = "https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&callback=mapInit";  
  document.body.appendChild(script);  
}
继续阅读 »

高德文档:https://lbs.amap.com/api/javascript-api/guide/abc/load
查询了好久都没有找到解决方法,弄好了分享一下.

//这里要加window., loadScrpit的callback才会执行  
window.mapInit = function(){  
  let mapObj = new AMap.Map('iCenter');  
  mapObj.plugin('AMap.Geolocation', function () {  
      let geolocation = new AMap.Geolocation({  
          enableHighAccuracy: false,//是否使用高精度定位,默认:true  
          timeout: 5000,          //超过5秒后停止定位,默认:无穷大  
      });  
      mapObj.addControl(geolocation);  
      geolocation.getCurrentPosition();  
      //返回定位信息  
      AMap.event.addListener(geolocation, 'complete', function (res) {  
          console.log(res);  
      });  
      //返回定位出错信息  
      AMap.event.addListener(geolocation, 'error', function (err) {  
          console.log(err);  
      });  
  });  
}  
// 页面onload调用此方法  
function loadScrpit(){  
  var script = document.createElement('script');  
  script.src = "https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&callback=mapInit";  
  document.body.appendChild(script);  
}
收起阅读 »

扫码黑屏

Barcode

扫码黑屏这个问题一直在华为和小米等手机不定时出现。

1、先解决办法如下。在退出的时候释放扫码对象并关闭

     mui.init({  
                beforeback: function() {  
                    //返回true继续页面关闭逻辑  
                    if(scan != null) {  
                        scan.close()  
                        scan = null;  
                    }  
                    return true;  
                }  
     })

2、没有使用demo的用法,这里在mui.plusReady中使用setTimeOut 300之后初始化扫码

            var scan=null;  
            mui.plusReady(function() {  
                setTimeout("scanInit()", 300)  
            })  

            function scanInit() {  
                var filter = [plus.barcode.CODE128];  
                scan = new plus.barcode.Barcode('bcid', filter);  
                scan.onmarked = onmarked;  
                scan.onerror = onerror;  
                scan.start();  
            }

以上用了之后确实没有出现过黑屏

继续阅读 »

扫码黑屏这个问题一直在华为和小米等手机不定时出现。

1、先解决办法如下。在退出的时候释放扫码对象并关闭

     mui.init({  
                beforeback: function() {  
                    //返回true继续页面关闭逻辑  
                    if(scan != null) {  
                        scan.close()  
                        scan = null;  
                    }  
                    return true;  
                }  
     })

2、没有使用demo的用法,这里在mui.plusReady中使用setTimeOut 300之后初始化扫码

            var scan=null;  
            mui.plusReady(function() {  
                setTimeout("scanInit()", 300)  
            })  

            function scanInit() {  
                var filter = [plus.barcode.CODE128];  
                scan = new plus.barcode.Barcode('bcid', filter);  
                scan.onmarked = onmarked;  
                scan.onerror = onerror;  
                scan.start();  
            }

以上用了之后确实没有出现过黑屏

收起阅读 »

码灵程序员导航-一个帮助开发者成长的网址导航

uniapp 教程 5+App开发 App入门

> 作为一名码农,随着平时工作的需要,慢慢收集了国内外很多优秀相关程序员站点,这其中包括在线工具、在线运行、免费接口、在线资源、在线学习、技术论坛、技术博客等等,为广大用户提供学习网站、学习方向、学习途径等内容。

https://nav.imaring.com/

继续阅读 »

> 作为一名码农,随着平时工作的需要,慢慢收集了国内外很多优秀相关程序员站点,这其中包括在线工具、在线运行、免费接口、在线资源、在线学习、技术论坛、技术博客等等,为广大用户提供学习网站、学习方向、学习途径等内容。

https://nav.imaring.com/

收起阅读 »