HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

uniapp 打开某个应用详情页面,通过应用包名打开。

html5plus 安卓

使用plus引入类,然后使用安卓原生语言调用。需要使用应用包名。
有两种打开方式:
第一种:在应用的内部打开应用详情页(下列代码注释位置)
第二种:调用设置打开应用详情页
根据项目的应用场景来选择:
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
var intentGoApp = new Intent(mainActivity.getIntent());
var uri = Uri.fromParts("package", "应用包名", null);

                            //内部打开  
            // intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);  
            // intent.setData(uri);  
                            //内部打开结束    

                            //调用设置打开  
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");  
            intent.setData(Uri.fromParts("package",  "应用包名", null));  
                            //调用设置打开结束                                  

            mainActivity.startActivity(intent);
继续阅读 »

使用plus引入类,然后使用安卓原生语言调用。需要使用应用包名。
有两种打开方式:
第一种:在应用的内部打开应用详情页(下列代码注释位置)
第二种:调用设置打开应用详情页
根据项目的应用场景来选择:
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
var intentGoApp = new Intent(mainActivity.getIntent());
var uri = Uri.fromParts("package", "应用包名", null);

                            //内部打开  
            // intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);  
            // intent.setData(uri);  
                            //内部打开结束    

                            //调用设置打开  
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");  
            intent.setData(Uri.fromParts("package",  "应用包名", null));  
                            //调用设置打开结束                                  

            mainActivity.startActivity(intent);
收起阅读 »

uniapp 获取已安装的应用,以及图标转换

html5plus 安卓 base64 bitmap

主要使用Native.js引用安卓的一些类,然后根据安卓原生来获取。

包名、版本、应用名都能正常获取,但是图标获取出来的并不是base64,所以我们要转为base64的路径,这里有一个坑(使用image标签引用转换出来的base64是不行的,要使用img标签), 转换的时间可能较慢,多等待一下。

