HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

nativejs android获取wifi强度及状态

Native.JS Android
const Context = plus.android.importClass("android.content.Context");  
const WifiManager = plus.android.importClass("android.net.wifi.WifiManager");  
const wifiManager = plus.android.runtimeMainActivity().getSystemService(Context.WIFI_SERVICE);  
const WifiInfo = plus.android.importClass("android.net.wifi.WifiInfo");  

const isWifiEnabled = wifiManager.isWifiEnabled();  
if (!isWifiEnabled) {  
    // 未开启wifi  
    // ....  
    return;  
}  

const connectionInfo = wifiManager.getConnectionInfo();  
const ipAddress = connectionInfo.getIpAddress();  
if (!ipAddress) {  
    // WiFi未连接  
    // ....  
    return;  
}  

// wifi已连接  
const rssi = connectionInfo.getRssi();  
// 0格 rssi<=-100  
// 1格 (-100, -88]  
// 2格 (-88, -77]  
// 3格 (-77, -55]  
// 4格 rssi>=-55
继续阅读 »
const Context = plus.android.importClass("android.content.Context");  
const WifiManager = plus.android.importClass("android.net.wifi.WifiManager");  
const wifiManager = plus.android.runtimeMainActivity().getSystemService(Context.WIFI_SERVICE);  
const WifiInfo = plus.android.importClass("android.net.wifi.WifiInfo");  

const isWifiEnabled = wifiManager.isWifiEnabled();  
if (!isWifiEnabled) {  
    // 未开启wifi  
    // ....  
    return;  
}  

const connectionInfo = wifiManager.getConnectionInfo();  
const ipAddress = connectionInfo.getIpAddress();  
if (!ipAddress) {  
    // WiFi未连接  
    // ....  
    return;  
}  

// wifi已连接  
const rssi = connectionInfo.getRssi();  
// 0格 rssi<=-100  
// 1格 (-100, -88]  
// 2格 (-88, -77]  
// 3格 (-77, -55]  
// 4格 rssi>=-55
收起阅读 »

【IOS相册权限】Native.js IOS相册权限获取 弹窗请求授权

Native.JS

优化官方推荐的uni.authorize文档中permission.js中的相册授权方法,判断是否有授权没有则弹窗请求授权。
发现很多小伙伴有这个需求,自己也在网上搜索了一番无果。
在此分享出来,方便大家开发。

// 判断相册权限是否开启 resolve()返回值可以根据需求更具体一点,在业务中拿到状态码后弹窗提示用户是否要去设置页修改权限  
function judgeIosPermissionPhotoLibrary() {  
    return new Promise((resolve, reject) => {  
        var PHAuthorizationStatus = {  
            NotDetermined: 0, // 未申请过权限  
            Restricted: 1, // 拒绝  
            Denied: 2,  // 拒绝  
            Authorized: 3, // 拥有  
            Limited: 4 // iOS 14 新增  
        };  
        if (!PHPhotoLibrary) {  
            var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");  
        }  
        var status  = PHPhotoLibrary.authorizationStatus();  
        if (status === PHAuthorizationStatus.NotDetermined) {  
            PHPhotoLibrary.requestAuthorization(() => {  
                const status = PHPhotoLibrary.authorizationStatus(); {  
                    if (status === PHAuthorizationStatus.Authorized) {  
                        plus.ios.deleteObject(PHPhotoLibrary);  
                        resolve(true)  
                    } else {  
                        plus.ios.deleteObject(PHPhotoLibrary);  
                        resolve(false)  
                    }  
                }  
            })  
        } else if (status === PHAuthorizationStatus.Authorized) {  
            plus.ios.deleteObject(PHPhotoLibrary);  
            resolve(true)  
        } else {  
            if (status === PHAuthorizationStatus.Denied || status === PHAuthorizationStatus.Restricted) {  
                console.log("您已拒绝访问相册权限,请在设置中手动开启。");   
            } else if (status === PHAuthorizationStatus.Limited) {  
                console.log("相册权限为有限访问。");   
            }  
            plus.ios.deleteObject(PHPhotoLibrary);  
            resolve(false)  
        }     
    })  

}
继续阅读 »

优化官方推荐的uni.authorize文档中permission.js中的相册授权方法,判断是否有授权没有则弹窗请求授权。
发现很多小伙伴有这个需求,自己也在网上搜索了一番无果。
在此分享出来,方便大家开发。

// 判断相册权限是否开启 resolve()返回值可以根据需求更具体一点,在业务中拿到状态码后弹窗提示用户是否要去设置页修改权限  
function judgeIosPermissionPhotoLibrary() {  
    return new Promise((resolve, reject) => {  
        var PHAuthorizationStatus = {  
            NotDetermined: 0, // 未申请过权限  
            Restricted: 1, // 拒绝  
            Denied: 2,  // 拒绝  
            Authorized: 3, // 拥有  
            Limited: 4 // iOS 14 新增  
        };  
        if (!PHPhotoLibrary) {  
            var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");  
        }  
        var status  = PHPhotoLibrary.authorizationStatus();  
        if (status === PHAuthorizationStatus.NotDetermined) {  
            PHPhotoLibrary.requestAuthorization(() => {  
                const status = PHPhotoLibrary.authorizationStatus(); {  
                    if (status === PHAuthorizationStatus.Authorized) {  
                        plus.ios.deleteObject(PHPhotoLibrary);  
                        resolve(true)  
                    } else {  
                        plus.ios.deleteObject(PHPhotoLibrary);  
                        resolve(false)  
                    }  
                }  
            })  
        } else if (status === PHAuthorizationStatus.Authorized) {  
            plus.ios.deleteObject(PHPhotoLibrary);  
            resolve(true)  
        } else {  
            if (status === PHAuthorizationStatus.Denied || status === PHAuthorizationStatus.Restricted) {  
                console.log("您已拒绝访问相册权限,请在设置中手动开启。");   
            } else if (status === PHAuthorizationStatus.Limited) {  
                console.log("相册权限为有限访问。");   
            }  
            plus.ios.deleteObject(PHPhotoLibrary);  
            resolve(false)  
        }     
    })  

}
收起阅读 »

使用Native.js引入IOS的NFC相关类失败,是不是Native.js不支持IOS的NFC功能?

NFC Native.JS iOS

使用以下代码测试,引入类打印结果为null:

getNfcAPI(){  
  let ndef = plus.ios.importClass("NFCNDEFReaderSession");  
  console.log("API",nedf);  
//结果为:API,null  
}
继续阅读 »

使用以下代码测试,引入类打印结果为null:

getNfcAPI(){  
  let ndef = plus.ios.importClass("NFCNDEFReaderSession");  
  console.log("API",nedf);  
//结果为:API,null  
}
收起阅读 »

安卓软件彻底重启

重启app,会杀掉所有进程以及服务后重启软件;plus.runtime.restart()只能重新加载,并非彻底重启,导致之前的服务进程无法退出

   const main = plus.android.runtimeMainActivity();  
   const Intent = plus.android.importClass("android.content.Intent");  
   const Process = plus.android.importClass("android.os.Process");  
   const intentMainActivity = new Intent(Intent.ACTION_MAIN);  
   const packageName = main.getPackageName();  
   intentMainActivity.setClassName(packageName, "io.dcloud.PandoraEntry");  
   intentMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
   main.startActivity(intentMainActivity);  
   Process.killProcess(Process.myPid());
继续阅读 »

重启app,会杀掉所有进程以及服务后重启软件;plus.runtime.restart()只能重新加载,并非彻底重启,导致之前的服务进程无法退出

   const main = plus.android.runtimeMainActivity();  
   const Intent = plus.android.importClass("android.content.Intent");  
   const Process = plus.android.importClass("android.os.Process");  
   const intentMainActivity = new Intent(Intent.ACTION_MAIN);  
   const packageName = main.getPackageName();  
   intentMainActivity.setClassName(packageName, "io.dcloud.PandoraEntry");  
   intentMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
   main.startActivity(intentMainActivity);  
   Process.killProcess(Process.myPid());
收起阅读 »

安卓11及以上版本申请所有文件访问权限

Native.JS

安卓11以后,文件读写权限申请变得更严格,常见的就是读取sdcard内的公共文件都提示没有权限,以下方法用于申请所有文件访问读写权限(并非所有空间都能读写,具体查看相关文档),添加MANAGE_EXTERNAL_STORAGE权限可能导致google play审核不通过,目前一般只允许文件管理器之类主要功能依赖文件读写的应用上架。

/**  
     * 安卓11及以上版本(SDK>=30),需要申请MANAGE_EXTERNAL_STORAGE权限,否则按钮无法点击,如下  
     * 在manifest.json>app-plus>distribute>android>permissions中添加权限  
     * <uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>  
     */  
    requestPermission() {  
      const main = plus.android.runtimeMainActivity();  
      const pkName = main.getPackageName();  
      const Intent = plus.android.importClass("android.content.Intent");  
      const Build = plus.android.importClass("android.os.Build");  
      const Settings = plus.android.importClass("android.provider.Settings");  
      const Environment = plus.android.importClass("android.os.Environment");  
      if (Build.VERSION.SDK_INT >= 30) {  
        // 权限未获取跳转到设置页  
        if (!Environment.isExternalStorageManager()) {  
          let intent = new Intent(  
            Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION  
          );  
          const Uri = plus.android.importClass("android.net.Uri");  
          const uri = Uri.fromParts("package", pkName, null);  
          intent.setData(uri);  
          main.startActivity(intent);  
        }  
        // 权限已获取,自定义处理  
        else {  
        }  
      }  
    }
继续阅读 »

安卓11以后,文件读写权限申请变得更严格,常见的就是读取sdcard内的公共文件都提示没有权限,以下方法用于申请所有文件访问读写权限(并非所有空间都能读写,具体查看相关文档),添加MANAGE_EXTERNAL_STORAGE权限可能导致google play审核不通过,目前一般只允许文件管理器之类主要功能依赖文件读写的应用上架。

/**  
     * 安卓11及以上版本(SDK>=30),需要申请MANAGE_EXTERNAL_STORAGE权限,否则按钮无法点击,如下  
     * 在manifest.json>app-plus>distribute>android>permissions中添加权限  
     * <uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>  
     */  
    requestPermission() {  
      const main = plus.android.runtimeMainActivity();  
      const pkName = main.getPackageName();  
      const Intent = plus.android.importClass("android.content.Intent");  
      const Build = plus.android.importClass("android.os.Build");  
      const Settings = plus.android.importClass("android.provider.Settings");  
      const Environment = plus.android.importClass("android.os.Environment");  
      if (Build.VERSION.SDK_INT >= 30) {  
        // 权限未获取跳转到设置页  
        if (!Environment.isExternalStorageManager()) {  
          let intent = new Intent(  
            Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION  
          );  
          const Uri = plus.android.importClass("android.net.Uri");  
          const uri = Uri.fromParts("package", pkName, null);  
          intent.setData(uri);  
          main.startActivity(intent);  
        }  
        // 权限已获取,自定义处理  
        else {  
        }  
      }  
    }
收起阅读 »

wifi打印机打印(二维码,条形码等)

  1. 打印机,需要插usb(或者微信小程序设置wifi)
  2. 打印机的默认端口是9100(一般是,具体看购买的打印机)
  3. wifitool.js是用于连接打印机的
  4. 此文章是用的CPCL指令,可以根据自己的指令格式修改(var command = tsc.jpPrinter.createNew();)
    vue

    <template>  
    <view>  
    <button @click="printSocket">WiFi打印</button>  
    </view>  
    </template>

    js

    
    <script>  
    import tsc from "@/static/libs/tsc.js";  
    import wifiTool from "@/static/libs/WifiTool.js";  
    export default {  
    data() {  
    return {  
      ip: "192.168.4.245",  
      port: 9100,  
      str: "yyy",  
    };  
    },  
    mounted() {  
    wifiTool.connectWifi("192.168.4.245", 9100);  
    },  
    methods: {  
    test(str, ip, port) {  
      str = "test";  
      var Socket = plus.android.importClass("java.net.Socket");  
      var JavaByte = plus.android.importClass("java.lang.Byte");  
      var PrintWriter = plus.android.importClass("java.io.PrintWriter");  
      var BufferedWriter = plus.android.importClass("java.io.BufferedWriter");  
      var OutputStreamWriter = plus.android.importClass("java.io.OutputStreamWriter");  
      var BufferedReader = plus.android.importClass("java.io.BufferedReader");  
      var InputStreamReader = plus.android.importClass("java.io.InputStreamReader");  
    
      //测试改良  
      var StrictMode = plus.android.importClass("android.os.StrictMode");  
      var Build = plus.android.importClass("android.os.Build");  
      if (Build.VERSION.SDK_INT > 9) {  
        var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
        StrictMode.setThreadPolicy(policy);  
      }  
      var socket = new Socket(ip, port);  
    
      var outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());  
      var bufferWriter = new BufferedWriter(outputStreamWriter);  
      var out = new PrintWriter(bufferWriter, true);  
    
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 200, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      //   command.setMag(2, 2);  
      //   command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      //   command.setMag(2, 2);  
      //   command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPagePrint();  
      let data = command.getData();  
    
      out.println(data);  
      socket.setSoTimeout(3000);  
      socket.close();  
    },  
    printSocket() {  
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 250, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      command.setMag(2, 2);  
      command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      command.setMag(2, 2);  
      command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPostfeed(32);//打印后走纸  
      command.setPagePrint();  
      let data = command.getData();  
      wifiTool.sendData(data);  
    },  
    connectWifi(ip, port) {  
      if (plus.os.name == "Android") {  
        // plus.nativeUI.showWaiting("正在打印中。。。");  
        var Socket = plus.android.importClass("java.net.Socket");  
        var socket;  
        var outputStream;  
        //解决高低版本兼容  
        var StrictMode = plus.android.importClass("android.os.StrictMode");  
        var Build = plus.android.importClass("android.os.Build");  
        if (Build.VERSION.SDK_INT > 9) {  
          var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
          StrictMode.setThreadPolicy(policy);  
        }  
        try {  
          socket = new Socket(ip, port);  
          socket.setKeepAlive(true);  
          outputStream = socket.getOutputStream();  
          plus.android.importClass(outputStream);  
          //   var bytes = plus.android.invoke(str, "getBytes", "gbk");  
          uni.showToast({  
            title: "wifi连接成功",  
          });  
    
          //   plus.nativeUI.closeWaiting();  
        } catch (e) {  
          console.log("网络连接超时,请重新连接!");  
          //TODO handle the exception  
          //   plus.nativeUI.closeWaiting();  
        }  
      }  
    },  
    },  
    };  
    </script>  
WifiTool.js  