plus.android.importClass('android.graphics.drawable.BitmapDrawable');
var BitmapFactory = plus.android.importClass("android.graphics.BitmapFactory");
var Base64 = plus.android.importClass("android.util.Base64");
var Bitmap = plus.android.importClass('android.graphics.Bitmap');
var ByteArrayOutputStream = plus.android.importClass("java.io.ByteArrayOutputStream");
var Canvas = plus.android.importClass('android.graphics.Canvas');
plus.android.importClass('java.util.ArrayList');
plus.android.importClass('android.content.pm.PackageInfo');
plus.android.importClass('android.content.pm.PackageManager');
var ApplicationInfo = plus.android.importClass('android.content.pm.ApplicationInfo');
var MainActivity = plus.android.runtimeMainActivity();
var PackageManager = MainActivity.getPackageManager();
if (pinfo != null) {
for (var i = 0; i < pinfo.size(); i++) {
//PackageInfo{4b45699f9d com.tencent.mobileqq}
var pkginfo = pinfo.get(i);
var issysapk = ((pkginfo.plusGetAttribute("applicationInfo").plusGetAttribute("flags") & ApplicationInfo.FLAG_SYSTEM) != 0) ? true : false
if (issysapk == false) {
const apkinfo = {
appName: pkginfo.plusGetAttribute("applicationInfo").loadLabel(PackageManager).toString(),
packageName: pkginfo.plusGetAttribute("packageName"),
versionName: pkginfo.plusGetAttribute("versionName"),
versionCode: pkginfo.plusGetAttribute("versionCode"),
appIco:pkginfo.plusGetAttribute("applicationInfo").loadIcon(PackageManager)
};
var bimp=null;
try{
bimp=apkinfo.appIco.getBitmap();
}catch(e){
bimp = Bitmap.createBitmap(apkinfo.appIco.getIntrinsicWidth(), apkinfo.appIco.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
var canvas = new Canvas(bimp);
apkinfo.appIco.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
apkinfo.appIco.draw(canvas);
}
var baos = new ByteArrayOutputStream();
bimp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
var bitmapBytes = baos.toByteArray();
var result = "data:image/jpeg;base64,"+Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
apkinfo.appIcon=result;
apkKist.push(apkinfo);
};
};
};

继续阅读 »

主要使用Native.js引用安卓的一些类,然后根据安卓原生来获取。

包名、版本、应用名都能正常获取,但是图标获取出来的并不是base64,所以我们要转为base64的路径,这里有一个坑(使用image标签引用转换出来的base64是不行的,要使用img标签), 转换的时间可能较慢,多等待一下。

plus.android.importClass('android.graphics.drawable.BitmapDrawable');
var BitmapFactory = plus.android.importClass("android.graphics.BitmapFactory");
var Base64 = plus.android.importClass("android.util.Base64");
var Bitmap = plus.android.importClass('android.graphics.Bitmap');
var ByteArrayOutputStream = plus.android.importClass("java.io.ByteArrayOutputStream");
var Canvas = plus.android.importClass('android.graphics.Canvas');
plus.android.importClass('java.util.ArrayList');
plus.android.importClass('android.content.pm.PackageInfo');
plus.android.importClass('android.content.pm.PackageManager');
var ApplicationInfo = plus.android.importClass('android.content.pm.ApplicationInfo');
var MainActivity = plus.android.runtimeMainActivity();
var PackageManager = MainActivity.getPackageManager();
if (pinfo != null) {
for (var i = 0; i < pinfo.size(); i++) {
//PackageInfo{4b45699f9d com.tencent.mobileqq}
var pkginfo = pinfo.get(i);
var issysapk = ((pkginfo.plusGetAttribute("applicationInfo").plusGetAttribute("flags") & ApplicationInfo.FLAG_SYSTEM) != 0) ? true : false
if (issysapk == false) {
const apkinfo = {
appName: pkginfo.plusGetAttribute("applicationInfo").loadLabel(PackageManager).toString(),
packageName: pkginfo.plusGetAttribute("packageName"),
versionName: pkginfo.plusGetAttribute("versionName"),
versionCode: pkginfo.plusGetAttribute("versionCode"),
appIco:pkginfo.plusGetAttribute("applicationInfo").loadIcon(PackageManager)
};
var bimp=null;
try{
bimp=apkinfo.appIco.getBitmap();
}catch(e){
bimp = Bitmap.createBitmap(apkinfo.appIco.getIntrinsicWidth(), apkinfo.appIco.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
var canvas = new Canvas(bimp);
apkinfo.appIco.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
apkinfo.appIco.draw(canvas);
}
var baos = new ByteArrayOutputStream();
bimp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
var bitmapBytes = baos.toByteArray();
var result = "data:image/jpeg;base64,"+Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
apkinfo.appIcon=result;
apkKist.push(apkinfo);
};
};
};

收起阅读 »

Nvue webview 错误页面自定义

Webview nvue

nvue web-view组件引入网络页面时,如果网络页面发生错误,会出现比较难看的样式
但是官方文档中页面没有web-view错误的回调
但是其实weex中的web组件的回调,在uniapp的web-view也是可以绑定着用的

nvue web-view组件引入网络页面时,如果网络页面发生错误,会出现比较难看的样式
但是官方文档中页面没有web-view错误的回调
但是其实weex中的web组件的回调,在uniapp的web-view也是可以绑定着用的

本地打包 调用plus.runtime.openFile 无任何反应

HTML5+ html5plus

离线打包后 打开文件的功能不正常,也没有任何反应。plus.runtime.openFile 无任何反应。经过调试摸索最后发现
发现是 AndroidManefest.xml的配置问题。android:authorities="改为自己的包名.dc.fileprovider"

<provider  
    android:name="io.dcloud.common.util.DCloud_FileProvider"  
    android:authorities="你的包名.dc.fileprovider"  
    android:exported="false"  
    android:grantUriPermissions="true">  
    <meta-data  
        android:name="android.support.FILE_PROVIDER_PATHS"  
        android:resource="@xml/dcloud_file_provider" />  
</provider>
继续阅读 »

离线打包后 打开文件的功能不正常,也没有任何反应。plus.runtime.openFile 无任何反应。经过调试摸索最后发现
发现是 AndroidManefest.xml的配置问题。android:authorities="改为自己的包名.dc.fileprovider"

<provider  
    android:name="io.dcloud.common.util.DCloud_FileProvider"  
    android:authorities="你的包名.dc.fileprovider"  
    android:exported="false"  
    android:grantUriPermissions="true">  
    <meta-data  
        android:name="android.support.FILE_PROVIDER_PATHS"  
        android:resource="@xml/dcloud_file_provider" />  
</provider>
收起阅读 »

你们开发的ios程序遇到过ipad没事,iphone上经常崩溃吗

iOS

我好像是用redirctto跳转页面的时候,用plus强制旋转,iphone强制旋转就会崩溃但ipad没问题

我好像是用redirctto跳转页面的时候,用plus强制旋转,iphone强制旋转就会崩溃但ipad没问题

nvue中使用picker遇到的问题

picker

最近在使用nvue做APP的开发,发现一个问题,在iOS下可以正常弹出的picker在安卓下怎么点都没有反应,后来逐步排查,发现在picker中的view我用了hover-class(因为是从vue修改过来,忘了删除)从而导致点击没有反应。删除hover-class后就没问题了,在安卓和iOS都可以正常弹出了。

继续阅读 »

最近在使用nvue做APP的开发,发现一个问题,在iOS下可以正常弹出的picker在安卓下怎么点都没有反应,后来逐步排查,发现在picker中的view我用了hover-class(因为是从vue修改过来,忘了删除)从而导致点击没有反应。删除hover-class后就没问题了,在安卓和iOS都可以正常弹出了。

收起阅读 »

记录一下真机slider显示bug的解决方法

bug反馈

模拟器中显示没问题,但是真机上只显示一个圆点,拖不动。
在模拟器中去掉“uni-slider .uni-slider-tap-area”这个类中的“flex: 1”出现同样的效果。

解决方案:
在slider组件中增加自定义的"mySlider"类,并写下样式:

前提:注意父元素的宽度有没有问题

继续阅读 »

模拟器中显示没问题,但是真机上只显示一个圆点,拖不动。
在模拟器中去掉“uni-slider .uni-slider-tap-area”这个类中的“flex: 1”出现同样的效果。

解决方案:
在slider组件中增加自定义的"mySlider"类,并写下样式:

前提:注意父元素的宽度有没有问题

收起阅读 »

接网站、中后台H5、小程序,联系v+18221154541

外包接单

【接单】接网站、中后台H5、小程序,联系v+18221154541。可大可小,可私接可对公

【接单】接网站、中后台H5、小程序,联系v+18221154541。可大可小,可私接可对公

个推11周年庆,最长90天消息推送VIP权益免费领!

消息推送 安卓

12月7日,个推即将迎来11岁生日

感恩每1份信任

致谢每1次选择

值个推十一周年之际

为回馈广大开发者

个推重磅推出【创业者扶持计划】

——个推消息推送VIP权益免费送!

厂商推送策略、后效分析、行业大盘分析等

数十款热门VIP功能统统免费用

最长可达90天!

满足一定条件

还能持续免费使用推送VIP权益

(详情咨询商务)

惊喜福利已登场!

还在犹豫什么

抓紧时间上车!

继续阅读 »

12月7日,个推即将迎来11岁生日

感恩每1份信任

致谢每1次选择

值个推十一周年之际

为回馈广大开发者

个推重磅推出【创业者扶持计划】

——个推消息推送VIP权益免费送!

厂商推送策略、后效分析、行业大盘分析等

数十款热门VIP功能统统免费用

最长可达90天!

满足一定条件

还能持续免费使用推送VIP权益

(详情咨询商务)

惊喜福利已登场!

还在犹豫什么

抓紧时间上车!

收起阅读 »

ZEBRA(斑马 T26)PDA 程序内按钮开启红外扫描

扫码
    main = plus.android.runtimeMainActivity(); //获取activity  
    var Intent = plus.android.importClass('android.content.Intent');  
    var intent = new Intent();  
    if (plus.device.model === 'TC26'){  
        var softScanTrigger = "com.symbol.datawedge.api.ACTION";  
        var extraData = "com.symbol.datawedge.api.SOFT_SCAN_TRIGGER";  
        intent.setAction(softScanTrigger);  
        intent.putExtra(extraData, "START_SCANNING");  
        main.sendBroadcast(intent, null);  
        var receiver;  
        try {  
            receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
                onReceive: function(context, intent) { //实现onReceiver回调函数  
                    plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                    var data = intent.getStringExtra('com.symbol.datawedge.data_string');  
                }  
            });  
        }catch(e){  
            alert("扫码异常,请退出重试");  
        }  
        var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
        var filter = new IntentFilter();  
       // com.symbol.datawedge.scan 为DataWedge文件设置内容  
        filter.addAction("com.symbol.datawedge.scan"); //监听扫码广播  
        main.registerReceiver(receiver, filter); //注册监听  
     }