```javascript  

/**  
 * 初始化参数  
 */  
//#ifdef APP-PLUS  
var Socket = plus.android.importClass("java.net.Socket");  
var socket;  
var outputStream;  
//解决高低版本兼容  
var StrictMode = plus.android.importClass("android.os.StrictMode");  
var Build = plus.android.importClass("android.os.Build");  
//#endif  
/**  
 * 构造对象  
 */  
var wifiTool = {  
    connectWifi(ip, port) {  
        if (Build.VERSION.SDK_INT > 9) {  
            var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
            StrictMode.setThreadPolicy(policy);  
        }  
        try {  
            socket = new Socket(ip, port);  
            socket.setKeepAlive(true);  
            outputStream = socket.getOutputStream();  
            plus.android.importClass(outputStream);  
            //   var bytes = plus.android.invoke(str, "getBytes", "gbk");  
            uni.showToast({  
                title: 'wifi连接成功',  
            });  

            //   plus.nativeUI.closeWaiting();  
        } catch (e) {  
            console.log("网络连接超时,请重新连接!")  
            //TODO handle the exception  
            //   plus.nativeUI.closeWaiting();  
        }  
    },  
    sendData(data) {  

        console.log(outputStream);  
        outputStream.write(data);  
        outputStream.flush();  
        // 关闭socket  
        // socket.shutdownOutput();  
        console.log(socket);  
    }  
}  

module.exports = wifiTool

tsc.js

/**  
 * tsc 命令打印工具类  
 * 2021.04.26 uni-app版本  
 * @auth boolTrue  
 */  
var encode = require("./encoding.js");  
var jpPrinter = {  
    createNew: function () {  
        var jpPrinter = {};  
        var data = "";  
        var command = []  
        var rawCommand = ''  

        jpPrinter.name = "标签模式";  

        jpPrinter.init = function (x, y, z, h, q) {  
            data = "! " + x + " " + y + " " + z + " " + h + " " + q + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.addCommand = function (content) { //将指令转成数组装起  
            //#ifdef MP-WEIXIN  
            var code = new encode.TextEncoder(  
                'gb18030', {  
                NONSTANDARD_allowLegacyEncoding: true  
            }).encode(content)  
            for (var i = 0; i < code.length; ++i) {  
                command.push(code[i])  
            }  
            //#endif  

            //#ifdef APP-PLUS  
            let byteCommand = plus.android.invoke(content, 'getBytes', 'gb18030');  
            for (var i = 0; i < byteCommand.length; ++i) {  
                command.push(byteCommand[i])  
            }  
            //#endif  

            console.log('command--:', content)  
            rawCommand += content  
        }  

        function intToByte(i) {  
            // 此处关键 -- android是java平台 byte数值范围是 [-128, 127]  
            // 因为java平台的byte类型是有符号的 最高位表示符号,所以数值范围固定  
            // 而图片计算出来的是数值是 0 -255 属于int类型  
            // 所以把int 转换成byte类型   
            //#ifdef APP-PLUS  
            var b = i & 0xFF;  
            var c = 0;  
            if (b >= 128) {  
                c = b % 128;  
                c = -1 * (128 - c);  
            } else {  
                c = b;  
            }  
            return c  
            //#endif  
            // 而微信小程序不需要,因为小程序api接收的是 无符号8位  
            //#ifdef MP-WEIXIN  
            return i  
            //#endif  
        }  
        jpPrinter.setPostfeed = function (length) { //打印之后走纸距离指令  
            data = "POSTFEED " +length + "\r\n";  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setSize = function (pageWidght, pageHeight) { //设置页面大小  
            data = "SIZE " + pageWidght.toString() + " mm" + "," + pageHeight.toString() + " mm" + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setSpeed = function (printSpeed) { //设置打印机速度  
            data = "SPEED " + printSpeed.toString() + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setDensity = function (printDensity) { //设置打印机浓度  
            data = "DENSITY " + printDensity.toString() + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setGap = function (printGap) { //传感器  
            data = "GAP " + printGap.toString() + " mm\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setCountry = function (country) { //选择国际字符集  
            /*  
            001:USA  
            002:French  
            003:Latin America  
            034:Spanish  
            039:Italian  
            044:United Kingdom  
            046:Swedish  
            047:Norwegian  
            049:German  
             */  
            data = "COUNTRY " + country + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setCodepage = function (codepage) { //选择国际代码页  
            /*  
            8-bit codepage 字符集代表  
            437:United States  
            850:Multilingual  
            852:Slavic  
            860:Portuguese  
            863:Canadian/French  
            865:Nordic  
            Windows code page  
            1250:Central Europe  
            1252:Latin I  
            1253:Greek  
            1254:Turkish  
            以下代码页仅限于 12×24 dot 英数字体  
            WestEurope:WestEurope  
            Greek:Greek  
            Hebrew:Hebrew  
            EastEurope:EastEurope  
            Iran:Iran  
            IranII:IranII  
            Latvian:Latvian  
            Arabic:Arabic  
            Vietnam:Vietnam  
            Uygur:Uygur  
            Thai:Thai  
            1252:Latin I  
            1257:WPC1257  
            1251:WPC1251  
            866:Cyrillic  
            858:PC858  
            747:PC747  
            864:PC864  
            1001:PC100  
            */  
            data = "CODEPAGE " + codepage + "\r\n";  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setCls = function () { //清除打印机缓存  
            data = "CLS " + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFeed = function (feed) { //将纸向前推出n  
            data = "FEED " + feed + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBackFeed = function (backup) { //将纸向后回拉n  
            data = "BACKFEED " + backup + "\r\n";  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setDirection = function (direction) { //设置打印方向,参考编程手册    
            data = "DIRECTION " + direction + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setReference = function (x, y) { //设置坐标原点,与打印方向有关  
            data = "REFERENCE " + x + "," + y + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFrom = function () { //定位控制指令  
            data = "FORM \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFromfeed = function () { //根据Size进一张标签纸  
            data = "FORMFEED \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setHome = function () { //根据Size找到下一张标签纸的位置  
            data = "HOME \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setSound = function (level, interval) { //控制蜂鸣器  
            data = "SOUND " + level + "," + interval + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setLimitfeed = function (limit) { // 检测垂直间距  
            data = "LIMITFEED " + limit + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBar = function (x, y, width, height) { //绘制线条  
            data = "BAR " + x + "," + y + "," + width + "," + height + "\r\n"  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBox = function (x_start, y_start, x_end, y_end, thickness) { //绘制方框  
            data = "BOX " + x_start + "," + y_start + "," + x_end + "," + y_end + "," + thickness + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setErase = function (x_start, y_start, x_width, y_height) { //清除指定区域的数据  
            data = "ERASE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setReverse = function (x_start, y_start, x_width, y_height) { //将指定的区域反相打印  
            data = "REVERSE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setText1 = function (font, s, x, y, str) { //打印文字  
            data = "TEXT " + font + " " + s + " " + x + " " + y + "  " + str + "\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setText = function (x, y, font, x_, y_, str) { //打印文字  
            data = "TEXT " + x + "," + y + ",\"" + font + "\"," + 0 + "," + x_ + "," + y_ + "," + "\"" +  
                str + "\"\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setMag = function (w,h) { //打印二维码  
            data = "SETMAG " + w + " " + h + "\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setQR = function (x, y, m, u, content) { //打印二维码  
            data = "BARCODE QR " + x + " " + y + " M " + m + " U " + u + "\r\n MA," + content + "\r\nENDQR\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setPDF = function (type, x, y,xd,yd,c,s, content) { //打印条形  
            data = "BARCODE " + type + " " + x + " " + y + " XD " + xd + " YD " + yd + " C " + c + " S " + s + "\r\n"+ content+ "\r\nENDPDF\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setBarCode = function (type, w, r, h, x, y, content) { //打印条形码  
            data = "BARCODE " + type + " " + w + " " + r + " " + h + " " + x + " " + y + " " + content + "\r\n"  
            jpPrinter.addCommand(data)  
        };  

        // 固定灰度阈值(128以上的都看作白色)  
        jpPrinter.setBitmap = function (x, y, mode, res) { //添加图片,res为画布参数  
            var width = parseInt((res.width) / 8 * 8 / 8)  
            var height = res.height  
            var imgWidth = res.width  
            var time = 1;  
            var temp = res.data.length - width * 32;  
            var pointList = []  
            var resultData = []  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            //console.log(res.data)  
            console.log('---以上是原始数据---')  

            //for循环顺序不要错了,外层遍历高度,内层遍历宽度,因为横向每8个像素点组成一个字节  
            for (var y = 0; y < height; y++) {  
                for (var x = 0; x < imgWidth; x++) {  
                    let r = res.data[(y * imgWidth + x) * 4];  
                    let g = res.data[(y * imgWidth + x) * 4 + 1];  
                    let b = res.data[(y * imgWidth + x) * 4 + 2];  
                    let a = res.data[(y * imgWidth + x) * 4 + 3]  
                    //console.log(`当前${y}行${x}列像素,rgba值:(${r},${g},${b},${a})`)  
                    // 像素灰度值  
                    let grayColor = r * 0.299 + g * 0.587 + b * 0.114  
                    //灰度值大于128位   
                    //1不打印, 0打印 (参考:佳博标签打印机编程手册tspl)  
                    if (grayColor > 128) {  
                        pointList.push(1)  
                    } else {  
                        pointList.push(0)  
                    }  
                }  
            }  
            //console.log(pointList)  
            for (var i = 0; i < pointList.length; i += 8) {  
                var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i +  
                    3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 +  
                    pointList[i + 7]  
                resultData.push(p)  
            }  
            console.log('最终数据:')  
            //console.log(resultData)  
            for (var i = 0; i < resultData.length; ++i) {  
                command.push(intToByte(resultData[i]))  
            }  
        }  

        jpPrinter.setBitmap2 = function (x, y, mode, res) { //添加图片,res为画布参数  
            var w = res.width  
            var width = parseInt((res.width + 7) / 8 * 8 / 8)  
            var height = res.height;  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            var r = []  
            var bits = new Uint8Array(height * width);  
            for (y = 0; y < height; y++) {  
                for (x = 0; x < w; x++) {  
                    let r = res.data[(y * w + x) * 4];  
                    let g = res.data[(y * w + x) * 4 + 1];  
                    let b = res.data[(y * w + x) * 4 + 2];  
                    let a = res.data[(y * w + x) * 4 + 3]  
                    var color = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) <<  
                        0);  
                    if ((color & 0xFF) > 128) {  
                        bits[parseInt(y * width + x / 8)] |= (0x80 >> (x % 8));  
                    }  
                }  
            }  
            for (var i = 0; i < bits.length; i++) {  
                //command.push((~bits[i]) & 0xFF);  
                command.push(intToByte(bits[i]));  
                //r.push((~bits[i]) & 0xFF);  
            }  
        }  

        // 平均灰度阈值(先计算平均灰度,然后大于平均灰度的都算作白色)  
        jpPrinter.setBitmap3 = function (x, y, mode, res) { //添加图片,res为画布参数  
            var width = parseInt((res.width) / 8 * 8 / 8)  
            var height = res.height  
            var imgWidth = res.width  
            var time = 1;  
            var temp = res.data.length - width * 32;  
            var pointList = []  
            var resultData = []  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            //console.log(res.data)  
            console.log('---以上是原始数据---')  

            let sumRed = 0,  
                sumGreen = 0,  
                sumBlue = 0;  
            let total = height * imgWidth;  
            let pix = res.data;  
            for (var i = 0; i < pix.length; i += 4) {  
                sumRed += pix[i]  
                sumGreen += pix[i + 1]  
                sumBlue += pix[i + 2]  
            }  

            let avgRed = parseInt(sumRed / total);  
            let avgGreen = parseInt(sumGreen / total);  
            let avgBlue = parseInt(sumBlue / total);  
            let avgGrayColor = avgRed * 0.299 + avgGreen * 0.587 + avgBlue * 0.114  

            //for循环顺序不要错了,外层遍历高度,内层遍历宽度,因为横向每8个像素点组成一个字节  
            for (var y = 0; y < height; y++) {  
                for (var x = 0; x < imgWidth; x++) {  
                    let r = res.data[(y * imgWidth + x) * 4];  
                    let g = res.data[(y * imgWidth + x) * 4 + 1];  
                    let b = res.data[(y * imgWidth + x) * 4 + 2];  
                    let a = res.data[(y * imgWidth + x) * 4 + 3]  
                    // 像素灰度值  
                    let grayColor = r * 0.299 + g * 0.587 + b * 0.114  
                    //灰度值大于128位   
                    //1不打印, 0打印 (参考:佳博标签打印机编程手册tspl)  
                    if (grayColor > avgGrayColor) {  
                        pointList.push(1)  
                    } else {  
                        pointList.push(0)  
                    }  
                }  
            }  
            //console.log(pointList)  
            for (var i = 0; i < pointList.length; i += 8) {  
                var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i +  
                    3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 +  
                    pointList[i + 7]  
                resultData.push(p)  

            }  
            console.log('最终数据:')  
            //console.log(resultData)  
            for (var i = 0; i < resultData.length; ++i) {  
                command.push(intToByte(resultData[i]))  
            }  
        }  

        jpPrinter.RawCommand = function (data) {  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setPagePrint = function () { //打印页面  
            // data = "PRINT 1,1\r\n"  
            data = "PRINT \r\n"  
            jpPrinter.addCommand(data)  
        };  
        //获取打印数据  
        jpPrinter.getData = function () {  
            return command;  
        };  

        jpPrinter.getRawData = function () {  
            return rawCommand;  
        };  
        jpPrinter.clearCommand = function () {  
            rawCommand = ''  
        };  

        return jpPrinter;  
    }  
};  

module.exports.jpPrinter = jpPrinter;  
继续阅读 »
  1. 打印机,需要插usb(或者微信小程序设置wifi)
  2. 打印机的默认端口是9100(一般是,具体看购买的打印机)
  3. wifitool.js是用于连接打印机的
  4. 此文章是用的CPCL指令,可以根据自己的指令格式修改(var command = tsc.jpPrinter.createNew();)
    vue

    <template>  
    <view>  
    <button @click="printSocket">WiFi打印</button>  
    </view>  
    </template>

    js

    
    <script>  
    import tsc from "@/static/libs/tsc.js";  
    import wifiTool from "@/static/libs/WifiTool.js";  
    export default {  
    data() {  
    return {  
      ip: "192.168.4.245",  
      port: 9100,  
      str: "yyy",  
    };  
    },  
    mounted() {  
    wifiTool.connectWifi("192.168.4.245", 9100);  
    },  
    methods: {  
    test(str, ip, port) {  
      str = "test";  
      var Socket = plus.android.importClass("java.net.Socket");  
      var JavaByte = plus.android.importClass("java.lang.Byte");  
      var PrintWriter = plus.android.importClass("java.io.PrintWriter");  
      var BufferedWriter = plus.android.importClass("java.io.BufferedWriter");  
      var OutputStreamWriter = plus.android.importClass("java.io.OutputStreamWriter");  
      var BufferedReader = plus.android.importClass("java.io.BufferedReader");  
      var InputStreamReader = plus.android.importClass("java.io.InputStreamReader");  
    
      //测试改良  
      var StrictMode = plus.android.importClass("android.os.StrictMode");  
      var Build = plus.android.importClass("android.os.Build");  
      if (Build.VERSION.SDK_INT > 9) {  
        var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
        StrictMode.setThreadPolicy(policy);  
      }  
      var socket = new Socket(ip, port);  
    
      var outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());  
      var bufferWriter = new BufferedWriter(outputStreamWriter);  
      var out = new PrintWriter(bufferWriter, true);  
    
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 200, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      //   command.setMag(2, 2);  
      //   command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      //   command.setMag(2, 2);  
      //   command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPagePrint();  
      let data = command.getData();  
    
      out.println(data);  
      socket.setSoTimeout(3000);  
      socket.close();  
    },  
    printSocket() {  
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 250, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      command.setMag(2, 2);  
      command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      command.setMag(2, 2);  
      command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPostfeed(32);//打印后走纸  
      command.setPagePrint();  
      let data = command.getData();  
      wifiTool.sendData(data);  
    },  
    connectWifi(ip, port) {  
      if (plus.os.name == "Android") {  
        // plus.nativeUI.showWaiting("正在打印中。。。");  
        var Socket = plus.android.importClass("java.net.Socket");  
        var socket;  
        var outputStream;  
        //解决高低版本兼容  
        var StrictMode = plus.android.importClass("android.os.StrictMode");  
        var Build = plus.android.importClass("android.os.Build");  
        if (Build.VERSION.SDK_INT > 9) {  
          var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
          StrictMode.setThreadPolicy(policy);  
        }  
        try {  
          socket = new Socket(ip, port);  
          socket.setKeepAlive(true);  
          outputStream = socket.getOutputStream();  
          plus.android.importClass(outputStream);  
          //   var bytes = plus.android.invoke(str, "getBytes", "gbk");  
          uni.showToast({  
            title: "wifi连接成功",  
          });  
    
          //   plus.nativeUI.closeWaiting();  
        } catch (e) {  
          console.log("网络连接超时,请重新连接!");  
          //TODO handle the exception  
          //   plus.nativeUI.closeWaiting();  
        }  
      }  
    },  
    },  
    };  
    </script>  
WifiTool.js  

```javascript  