继续阅读 »
    main = plus.android.runtimeMainActivity(); //获取activity  
    var Intent = plus.android.importClass('android.content.Intent');  
    var intent = new Intent();  
    if (plus.device.model === 'TC26'){  
        var softScanTrigger = "com.symbol.datawedge.api.ACTION";  
        var extraData = "com.symbol.datawedge.api.SOFT_SCAN_TRIGGER";  
        intent.setAction(softScanTrigger);  
        intent.putExtra(extraData, "START_SCANNING");  
        main.sendBroadcast(intent, null);  
        var receiver;  
        try {  
            receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
                onReceive: function(context, intent) { //实现onReceiver回调函数  
                    plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                    var data = intent.getStringExtra('com.symbol.datawedge.data_string');  
                }  
            });  
        }catch(e){  
            alert("扫码异常,请退出重试");  
        }  
        var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
        var filter = new IntentFilter();  
       // com.symbol.datawedge.scan 为DataWedge文件设置内容  
        filter.addAction("com.symbol.datawedge.scan"); //监听扫码广播  
        main.registerReceiver(receiver, filter); //注册监听  
     }
收起阅读 »

uniapp 开发launcher

html5plus 安卓 launcher

使用uniapp怎么开发一个桌面应用呢?
其实最主要的就是添加一下配置:

《action android:name="android.intent.action.MAIN"/》

《category android:name="android.intent.category.LAUNCHER"/》

《category android:name="android.intent.category.HOME"/》

《category android:name="android.intent.category.DEFAULT"/》

那么如何去配置呢?
首先使用uniapp云打包,拿到apk文件,在使用反编译工具编辑apk。
得到AndroidManifest.xml文件,在此文件第一个activity便签下添加以上的配置。
添加好之后,再次编译文件到apk。
这样一个launcher程序就写好了。

按照以下网址使用,编译apk,和回编apk

反编译apk:https://juejin.cn/post/6981734318791983135
回编译apk:https://blog.csdn.net/u013265344/article/details/85004002

反编译的时候有的时候xml文件不对,使用:
java -jar apktool.jar d -f .\app.apk -o serial --only-main-classes

附加:
launcher开发出来之后,有些用户场景需要去监听app添加、卸载。
在App.vue文件onLaunch下添加以下代码即可。
//监听应用的添加
var receiver;
var mainActivity = plus.android.runtimeMainActivity();
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var filter = new IntentFilter();
var Intent = plus.android.importClass('android.content.Intent');
plus.android.importClass('android.content.BroadcastReceiver');
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) { //实现onReceiver回调函数
plus.android.importClass(intent);
var packageName =intent.getDataString(); //包名
var action = intent.getAction(); //监听的方法
// mainActivity.unregisterReceiver(receiver); 关闭监听
}
});
filter.addDataScheme("package");
// filter.addAction(Intent.ACTION_PACKAGE_ADDED); //监听app添加
// filter.addAction(Intent.ACTION_PACKAGE_REMOVED); //监听app卸载
filter.addAction(Intent.ACTION_PACKAGE_REPLACED); //监听app升级安装
mainActivity.registerReceiver(receiver, filter); //注册监听
//监听应用的添加结束

以下图片为AndroidManifest.xml文件中的launcher配置

继续阅读 »

使用uniapp怎么开发一个桌面应用呢?
其实最主要的就是添加一下配置:

《action android:name="android.intent.action.MAIN"/》

《category android:name="android.intent.category.LAUNCHER"/》

《category android:name="android.intent.category.HOME"/》

《category android:name="android.intent.category.DEFAULT"/》

那么如何去配置呢?
首先使用uniapp云打包,拿到apk文件,在使用反编译工具编辑apk。
得到AndroidManifest.xml文件,在此文件第一个activity便签下添加以上的配置。
添加好之后,再次编译文件到apk。
这样一个launcher程序就写好了。

按照以下网址使用,编译apk,和回编apk

反编译apk:https://juejin.cn/post/6981734318791983135
回编译apk:https://blog.csdn.net/u013265344/article/details/85004002