/**  
 * 初始化参数  
 */  
//#ifdef APP-PLUS  
var Socket = plus.android.importClass("java.net.Socket");  
var socket;  
var outputStream;  
//解决高低版本兼容  
var StrictMode = plus.android.importClass("android.os.StrictMode");  
var Build = plus.android.importClass("android.os.Build");  
//#endif  
/**  
 * 构造对象  
 */  
var wifiTool = {  
    connectWifi(ip, port) {  
        if (Build.VERSION.SDK_INT > 9) {  
            var policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
            StrictMode.setThreadPolicy(policy);  
        }  
        try {  
            socket = new Socket(ip, port);  
            socket.setKeepAlive(true);  
            outputStream = socket.getOutputStream();  
            plus.android.importClass(outputStream);  
            //   var bytes = plus.android.invoke(str, "getBytes", "gbk");  
            uni.showToast({  
                title: 'wifi连接成功',  
            });  

            //   plus.nativeUI.closeWaiting();  
        } catch (e) {  
            console.log("网络连接超时,请重新连接!")  
            //TODO handle the exception  
            //   plus.nativeUI.closeWaiting();  
        }  
    },  
    sendData(data) {  

        console.log(outputStream);  
        outputStream.write(data);  
        outputStream.flush();  
        // 关闭socket  
        // socket.shutdownOutput();  
        console.log(socket);  
    }  
}  

module.exports = wifiTool

tsc.js

/**  
 * tsc 命令打印工具类  
 * 2021.04.26 uni-app版本  
 * @auth boolTrue  
 */  
var encode = require("./encoding.js");  
var jpPrinter = {  
    createNew: function () {  
        var jpPrinter = {};  
        var data = "";  
        var command = []  
        var rawCommand = ''  

        jpPrinter.name = "标签模式";  

        jpPrinter.init = function (x, y, z, h, q) {  
            data = "! " + x + " " + y + " " + z + " " + h + " " + q + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.addCommand = function (content) { //将指令转成数组装起  
            //#ifdef MP-WEIXIN  
            var code = new encode.TextEncoder(  
                'gb18030', {  
                NONSTANDARD_allowLegacyEncoding: true  
            }).encode(content)  
            for (var i = 0; i < code.length; ++i) {  
                command.push(code[i])  
            }  
            //#endif  

            //#ifdef APP-PLUS  
            let byteCommand = plus.android.invoke(content, 'getBytes', 'gb18030');  
            for (var i = 0; i < byteCommand.length; ++i) {  
                command.push(byteCommand[i])  
            }  
            //#endif  

            console.log('command--:', content)  
            rawCommand += content  
        }  

        function intToByte(i) {  
            // 此处关键 -- android是java平台 byte数值范围是 [-128, 127]  
            // 因为java平台的byte类型是有符号的 最高位表示符号,所以数值范围固定  
            // 而图片计算出来的是数值是 0 -255 属于int类型  
            // 所以把int 转换成byte类型   
            //#ifdef APP-PLUS  
            var b = i & 0xFF;  
            var c = 0;  
            if (b >= 128) {  
                c = b % 128;  
                c = -1 * (128 - c);  
            } else {  
                c = b;  
            }  
            return c  
            //#endif  
            // 而微信小程序不需要,因为小程序api接收的是 无符号8位  
            //#ifdef MP-WEIXIN  
            return i  
            //#endif  
        }  
        jpPrinter.setPostfeed = function (length) { //打印之后走纸距离指令  
            data = "POSTFEED " +length + "\r\n";  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setSize = function (pageWidght, pageHeight) { //设置页面大小  
            data = "SIZE " + pageWidght.toString() + " mm" + "," + pageHeight.toString() + " mm" + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setSpeed = function (printSpeed) { //设置打印机速度  
            data = "SPEED " + printSpeed.toString() + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setDensity = function (printDensity) { //设置打印机浓度  
            data = "DENSITY " + printDensity.toString() + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setGap = function (printGap) { //传感器  
            data = "GAP " + printGap.toString() + " mm\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setCountry = function (country) { //选择国际字符集  
            /*  
            001:USA  
            002:French  
            003:Latin America  
            034:Spanish  
            039:Italian  
            044:United Kingdom  
            046:Swedish  
            047:Norwegian  
            049:German  
             */  
            data = "COUNTRY " + country + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setCodepage = function (codepage) { //选择国际代码页  
            /*  
            8-bit codepage 字符集代表  
            437:United States  
            850:Multilingual  
            852:Slavic  
            860:Portuguese  
            863:Canadian/French  
            865:Nordic  
            Windows code page  
            1250:Central Europe  
            1252:Latin I  
            1253:Greek  
            1254:Turkish  
            以下代码页仅限于 12×24 dot 英数字体  
            WestEurope:WestEurope  
            Greek:Greek  
            Hebrew:Hebrew  
            EastEurope:EastEurope  
            Iran:Iran  
            IranII:IranII  
            Latvian:Latvian  
            Arabic:Arabic  
            Vietnam:Vietnam  
            Uygur:Uygur  
            Thai:Thai  
            1252:Latin I  
            1257:WPC1257  
            1251:WPC1251  
            866:Cyrillic  
            858:PC858  
            747:PC747  
            864:PC864  
            1001:PC100  
            */  
            data = "CODEPAGE " + codepage + "\r\n";  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setCls = function () { //清除打印机缓存  
            data = "CLS " + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFeed = function (feed) { //将纸向前推出n  
            data = "FEED " + feed + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBackFeed = function (backup) { //将纸向后回拉n  
            data = "BACKFEED " + backup + "\r\n";  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setDirection = function (direction) { //设置打印方向,参考编程手册    
            data = "DIRECTION " + direction + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setReference = function (x, y) { //设置坐标原点,与打印方向有关  
            data = "REFERENCE " + x + "," + y + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFrom = function () { //定位控制指令  
            data = "FORM \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setFromfeed = function () { //根据Size进一张标签纸  
            data = "FORMFEED \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setHome = function () { //根据Size找到下一张标签纸的位置  
            data = "HOME \r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setSound = function (level, interval) { //控制蜂鸣器  
            data = "SOUND " + level + "," + interval + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setLimitfeed = function (limit) { // 检测垂直间距  
            data = "LIMITFEED " + limit + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBar = function (x, y, width, height) { //绘制线条  
            data = "BAR " + x + "," + y + "," + width + "," + height + "\r\n"  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setBox = function (x_start, y_start, x_end, y_end, thickness) { //绘制方框  
            data = "BOX " + x_start + "," + y_start + "," + x_end + "," + y_end + "," + thickness + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setErase = function (x_start, y_start, x_width, y_height) { //清除指定区域的数据  
            data = "ERASE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";  
            jpPrinter.addCommand(data)  
        };  

        jpPrinter.setReverse = function (x_start, y_start, x_width, y_height) { //将指定的区域反相打印  
            data = "REVERSE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n";  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setText1 = function (font, s, x, y, str) { //打印文字  
            data = "TEXT " + font + " " + s + " " + x + " " + y + "  " + str + "\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setText = function (x, y, font, x_, y_, str) { //打印文字  
            data = "TEXT " + x + "," + y + ",\"" + font + "\"," + 0 + "," + x_ + "," + y_ + "," + "\"" +  
                str + "\"\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setMag = function (w,h) { //打印二维码  
            data = "SETMAG " + w + " " + h + "\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setQR = function (x, y, m, u, content) { //打印二维码  
            data = "BARCODE QR " + x + " " + y + " M " + m + " U " + u + "\r\n MA," + content + "\r\nENDQR\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setPDF = function (type, x, y,xd,yd,c,s, content) { //打印条形  
            data = "BARCODE " + type + " " + x + " " + y + " XD " + xd + " YD " + yd + " C " + c + " S " + s + "\r\n"+ content+ "\r\nENDPDF\r\n"  
            jpPrinter.addCommand(data)  
        };  
        jpPrinter.setBarCode = function (type, w, r, h, x, y, content) { //打印条形码  
            data = "BARCODE " + type + " " + w + " " + r + " " + h + " " + x + " " + y + " " + content + "\r\n"  
            jpPrinter.addCommand(data)  
        };  

        // 固定灰度阈值(128以上的都看作白色)  
        jpPrinter.setBitmap = function (x, y, mode, res) { //添加图片,res为画布参数  
            var width = parseInt((res.width) / 8 * 8 / 8)  
            var height = res.height  
            var imgWidth = res.width  
            var time = 1;  
            var temp = res.data.length - width * 32;  
            var pointList = []  
            var resultData = []  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            //console.log(res.data)  
            console.log('---以上是原始数据---')  

            //for循环顺序不要错了,外层遍历高度,内层遍历宽度,因为横向每8个像素点组成一个字节  
            for (var y = 0; y < height; y++) {  
                for (var x = 0; x < imgWidth; x++) {  
                    let r = res.data[(y * imgWidth + x) * 4];  
                    let g = res.data[(y * imgWidth + x) * 4 + 1];  
                    let b = res.data[(y * imgWidth + x) * 4 + 2];  
                    let a = res.data[(y * imgWidth + x) * 4 + 3]  
                    //console.log(`当前${y}行${x}列像素,rgba值:(${r},${g},${b},${a})`)  
                    // 像素灰度值  
                    let grayColor = r * 0.299 + g * 0.587 + b * 0.114  
                    //灰度值大于128位   
                    //1不打印, 0打印 (参考:佳博标签打印机编程手册tspl)  
                    if (grayColor > 128) {  
                        pointList.push(1)  
                    } else {  
                        pointList.push(0)  
                    }  
                }  
            }  
            //console.log(pointList)  
            for (var i = 0; i < pointList.length; i += 8) {  
                var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i +  
                    3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 +  
                    pointList[i + 7]  
                resultData.push(p)  
            }  
            console.log('最终数据:')  
            //console.log(resultData)  
            for (var i = 0; i < resultData.length; ++i) {  
                command.push(intToByte(resultData[i]))  
            }  
        }  

        jpPrinter.setBitmap2 = function (x, y, mode, res) { //添加图片,res为画布参数  
            var w = res.width  
            var width = parseInt((res.width + 7) / 8 * 8 / 8)  
            var height = res.height;  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            var r = []  
            var bits = new Uint8Array(height * width);  
            for (y = 0; y < height; y++) {  
                for (x = 0; x < w; x++) {  
                    let r = res.data[(y * w + x) * 4];  
                    let g = res.data[(y * w + x) * 4 + 1];  
                    let b = res.data[(y * w + x) * 4 + 2];  
                    let a = res.data[(y * w + x) * 4 + 3]  
                    var color = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) <<  
                        0);  
                    if ((color & 0xFF) > 128) {  
                        bits[parseInt(y * width + x / 8)] |= (0x80 >> (x % 8));  
                    }  
                }  
            }  
            for (var i = 0; i < bits.length; i++) {  
                //command.push((~bits[i]) & 0xFF);  
                command.push(intToByte(bits[i]));  
                //r.push((~bits[i]) & 0xFF);  
            }  
        }  

        // 平均灰度阈值(先计算平均灰度,然后大于平均灰度的都算作白色)  
        jpPrinter.setBitmap3 = function (x, y, mode, res) { //添加图片,res为画布参数  
            var width = parseInt((res.width) / 8 * 8 / 8)  
            var height = res.height  
            var imgWidth = res.width  
            var time = 1;  
            var temp = res.data.length - width * 32;  
            var pointList = []  
            var resultData = []  
            console.log(width + "--" + height)  
            data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ","  
            jpPrinter.addCommand(data)  
            //console.log(res.data)  
            console.log('---以上是原始数据---')  

            let sumRed = 0,  
                sumGreen = 0,  
                sumBlue = 0;  
            let total = height * imgWidth;  
            let pix = res.data;  
            for (var i = 0; i < pix.length; i += 4) {  
                sumRed += pix[i]  
                sumGreen += pix[i + 1]  
                sumBlue += pix[i + 2]  
            }  

            let avgRed = parseInt(sumRed / total);  
            let avgGreen = parseInt(sumGreen / total);  
            let avgBlue = parseInt(sumBlue / total);  
            let avgGrayColor = avgRed * 0.299 + avgGreen * 0.587 + avgBlue * 0.114  

            //for循环顺序不要错了,外层遍历高度,内层遍历宽度,因为横向每8个像素点组成一个字节  
            for (var y = 0; y < height; y++) {  
                for (var x = 0; x < imgWidth; x++) {  
                    let r = res.data[(y * imgWidth + x) * 4];  
                    let g = res.data[(y * imgWidth + x) * 4 + 1];  
                    let b = res.data[(y * imgWidth + x) * 4 + 2];  
                    let a = res.data[(y * imgWidth + x) * 4 + 3]  
                    // 像素灰度值  
                    let grayColor = r * 0.299 + g * 0.587 + b * 0.114  
                    //灰度值大于128位   
                    //1不打印, 0打印 (参考:佳博标签打印机编程手册tspl)  
                    if (grayColor > avgGrayColor) {  
                        pointList.push(1)  
                    } else {  
                        pointList.push(0)  
                    }  
                }  
            }  
            //console.log(pointList)  
            for (var i = 0; i < pointList.length; i += 8) {  
                var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i +  
                    3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 +  
                    pointList[i + 7]  
                resultData.push(p)  

            }  
            console.log('最终数据:')  
            //console.log(resultData)  
            for (var i = 0; i < resultData.length; ++i) {  
                command.push(intToByte(resultData[i]))  
            }  
        }  

        jpPrinter.RawCommand = function (data) {  
            jpPrinter.addCommand(data)  
        }  

        jpPrinter.setPagePrint = function () { //打印页面  
            // data = "PRINT 1,1\r\n"  
            data = "PRINT \r\n"  
            jpPrinter.addCommand(data)  
        };  
        //获取打印数据  
        jpPrinter.getData = function () {  
            return command;  
        };  

        jpPrinter.getRawData = function () {  
            return rawCommand;  
        };  
        jpPrinter.clearCommand = function () {  
            rawCommand = ''  
        };  

        return jpPrinter;  
    }  
};  

module.exports.jpPrinter = jpPrinter;  
收起阅读 »

蓝牙连接便携式打印机(芝柯)

蓝牙打印

vue

<template>  
  <view>  
    <button @click="searchBle">搜索蓝牙</button>  
    <view style="margin-top: 30upx" :key="index" v-for="(item, index) in devices">  
      <button style="width: 400upx; color: #0081ff" @click="onConn(item)">  
        {{ item.name }}  
      </button>  
    </view>  
    <button style="margin-top: 100upx" @click="senBleLabel()">标签打印</button>  
  </view>  
</template>  

js


<script>  
import tsc from "@/static/libs/tsc.js";  
import bluetoothTool from "@/static/libs/BluetoothTool.js";  

export default {  
  data() {  
    return {  
      devices: [],  
      currDev: null,  
      connId: "",  
      piaojuText: "",  

      tableDomId: "",  
      tableImgPath: "",  

      canvasWidth: 80,  
      canvasHeight: 60,  

      msg: "",  
      count: 0,  
    };  
  },  
  watch: {  
    msg() {  
      uni.showToast({  
        title: this.msg,  
      });  
    },  
  },  
  onReady() {  
    this.renderCanvas();  
  },  
  mounted() {  
    //#ifdef APP-PLUS  
    // 蓝牙  
    bluetoothTool.init({  
      listenBTStatusCallback: (state) => {  
        if (state == "STATE_ON") {  
          let lastBleAddress = uni.getStorageSync("lastBleAddress");  
          if (lastBleAddress) {  
            uni.showLoading({  
              title: "正在连接...",  
            });  
            console.log(lastBleAddress);  
            bluetoothTool.connDevice(lastBleAddress, (result) => {  
              uni.hideLoading();  
              uni.showToast({  
                title: result ? "连接成功!" : "连接失败...",  
              });  
              let _this = this;  

              let countSet = setInterval(() => {  
                if (_this.count == 5) {  
                  clearInterval(countSet);  
                } else {  
                  _this.count  ;  
                  _this.senBleLabel();  
                }  
              }, 2000);  
            });  
          }  
        }  
      },  
      discoveryDeviceCallback: this.onDevice,  
      discoveryFinishedCallback: function () {  
        that.msg = "搜索完成";  
      },  
      readDataCallback: function (dataByteArr) {  
        // 读取蓝牙返回的数据  
        /* if(that.receiveDataArr.length >= 200) {  
                            that.receiveDataArr = [];  
                        }  
                        that.receiveDataArr.push.apply(that.receiveDataArr, dataByteArr); */  
      },  
      connExceptionCallback: function (e) {  
        console.log(e);  
        that.msg = "设备连接失败";  
      },  
    });  
    //#endif  
  },  
  methods: {  
    destroyed: function () {  
      console.log("destroyed----------");  
      if (this.connId != "") {  
        uni.closeBLEConnection({  
          deviceId: this.connId,  
          success(res) {  
            console.log(res);  
          },  
        });  
      }  
    },  
    searchBle() {  
      var that = this;  
      console.log("initBule");  
      // 使用openBluetoothAdapter 接口,免去主动申请权限的麻烦  
      uni.openBluetoothAdapter({  
        success(res) {  
          this.devices = [];  
          console.log("打开 蓝牙模块,开始搜索模式...");  
          console.log(res);  
          bluetoothTool.discoveryNewDevice();  
          //that.onDevice()  
        },  
      });  
    },  
    onDevice(newDevice) {  
      console.log("监听寻找到新设备的事件---------------");  
      console.log(newDevice);  
      if (newDevice.name && newDevice.name != "null") {  
        this.devices.push({  
          name: newDevice.name,  
          address: newDevice.address,  
        });  
      }  
    },  
 stopFindBule() {  
      console.log("停止搜寻附近的蓝牙外围设备---------------");  
      uni.stopBluetoothDevicesDiscovery({  
        success(res) {  
          console.log(res);  
        },  
      });  
    },  
    onConn(item) {  
      console.log("连接蓝牙---------------" + item.address);  

      if (this.selectDevices.includes(item.address)) {  
        that.msg = "该蓝牙已连接";  
      }  
      bluetoothTool.connDevice(item.address, (result) => {  
        if (result) {  
          if (this.selectDevices.length == 3) {  
            this.selectDevices.shift();  
          }  
          this.selectDevices.push(item);  
          uni.setStorageSync("selectDevices", this.selectDevices);  
        }  
        console.log("连接结果:", result);  
      });  
    },  
    senBleLabel() {  
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 200, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      command.setMag(2, 2);  
      command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      command.setMag(2, 2);  
      command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPagePrint();  
      let data = command.getData();  
      bluetoothTool.sendByteData(data);  
    },  
  },  
};  
</script>
继续阅读 »

vue

<template>  
  <view>  
    <button @click="searchBle">搜索蓝牙</button>  
    <view style="margin-top: 30upx" :key="index" v-for="(item, index) in devices">  
      <button style="width: 400upx; color: #0081ff" @click="onConn(item)">  
        {{ item.name }}  
      </button>  
    </view>  
    <button style="margin-top: 100upx" @click="senBleLabel()">标签打印</button>  
  </view>  
</template>  

js


<script>  
import tsc from "@/static/libs/tsc.js";  
import bluetoothTool from "@/static/libs/BluetoothTool.js";  

export default {  
  data() {  
    return {  
      devices: [],  
      currDev: null,  
      connId: "",  
      piaojuText: "",  

      tableDomId: "",  
      tableImgPath: "",  

      canvasWidth: 80,  
      canvasHeight: 60,  

      msg: "",  
      count: 0,  
    };  
  },  
  watch: {  
    msg() {  
      uni.showToast({  
        title: this.msg,  
      });  
    },  
  },  
  onReady() {  
    this.renderCanvas();  
  },  
  mounted() {  
    //#ifdef APP-PLUS  
    // 蓝牙  
    bluetoothTool.init({  
      listenBTStatusCallback: (state) => {  
        if (state == "STATE_ON") {  
          let lastBleAddress = uni.getStorageSync("lastBleAddress");  
          if (lastBleAddress) {  
            uni.showLoading({  
              title: "正在连接...",  
            });  
            console.log(lastBleAddress);  
            bluetoothTool.connDevice(lastBleAddress, (result) => {  
              uni.hideLoading();  
              uni.showToast({  
                title: result ? "连接成功!" : "连接失败...",  
              });  
              let _this = this;  

              let countSet = setInterval(() => {  
                if (_this.count == 5) {  
                  clearInterval(countSet);  
                } else {  
                  _this.count  ;  
                  _this.senBleLabel();  
                }  
              }, 2000);  
            });  
          }  
        }  
      },  
      discoveryDeviceCallback: this.onDevice,  
      discoveryFinishedCallback: function () {  
        that.msg = "搜索完成";  
      },  
      readDataCallback: function (dataByteArr) {  
        // 读取蓝牙返回的数据  
        /* if(that.receiveDataArr.length >= 200) {  
                            that.receiveDataArr = [];  
                        }  
                        that.receiveDataArr.push.apply(that.receiveDataArr, dataByteArr); */  
      },  
      connExceptionCallback: function (e) {  
        console.log(e);  
        that.msg = "设备连接失败";  
      },  
    });  
    //#endif  
  },  
  methods: {  
    destroyed: function () {  
      console.log("destroyed----------");  
      if (this.connId != "") {  
        uni.closeBLEConnection({  
          deviceId: this.connId,  
          success(res) {  
            console.log(res);  
          },  
        });  
      }  
    },  
    searchBle() {  
      var that = this;  
      console.log("initBule");  
      // 使用openBluetoothAdapter 接口,免去主动申请权限的麻烦  
      uni.openBluetoothAdapter({  
        success(res) {  
          this.devices = [];  
          console.log("打开 蓝牙模块,开始搜索模式...");  
          console.log(res);  
          bluetoothTool.discoveryNewDevice();  
          //that.onDevice()  
        },  
      });  
    },  
    onDevice(newDevice) {  
      console.log("监听寻找到新设备的事件---------------");  
      console.log(newDevice);  
      if (newDevice.name && newDevice.name != "null") {  
        this.devices.push({  
          name: newDevice.name,  
          address: newDevice.address,  
        });  
      }  
    },  
 stopFindBule() {  
      console.log("停止搜寻附近的蓝牙外围设备---------------");  
      uni.stopBluetoothDevicesDiscovery({  
        success(res) {  
          console.log(res);  
        },  
      });  
    },  
    onConn(item) {  
      console.log("连接蓝牙---------------" + item.address);  

      if (this.selectDevices.includes(item.address)) {  
        that.msg = "该蓝牙已连接";  
      }  
      bluetoothTool.connDevice(item.address, (result) => {  
        if (result) {  
          if (this.selectDevices.length == 3) {  
            this.selectDevices.shift();  
          }  
          this.selectDevices.push(item);  
          uni.setStorageSync("selectDevices", this.selectDevices);  
        }  
        console.log("连接结果:", result);  
      });  
    },  
    senBleLabel() {  
      var command = tsc.jpPrinter.createNew();  
      command.init(0, 200, 200, 210, 1);  
      command.setCls();  
      command.setQR(30, 40, 2, 6, "123");  
      command.setMag(2, 2);  
      command.setText1(55, 30, 180, 60, "地址: 内蒙");  
      command.setMag(2, 2);  
      command.setText1(55, 6, 180, 120, "重量: 15kg");  
      command.setPagePrint();  
      let data = command.getData();  
      bluetoothTool.sendByteData(data);  
    },  
  },  
};  
</script>
收起阅读 »

请问使用5+app中的plus.android.importClass('android.media.AudioRecord');引入对象后,调用对象的 read 方法一直返回null是怎么回事呢?

5+App开发 Native.JS html5plus

请问使用5+app中的plus.android.importClass('android.media.AudioRecord');引入对象后,调用对象的 read() 方法一直返回null是怎么回事呢?
在调用对象的 read() 方法之前已经实例化AudioRecord,并调用了 startRecording() 方法,请各位大佬赐教

继续阅读 »

请问使用5+app中的plus.android.importClass('android.media.AudioRecord');引入对象后,调用对象的 read() 方法一直返回null是怎么回事呢?
在调用对象的 read() 方法之前已经实例化AudioRecord,并调用了 startRecording() 方法,请各位大佬赐教

收起阅读 »

关于Android 部分手机NotificationManagerCompat.from 返回null 解决办法

NJS

在做一个检查应用是否拥有通知权限功能的时候发现部分手机(Redmi Note 5A 【Android 7.1.2】)调用NotificationManagerCompat.from(context) 会返回null
查阅了Android Dev 文档,官方描述NotificationManagerCompat.from 的返回值是 NonNull的 理应不会返回null

尝试修复方式如下,我自己去看了NotificationManagerCompat.from + NotificationManagerCompat.areNotificationsEnabled源代码手撸的;
相当于给NotificationManagerCompat.from 添加了个Polyfill;

const activity = plus.android.runtimeMainActivity();  
const NotificationManagerCompat = plus.android.importClass('androidx.core.app.NotificationManagerCompat');  
const manager = NotificationManagerCompat.from(activity) || {  
    /** 手动实现 NotificationManagerCompat,因为部分手机NotificationManagerCompat.from会返回null */  
    areNotificationsEnabled() {  
        const Build = plus.android.importClass('android.os.Build');  

        if (Build.VERSION.SDK_INT >= 24) {  
            plus.android.importClass('android.app.NotificationManager');  
            const notificationManager = activity.getSystemService(activity.NOTIFICATION_SERVICE);  
            const areNotificationsEnabled = notificationManager.areNotificationsEnabled();  

            plus.android.autoCollection(notificationManager);  

            return areNotificationsEnabled;  
        } else if (Build.VERSION.SDK_INT >= 19) {  
            const AppOpsManager = plus.android.importClass('android.app.AppOpsManager');  
            const ApplicationInfo = plus.android.importClass('android.content.pm.ApplicationInfo');  

            const appOps = activity.getSystemService(activity.APP_OPS_SERVICE);  
            const appInfo = activity.getApplicationInfo();  

            try {  
                const isEnabled = appOps.checkOpNoThrow(  
                    AppOpsManager.OP_POST_NOTIFICATION,  
                    plus.android.getAttribute(appInfo, 'uid'), //直接appInfo.uid 返回的是undefined  
                    activity.getApplicationContext().getPackageName()  
                ) === AppOpsManager.MODE_ALLOWED;  

                plus.android.autoCollection(appOps);  
                plus.android.autoCollection(appInfo);  
                return isEnabled;  
            } catch (e) {  
                return true;  
            }  
        }  

        return true;  
    }  
};  

console.log(manager.areNotificationsEnabled())
继续阅读 »

在做一个检查应用是否拥有通知权限功能的时候发现部分手机(Redmi Note 5A 【Android 7.1.2】)调用NotificationManagerCompat.from(context) 会返回null
查阅了Android Dev 文档,官方描述NotificationManagerCompat.from 的返回值是 NonNull的 理应不会返回null

尝试修复方式如下,我自己去看了NotificationManagerCompat.from + NotificationManagerCompat.areNotificationsEnabled源代码手撸的;
相当于给NotificationManagerCompat.from 添加了个Polyfill;

const activity = plus.android.runtimeMainActivity();  
const NotificationManagerCompat = plus.android.importClass('androidx.core.app.NotificationManagerCompat');  
const manager = NotificationManagerCompat.from(activity) || {  
    /** 手动实现 NotificationManagerCompat,因为部分手机NotificationManagerCompat.from会返回null */  
    areNotificationsEnabled() {  
        const Build = plus.android.importClass('android.os.Build');  

        if (Build.VERSION.SDK_INT >= 24) {  
            plus.android.importClass('android.app.NotificationManager');  
            const notificationManager = activity.getSystemService(activity.NOTIFICATION_SERVICE);  
            const areNotificationsEnabled = notificationManager.areNotificationsEnabled();  

            plus.android.autoCollection(notificationManager);  

            return areNotificationsEnabled;  
        } else if (Build.VERSION.SDK_INT >= 19) {  
            const AppOpsManager = plus.android.importClass('android.app.AppOpsManager');  
            const ApplicationInfo = plus.android.importClass('android.content.pm.ApplicationInfo');  

            const appOps = activity.getSystemService(activity.APP_OPS_SERVICE);  
            const appInfo = activity.getApplicationInfo();  

            try {  
                const isEnabled = appOps.checkOpNoThrow(  
                    AppOpsManager.OP_POST_NOTIFICATION,  
                    plus.android.getAttribute(appInfo, 'uid'), //直接appInfo.uid 返回的是undefined  
                    activity.getApplicationContext().getPackageName()  
                ) === AppOpsManager.MODE_ALLOWED;  

                plus.android.autoCollection(appOps);  
                plus.android.autoCollection(appInfo);  
                return isEnabled;  
            } catch (e) {  
                return true;  
            }  
        }  

        return true;  
    }  
};  

console.log(manager.areNotificationsEnabled())
收起阅读 »

uniapp 官方公布的plug 不支持 流文件写入,给你们来一个简单的

文件

uniapp 流文件的写入

fileEntry.createWriter(function(write){
writer.seek(0);
//此处的base64不含 文件的头信息,不能有\r\n. 相当于不能通过 readAsBase64来获取,或者自行替换。
writer.writeAsBinary(base64Str);
writer.abort();
})

没有测试 苹果的,我看的是安卓的,按理说,官方应该同时支持的。
官方还有没公布的,可能有用的 “readAsBase64”,不过跟readAsDataURL差不多,只是 readAsBase64出来的没有文件头,且有\r\n。

继续阅读 »

uniapp 流文件的写入

fileEntry.createWriter(function(write){
writer.seek(0);
//此处的base64不含 文件的头信息,不能有\r\n. 相当于不能通过 readAsBase64来获取,或者自行替换。
writer.writeAsBinary(base64Str);
writer.abort();
})

没有测试 苹果的,我看的是安卓的,按理说,官方应该同时支持的。
官方还有没公布的,可能有用的 “readAsBase64”,不过跟readAsDataURL差不多,只是 readAsBase64出来的没有文件头,且有\r\n。

收起阅读 »

iOS 本地消息推送通知

消息推送 iOS

效果如图

参考 iOS 最新的 UNNotificationRequest API

function notifyWithInterval(interval) {  

    //content https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent?language=objc  
    const content = plus.ios.newObject("UNMutableNotificationContent")  
    const Sound = plus.ios.importClass('UNNotificationSound')  
    content.plusSetAttribute("title", 'title');  
    content.plusSetAttribute("subtitle", 'subtitle');  
    content.plusSetAttribute("body", 'body_' + interval);  
    content.plusSetAttribute('sound', Sound.defaultSound());  

    //trigger https://developer.apple.com/documentation/usernotifications/unnotificationtrigger?language=objc  
    const Trigger = plus.ios.importClass("UNTimeIntervalNotificationTrigger")  
    const trigger = Trigger.triggerWithTimeIntervalrepeats(interval, false)  

    const UUID = plus.ios.newObject('NSUUID')  
    const uuid = UUID.plusGetAttribute('UUIDString')  
    // const uuid = plus.tools.UUID('TIMER');  

    //request  
    const Req = plus.ios.importClass('UNNotificationRequest')  
    const req = Req.requestWithIdentifiercontenttrigger(uuid, content, trigger)  

    const NotiCenter = plus.ios.importClass("UNUserNotificationCenter")  
    const userNotiCenter = NotiCenter.currentNotificationCenter()  

    userNotiCenter.addNotificationRequest(req)  
}

调用如下:

export default {  
    ......  
    onLaunch: function() {  
        ......  
        // 5 秒后推送本地提醒  
        notifyWithInterval(5)  
    }  
    ......  
}

其实不复杂,只是参考资料太少了,花两百买了一段代码,结果还是iOS废弃的api,自己看 iOS的文档重写了一个。
这里只写了一个 triggerWithTimeIntervalrepeats 的例子,其他的可参考 unnotificationtrigger

比较遗憾的是 delegate功能一直没调通,也就是自定义收到消息的后续操作,完全按 iOS 的文档实现 UNUserNotificationCenterDelegate
怎么都不行,有实现了的可以交流下,不打算弄原生插件,打算弃坑了……

继续阅读 »

效果如图

参考 iOS 最新的 UNNotificationRequest API

function notifyWithInterval(interval) {  

    //content https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent?language=objc  
    const content = plus.ios.newObject("UNMutableNotificationContent")  
    const Sound = plus.ios.importClass('UNNotificationSound')  
    content.plusSetAttribute("title", 'title');  
    content.plusSetAttribute("subtitle", 'subtitle');  
    content.plusSetAttribute("body", 'body_' + interval);  
    content.plusSetAttribute('sound', Sound.defaultSound());  

    //trigger https://developer.apple.com/documentation/usernotifications/unnotificationtrigger?language=objc  
    const Trigger = plus.ios.importClass("UNTimeIntervalNotificationTrigger")  
    const trigger = Trigger.triggerWithTimeIntervalrepeats(interval, false)  

    const UUID = plus.ios.newObject('NSUUID')  
    const uuid = UUID.plusGetAttribute('UUIDString')  
    // const uuid = plus.tools.UUID('TIMER');  

    //request  
    const Req = plus.ios.importClass('UNNotificationRequest')  
    const req = Req.requestWithIdentifiercontenttrigger(uuid, content, trigger)  

    const NotiCenter = plus.ios.importClass("UNUserNotificationCenter")  
    const userNotiCenter = NotiCenter.currentNotificationCenter()  

    userNotiCenter.addNotificationRequest(req)  
}

调用如下:

export default {  
    ......  
    onLaunch: function() {  
        ......  
        // 5 秒后推送本地提醒  
        notifyWithInterval(5)  
    }  
    ......  
}

其实不复杂,只是参考资料太少了,花两百买了一段代码,结果还是iOS废弃的api,自己看 iOS的文档重写了一个。
这里只写了一个 triggerWithTimeIntervalrepeats 的例子,其他的可参考 unnotificationtrigger

比较遗憾的是 delegate功能一直没调通,也就是自定义收到消息的后续操作,完全按 iOS 的文档实现 UNUserNotificationCenterDelegate
怎么都不行,有实现了的可以交流下,不打算弄原生插件,打算弃坑了……

收起阅读 »

uniapp实现安卓禁止截屏和允许截屏

NJS Native.JS
let flag = 0  
let WindowManager = null  
let mainActivity = null  
let window_android = null  
document.addEventListener('plusready', function(){  
    WindowManager = plus.android.importClass('android.view.WindowManager')  
    plus.android.importClass("android.view.Window");      
    mainActivity = plus.android.runtimeMainActivity();      
    window_android = mainActivity.getWindow();  
    flag = WindowManager.LayoutParams.FLAG_SECURE  
});  
function allowJp(){  
    // 允许截屏  
    window_android.clearFlags(flag);      
}  
function forbidJp(){  
    // 禁止截屏  
    window_android.addFlags(flag);  
}

直接调用上面的方法即可实现禁止和允许截屏
Tips: 在vue文件里面写不用监听plusready,可以直接把function里面的代码拿出来

继续阅读 »
let flag = 0  
let WindowManager = null  
let mainActivity = null  
let window_android = null  
document.addEventListener('plusready', function(){  
    WindowManager = plus.android.importClass('android.view.WindowManager')  
    plus.android.importClass("android.view.Window");      
    mainActivity = plus.android.runtimeMainActivity();      
    window_android = mainActivity.getWindow();  
    flag = WindowManager.LayoutParams.FLAG_SECURE  
});  
function allowJp(){  
    // 允许截屏  
    window_android.clearFlags(flag);      
}  
function forbidJp(){  
    // 禁止截屏  
    window_android.addFlags(flag);  
}

直接调用上面的方法即可实现禁止和允许截屏
Tips: 在vue文件里面写不用监听plusready,可以直接把function里面的代码拿出来

收起阅读 »