反编译的时候有的时候xml文件不对,使用:
java -jar apktool.jar d -f .\app.apk -o serial --only-main-classes

附加:
launcher开发出来之后,有些用户场景需要去监听app添加、卸载。
在App.vue文件onLaunch下添加以下代码即可。
//监听应用的添加
var receiver;
var mainActivity = plus.android.runtimeMainActivity();
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var filter = new IntentFilter();
var Intent = plus.android.importClass('android.content.Intent');
plus.android.importClass('android.content.BroadcastReceiver');
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) { //实现onReceiver回调函数
plus.android.importClass(intent);
var packageName =intent.getDataString(); //包名
var action = intent.getAction(); //监听的方法
// mainActivity.unregisterReceiver(receiver); 关闭监听
}
});
filter.addDataScheme("package");
// filter.addAction(Intent.ACTION_PACKAGE_ADDED); //监听app添加
// filter.addAction(Intent.ACTION_PACKAGE_REMOVED); //监听app卸载
filter.addAction(Intent.ACTION_PACKAGE_REPLACED); //监听app升级安装
mainActivity.registerReceiver(receiver, filter); //注册监听
//监听应用的添加结束

以下图片为AndroidManifest.xml文件中的launcher配置

收起阅读 »

【经验分享】uni-App全端直播解决方案

H5直播 live_player live_pusher LivePusher 直播

主播端

使用plus.video.LivePusher H5+原生方法 或者 live-pusher组件,我的项目使用的plus LivePusher实现,主Webview创建LivePusher,创建背景透明子Webview,实现直播上层渲染所有操作方法,包括商品上屏下屏、聊天、优惠券、直播设置等等操作全部在子页面中。

观看端

一、小程序使用live-player组件播放,直播流使用rtmp协议;

二、App使用video组件,聊天、商品等同样是创建的子Webview,静态hybrid方式,外链vue.js渲染数据,与主页面数据通信参考:https://ask.dcloud.net.cn/article/39086;
直播流使用rtmp协议;

三、H5端使用B站直播解决方案,flv.js方式播放直播源,最终为video播放,可以直接在npm上找相应的库,比如vue-flv-player,直播流使用httpflv协议;
H5直播存在很多兼容问题,flv流协议仅支持pc、安卓非微信浏览器,最终改用HLS协议(m3u8),流切片方式,延迟较高10-20s,但是能兼容安卓 ios 微信浏览器,使用video.js库。(浏览器播放需要注意浏览器不允许用户打开直接播放有声视频,所以先设置静音,提示用户操作开启声音)

长连接通信主播端、H5端使用signalR,小程序、App使用wx.connectSocket封装,实现与signalR一样的方法条件编译引入即可;

直播相关知识参考:https://www.cnblogs.com/saysmy/p/7851911.html

继续阅读 »

主播端

使用plus.video.LivePusher H5+原生方法 或者 live-pusher组件,我的项目使用的plus LivePusher实现,主Webview创建LivePusher,创建背景透明子Webview,实现直播上层渲染所有操作方法,包括商品上屏下屏、聊天、优惠券、直播设置等等操作全部在子页面中。

观看端

一、小程序使用live-player组件播放,直播流使用rtmp协议;

二、App使用video组件,聊天、商品等同样是创建的子Webview,静态hybrid方式,外链vue.js渲染数据,与主页面数据通信参考:https://ask.dcloud.net.cn/article/39086;
直播流使用rtmp协议;

三、H5端使用B站直播解决方案,flv.js方式播放直播源,最终为video播放,可以直接在npm上找相应的库,比如vue-flv-player,直播流使用httpflv协议;
H5直播存在很多兼容问题,flv流协议仅支持pc、安卓非微信浏览器,最终改用HLS协议(m3u8),流切片方式,延迟较高10-20s,但是能兼容安卓 ios 微信浏览器,使用video.js库。(浏览器播放需要注意浏览器不允许用户打开直接播放有声视频,所以先设置静音,提示用户操作开启声音)

长连接通信主播端、H5端使用signalR,小程序、App使用wx.connectSocket封装,实现与signalR一样的方法条件编译引入即可;

直播相关知识参考:https://www.cnblogs.com/saysmy/p/7851911.html

收起阅读 »