Commit 5ab86d29 authored by 王雷's avatar 王雷

修改搜索蓝牙导致的内容泄漏

parent 351890d4
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<application <application
android:requestLegacyExternalStorage="true"
android:name=".App" android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
......
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -22,7 +22,6 @@ var hockeyTeam = { ...@@ -22,7 +22,6 @@ var hockeyTeam = {
}, },
}; };
console.log("111",hockeyTeam.getPrintData());
function print1(){ function print1(){
var arrays2 = var arrays2 =
[27, 64, 10, 27, 51, 20, 27, 97, 1, 29, 33, 17, 27, 69, 0, 83, 97, 109, 112, 108, [27, 64, 10, 27, 51, 20, 27, 97, 1, 29, 33, 17, 27, 69, 0, 83, 97, 109, 112, 108,
......
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.tools = factory());
}(this, (function () { 'use strict';
var tools = {
// 文字大小
fontSize(size) {
var array = []
switch(size) {
case 'normal':
array = [29, 33, 0]
break
case 'doubleHeight':
array = [29, 33, 1]
break
case 'doubleWidth':
array = [29, 33, 16]
break
case 'double':
array = [29, 33, 17]
break
}
return array
},
// 文字加粗
fontBold() {
return [27, 69, 1]
},
// 文字对齐方式
fontAlign(align) {
var array = []
switch(align) {
case 'left':
array = [27, 97, 48]
break
case 'center':
array = [27, 97, 49]
break
case 'right':
array = [27, 97, 50]
break
}
return array
},
normalizeStyle(styleString) {
let styleArray = styleString.split(';')
let styleObject = {}
styleArray.forEach(item => {
if (item) {
var styleItem = item.split(':')
styleObject[styleItem[0]] = styleItem[1]
}
})
return styleObject
}
}
return tools
})))
\ No newline at end of file
...@@ -71,7 +71,7 @@ class BtListActivity : AppCompatActivity(), View.OnClickListener { ...@@ -71,7 +71,7 @@ class BtListActivity : AppCompatActivity(), View.OnClickListener {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bt_list) setContentView(R.layout.activity_bt_list)
Log.d(TAG, "onCreate: model= ${Build.MODEL} brand = ${Build.BRAND} ") Log.d(TAG, "onCreate: model= ${Build.MODEL} brand = ${Build.BRAND} ")
PrintManagerUtils.getInstance().getSearchBlueToothList(object : BlueToothSearchCallBack { PrintManagerUtils.getInstance().getSearchBlueToothList(this,object : BlueToothSearchCallBack {
override fun onRefuseGrantPermission() { override fun onRefuseGrantPermission() {
} }
......
...@@ -6,14 +6,18 @@ import android.hardware.usb.UsbDevice ...@@ -6,14 +6,18 @@ import android.hardware.usb.UsbDevice
import android.os.Build import android.os.Build
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import com.dianping.logan.Logan
import com.eclipsesource.v8.JavaVoidCallback import com.eclipsesource.v8.JavaVoidCallback
import com.eclipsesource.v8.V8 import com.eclipsesource.v8.V8
import com.eclipsesource.v8.V8Array import com.eclipsesource.v8.V8Array
import com.eclipsesource.v8.V8Object import com.eclipsesource.v8.V8Object
import com.permissionx.guolindev.PermissionX import com.permissionx.guolindev.PermissionX
import com.qimai.android.widget.R import com.qimai.android.widget.R
import com.qimai.log.LoganParser
import com.qimai.log.QmLog
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main_printer.* import kotlinx.android.synthetic.main.activity_main_printer.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
...@@ -27,14 +31,11 @@ import zs.qimai.com.printer2.manager.DeviceManager.Companion.USB ...@@ -27,14 +31,11 @@ import zs.qimai.com.printer2.manager.DeviceManager.Companion.USB
import zs.qimai.com.printer2.manager.DeviceManagerUtils import zs.qimai.com.printer2.manager.DeviceManagerUtils
import zs.qimai.com.printer2.manager.UsbDeviceManager import zs.qimai.com.printer2.manager.UsbDeviceManager
import zs.qimai.com.printer2.utils.PrintManagerUtils import zs.qimai.com.printer2.utils.PrintManagerUtils
import java.io.BufferedReader import java.io.*
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVoidCallback { class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack, JavaVoidCallback {
private var list = ArrayList<DeviceManager>() private var list = ArrayList<DeviceManager>()
...@@ -52,6 +53,12 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -52,6 +53,12 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_printer) setContentView(R.layout.activity_main_printer)
GlobalScope.launch(Dispatchers.IO){
for (i in 0..1000000) {
QmLog.w("network", "test network")
}
}
DeviceManagerUtils.getInstance().addConnectStatusCallBack(this) DeviceManagerUtils.getInstance().addConnectStatusCallBack(this)
initUsbPrinter() initUsbPrinter()
val value = Utils.getSN() val value = Utils.getSN()
...@@ -60,27 +67,84 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -60,27 +67,84 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
startActivity(Intent(this, BtListActivity::class.java)) startActivity(Intent(this, BtListActivity::class.java))
} }
tv_print.setOnClickListener { tv_print.setOnClickListener {
val file =
File("${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/test.js")
val bos = ByteArrayOutputStream()
val b = ByteArray(1024)
val `is`: InputStream = FileInputStream(file)
var len: Int
while (`is`!!.read(b).also { len = it } != -1) {
bos.write(b, 0, len)
}
val json = bos.toString()
Log.d(TAG, "onCreate: json= ${json}")
Logan.w("test logan", 2)
val value = "企迈测试".toByteArray(charset("gbk")) val value = "企迈测试".toByteArray(charset("gbk"))
Log.d(TAG, "onCreate value: value= ${Arrays.toString(value)}") Log.d(TAG, "onCreate value: value= ${Arrays.toString(value)}")
val v8 = V8.createV8Runtime() val v8 = V8.createV8Runtime()
// v8.registerJavaMethod(this,"print","print",arrayOf(V8Array::class.java))
// v8.executeJSFunction("print") // v8.executeJSFunction("print")
// val v8Array = v8.executeArrayScript("print1") as V8Array // val v8Array = v8.executeArrayScript("print1") as V8Array
// val v8Array = v8.executeScript(readFile()) as V8Array // val v8Array = v8.executeScript(readFile()) as V8Array
// val byteArray = v8Array.getBytes(0,v8Array.length()) // val byteArray = v8Array.getBytes(0,v8Array.length())
//Log.d(TAG, "onCreate: byteArray = ${Arrays.toString(byteArray)}") //Log.d(TAG, "onCreate: byteArray = ${Arrays.toString(byteArray)}")
v8.executeVoidScript(readFile())
var object1 = v8.getObject("hockeyTeam") v8.executeScript(readFile("htmlparser2.js"))
val array = object1.executeJSFunction("getPrintData") as V8Array v8.executeScript(readFile("art-template.js"))
// print(array) v8.executeScript(readFile("encoding-indexes.js"))
Log.d(TAG, "onCreate: array= ${array}") v8.executeScript(readFile("encoding.js"))
v8.executeScript(readFile("tools.js"))
v8.executeScript(json)
val android = Console()
val v8Object = V8Object(v8)
v8.add("android",v8Object)
v8Object.registerJavaMethod(android,"printString","printString",arrayOf(String::class.java))
v8Object.registerJavaMethod(android,"print12","print12",arrayOf(V8Array::class.java))
v8.executeJSFunction("print1")
//val v8Array =
// v8.executeJSFunction("print1")
/*as V8Array
val byteArray = v8Array.getBytes(0,v8Array.length())
val task = object : PrintExecutor() {
override fun covertEscData(): ByteArray? {
return TestPrintTemplate().getPrintData("122")
}
override fun convertTscData(): ByteArray? {
return LabelTemplete().getPrintData("Test")
}
}
task.mPrintCallBack = object : PrintCallBack {
override fun printSuccess(deviceManager: DeviceManager) {
Log.d(TAG, "printSuccess: deviceManager = $deviceManager")
}
override fun printFailed(msg: String?) {
Log.d(TAG, "printFailed: msg= $msg")
}
}
//task.execute()
task.goToPrint(DeviceManagerUtils.getInstance().lists[0], byteArray)*/
} }
tv_connect_usb.setOnClickListener { tv_connect_usb.setOnClickListener {
startActivity(Intent(this, UsbActivity::class.java)) startActivity(Intent(this, UsbActivity::class.java))
} }
tv_disconnect_bt.setOnClickListener { tv_disconnect_bt.setOnClickListener {
val dir = File(getExternalFilesDir(null)?.absolutePath+"/logan_v1")
val file = Logan.getAllFilesInfo()
val files: Array<File> = dir.listFiles()
val uncompressBytesArray = ByteArrayOutputStream()
val loganParser =
LoganParser("0123456789012345".toByteArray(), "0123456789012345".toByteArray())
loganParser.parse(FileInputStream(files[0]),uncompressBytesArray)
val result = String(uncompressBytesArray.toByteArray())
Log.d(TAG, "onCreate: result = $result")
list.forEach { list.forEach {
if (it.mType == BT) { if (it.mType == BT) {
PrintManagerUtils.getInstance().closeBtConn(it.address!!) PrintManagerUtils.getInstance().closeBtConn(it.address!!)
...@@ -207,11 +271,11 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -207,11 +271,11 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
} }
fun readFile(): String { fun readFile(fileNme:String): String {
var result = "没有" var result = "没有"
var in1: InputStream? = null var in1: InputStream? = null
try { try {
in1 = getAssets().open("test.js"); in1 = getAssets().open(fileNme)
} catch (e: IOException) { } catch (e: IOException) {
e.printStackTrace() e.printStackTrace()
} }
...@@ -219,7 +283,7 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -219,7 +283,7 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
val sb = StringBuilder() val sb = StringBuilder()
var line: String? = null var line: String? = null
while ((reader.readLine().also { line = it }) != null) { while ((reader.readLine().also { line = it }) != null) {
sb.append(line) sb.append(line).append("\n")
} }
return sb.toString() return sb.toString()
...@@ -229,8 +293,10 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -229,8 +293,10 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
override fun invoke(p0: V8Object?, p1: V8Array?) { override fun invoke(p0: V8Object?, p1: V8Array?) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
fun print(value:V8Array){
val value1 = value.getBytes(0,value.length())
fun print12(value: V8Array) {
val value1 = value.getBytes(0, value.length())
Log.d(TAG, "print: value1= ${Arrays.toString(value1)}") Log.d(TAG, "print: value1= ${Arrays.toString(value1)}")
val task = object : PrintExecutor() { val task = object : PrintExecutor() {
override fun covertEscData(): ByteArray? { override fun covertEscData(): ByteArray? {
...@@ -253,7 +319,7 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -253,7 +319,7 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
//task.execute() //task.execute()
task.goToPrint(DeviceManagerUtils.getInstance().lists[0], value1) task.goToPrint(DeviceManagerUtils.getInstance().lists[0], value1)
value1.forEach{ value1.forEach {
Log.d(TAG, "test123: 111 value= ${it}") Log.d(TAG, "test123: 111 value= ${it}")
} }
...@@ -262,4 +328,49 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo ...@@ -262,4 +328,49 @@ class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack , JavaVo
Log.d(TAG, "print: it= $it") Log.d(TAG, "print: it= $it")
} }
} }
class Console{
fun printString(text:String){
Log.d("TAG", "printString: text= ${text}")
}
fun print12(value:V8Array){
val value1 = value.getBytes(0, value.length())
Log.d("TAG", "print: value1= ${Arrays.toString(value1)}")
val task = object : PrintExecutor() {
override fun covertEscData(): ByteArray? {
return TestPrintTemplate().getPrintData("122")
}
override fun convertTscData(): ByteArray? {
return LabelTemplete().getPrintData("Test")
}
}
task.mPrintCallBack = object : PrintCallBack {
override fun printSuccess(deviceManager: DeviceManager) {
Log.d("TAG", "printSuccess: deviceManager = $deviceManager")
}
override fun printFailed(msg: String?) {
Log.d("TAG", "printFailed: msg= $msg")
}
}
//task.execute()
task.goToPrint(DeviceManagerUtils.getInstance().lists[0], value1)
value1.forEach {
Log.d("TAG", "test123: 111 value= ${it}")
}
"hello world".toByteArray().forEach {
Log.d("TAG", "print: it= $it")
}
}
}
} }
...@@ -67,6 +67,7 @@ dependencies { ...@@ -67,6 +67,7 @@ dependencies {
api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
api "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" api "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
compile 'com.dianping.android.sdk:logan:1.2.4'
} }
group 'com.qmai.android.log' group 'com.qmai.android.log'
......
...@@ -6,13 +6,15 @@ import android.content.Context ...@@ -6,13 +6,15 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import com.dianping.logan.Logan
import com.dianping.logan.LoganConfig
import com.qimai.log.service.ScheduledExecutionService import com.qimai.log.service.ScheduledExecutionService
import com.tencent.mars.xlog.Log import com.tencent.mars.xlog.Log
import com.tencent.mars.xlog.Xlog import com.tencent.mars.xlog.Xlog
import java.io.File
class LogInit private constructor() { class LogInit private constructor() {
private lateinit var mLogConfig: QmLogConfig private lateinit var mLogConfig: QmLogConfig
@JvmOverloads @JvmOverloads
fun init(application: Context) { fun init(application: Context) {
init(QmLogConfig(application)) init(QmLogConfig(application))
...@@ -54,7 +56,24 @@ class LogInit private constructor() { ...@@ -54,7 +56,24 @@ class LogInit private constructor() {
// val intent = Intent(getConfig().app, ScheduledExecutionService::class.java) // val intent = Intent(getConfig().app, ScheduledExecutionService::class.java)
// getConfig().app.startService(intent) // getConfig().app.startService(intent)
//初始化
val config = LoganConfig.Builder()
.setCachePath(mLogConfig.app.filesDir.absolutePath)
.setPath(mLogConfig.app.getExternalFilesDir(null)?.absolutePath
+ File.separator + "logan_v1")
.setEncryptKey16("0123456789012345".toByteArray())
.setEncryptIV16("0123456789012345".toByteArray())
.build()
Logan.init(config)
//开启debug模式
Logan.setDebug(true)
//记录日志
Logan.w("test logan", 1)
//将日志从缓存冲刷到物理文件上
//如果未调用该方法程序就崩溃了,框架会将缓存中的内容冲刷到物理文件上
Logan.f()
//获取日志信息,key为日期,value为日志大小
//日志以时间进行分隔存储
} }
......
package com.qimai.log;/*
* Copyright (c) 2018-present, 美团点评
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
public class LoganParser {
private static final String ALGORITHM = "AES";
private static final String ALGORITHM_TYPE = "AES/CBC/NoPadding";
private Cipher mDecryptCipher;
private byte[] mEncryptKey16; //128位ase加密Key
private byte[] mEncryptIv16; //128位aes加密IV
public LoganParser(byte[] encryptKey16, byte[] encryptIv16) {
mEncryptKey16 = encryptKey16;
mEncryptIv16 = encryptIv16;
initEncrypt();
}
private void initEncrypt() {
SecretKeySpec secretKeySpec = new SecretKeySpec(mEncryptKey16, ALGORITHM);
try {
mDecryptCipher = Cipher.getInstance(ALGORITHM_TYPE);
mDecryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(mEncryptIv16));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
}
public void parse(InputStream is, OutputStream os) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int t = 0;
try {
while ((t = is.read(buffer)) >= 0) {
bos.write(buffer, 0, t);
bos.flush();
}
byte[] content = bos.toByteArray();
for (int i = 0; i < content.length; i++) {
byte start = content[i];
if (start == '\1') {
i++;
int length = (content[i] & 0xFF) << 24 |
(content[i + 1] & 0xFF) << 16 |
(content[i + 2] & 0xFF) << 8 |
(content[i + 3] & 0xFF);
i += 3;
int type;
if (length > 0) {
int temp = i + length + 1;
if (content.length - i - 1 == length) { //异常
type = 0;
} else if (content.length - i - 1 > length && '\0' == content[temp]) {
type = 1;
} else if (content.length - i - 1 > length && '\1' == content[temp]) { //异常
type = 2;
} else {
i -= 4;
continue;
}
byte[] dest = new byte[length];
System.arraycopy(content, i + 1, dest, 0, length);
ByteArrayOutputStream uncompressBytesArray = new ByteArrayOutputStream();
InflaterInputStream inflaterOs = null;
byte[] uncompressByte;
try {
uncompressBytesArray.reset();
inflaterOs = new GZIPInputStream(new CipherInputStream(new ByteArrayInputStream(dest), mDecryptCipher));
int e = 0;
while ((e = inflaterOs.read(buffer)) >= 0) {
uncompressBytesArray.write(buffer, 0, e);
}
} catch (Exception e) {
e.printStackTrace();
}
uncompressByte = uncompressBytesArray.toByteArray();
uncompressBytesArray.reset();
os.write(uncompressByte);
if (inflaterOs != null)
inflaterOs.close();
i += length;
if (type == 1) {
i++;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.qimai.log package com.qimai.log
import android.content.Intent import android.content.Intent
import com.dianping.logan.Logan
import com.tencent.mars.xlog.Log import com.tencent.mars.xlog.Log
object QmLog { object QmLog {
...@@ -18,13 +19,19 @@ object QmLog { ...@@ -18,13 +19,19 @@ object QmLog {
} }
fun w(tag: String, message: String) { fun w(tag: String, message: String) {
Log.w(tag, message) // Log.w(tag, message)
Logan.w(tag + message, 2)
} }
fun i(tag: String, message: String) { fun i(tag: String, message: String) {
Log.i(tag, message) Log.i(tag, message)
} }
fun getInfo(){
}
fun flush() { fun flush() {
Log.appenderClose() Log.appenderClose()
} }
...@@ -39,11 +46,13 @@ object QmLog { ...@@ -39,11 +46,13 @@ object QmLog {
intent.putExtra("upload", config) intent.putExtra("upload", config)
getConfig().app.startService(intent) getConfig().app.startService(intent)
} }
fun uploadLog(config: UploadConfig,callBack: UploadCallBack) {
fun uploadLog(config: UploadConfig, callBack: UploadCallBack) {
//刷新下 //刷新下
Log.appenderFlush(false) Log.appenderFlush(false)
FtpUpload.upload(config,callBack) FtpUpload.upload(config, callBack)
} }
fun getConfig(): QmLogConfig { fun getConfig(): QmLogConfig {
val config: QmLogConfig? = LogInit.getInstance().getConfig() val config: QmLogConfig? = LogInit.getInstance().getConfig()
if (config == null) { if (config == null) {
......
...@@ -5,7 +5,12 @@ import android.app.Activity ...@@ -5,7 +5,12 @@ import android.app.Activity
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import com.tbruyelle.rxpermissions2.RxPermissions import com.tbruyelle.rxpermissions2.RxPermissions
import zs.qimai.com.printer2.receiverManager.RequestBlueToothListReceiverManager import zs.qimai.com.printer2.receiverManager.RequestBlueToothListReceiverManager
import zs.qimai.com.printer2.callback.BlueToothSearchCallBack import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
...@@ -13,16 +18,28 @@ import zs.qimai.com.printer2.callback.BlueToothSearchCallBack ...@@ -13,16 +18,28 @@ import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
/**** /****
* 没有界面的Fragment 管理获取定位权限,获取搜索到的蓝牙列表 * 没有界面的Fragment 管理获取定位权限,获取搜索到的蓝牙列表
* **/ * **/
class BlueToothListFragment : Fragment() { class BlueToothListFragment : Fragment(), LifecycleObserver {
private val TAG = "BlueToothListFragment" private val TAG = "BlueToothListFragment"
var activity: Activity? = null var activity: Activity? = null
private var mOuterLifecycleOwner:LifecycleOwner? = null
var callback: BlueToothSearchCallBack? = null var callback: BlueToothSearchCallBack? = null
override fun onAttach(context: Context?) { override fun onAttach(context: Context?) {
super.onAttach(context) super.onAttach(context)
activity = context as Activity? activity = context as Activity?
} }
fun getBlueToothList(callBack1: BlueToothSearchCallBack? = null) { //监听生命周期
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestory() {
}
fun getBlueToothList(
lifecycleOwner: LifecycleOwner,
callBack1: BlueToothSearchCallBack? = null
) {
mOuterLifecycleOwner = lifecycleOwner
mOuterLifecycleOwner!!.lifecycle.addObserver(this)
this.callback = callBack1 this.callback = callBack1
this.callback?.onSearchStart() this.callback?.onSearchStart()
//先检查权限 蓝牙搜索必须要这些权限 //先检查权限 蓝牙搜索必须要这些权限
...@@ -50,7 +67,12 @@ class BlueToothListFragment : Fragment() { ...@@ -50,7 +67,12 @@ class BlueToothListFragment : Fragment() {
* 获取列表 * 获取列表
* **/ * **/
private fun requestBlueList() { private fun requestBlueList() {
RequestBlueToothListReceiverManager(this).blueToothSearchCallBack = this.callback
mOuterLifecycleOwner?.apply {
RequestBlueToothListReceiverManager(this).blueToothSearchCallBack = this@BlueToothListFragment.callback
}
} }
/*** /***
...@@ -82,6 +104,7 @@ class BlueToothListFragment : Fragment() { ...@@ -82,6 +104,7 @@ class BlueToothListFragment : Fragment() {
} }
override fun onDestroy() { override fun onDestroy() {
callback = null
super.onDestroy() super.onDestroy()
activity = null activity = null
callback = null callback = null
......
...@@ -4,6 +4,7 @@ import android.util.Log ...@@ -4,6 +4,7 @@ import android.util.Log
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import zs.qimai.com.printer2.callback.BlueToothSearchCallBack import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
/*** /***
...@@ -12,16 +13,22 @@ import zs.qimai.com.printer2.callback.BlueToothSearchCallBack ...@@ -12,16 +13,22 @@ import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
class BlueToothLists { class BlueToothLists {
private val TAG = "BlueToothLists" private val TAG = "BlueToothLists"
var mBlueToothListFragment: BlueToothListFragment? = null var mBlueToothListFragment: BlueToothListFragment? = null
private var mOuterLifecycleOwner: LifecycleOwner? = null
constructor(fragmentActivity: FragmentActivity) { constructor(fragmentActivity: FragmentActivity) {
mOuterLifecycleOwner = fragmentActivity
mBlueToothListFragment = getFragment(fragmentActivity) mBlueToothListFragment = getFragment(fragmentActivity)
} }
constructor(fragment: Fragment) { constructor(fragment: Fragment) {
mOuterLifecycleOwner = fragment.viewLifecycleOwner
mBlueToothListFragment = getFragment(fragment) mBlueToothListFragment = getFragment(fragment)
} }
private fun getFragment(fragment: Fragment): BlueToothListFragment? { private fun getFragment(fragment: Fragment): BlueToothListFragment? {
mOuterLifecycleOwner = fragment.viewLifecycleOwner
return findFragment(fragment.childFragmentManager) return findFragment(fragment.childFragmentManager)
} }
...@@ -30,7 +37,7 @@ class BlueToothLists { ...@@ -30,7 +37,7 @@ class BlueToothLists {
} }
private fun findFragment(supportFragmentManager: FragmentManager?): BlueToothListFragment? { private fun findFragment(supportFragmentManager: FragmentManager?): BlueToothListFragment {
var blueToothListFragment: BlueToothListFragment? = null var blueToothListFragment: BlueToothListFragment? = null
blueToothListFragment = blueToothListFragment =
...@@ -41,7 +48,7 @@ class BlueToothLists { ...@@ -41,7 +48,7 @@ class BlueToothLists {
} }
if (!blueToothListFragment.isAdded) { if (!blueToothListFragment.isAdded) {
supportFragmentManager?.beginTransaction()?.add(blueToothListFragment, TAG) supportFragmentManager?.beginTransaction()?.add(blueToothListFragment, TAG)
?.commitNow() ?.commitNowAllowingStateLoss()
} }
return blueToothListFragment return blueToothListFragment
} }
...@@ -50,6 +57,6 @@ class BlueToothLists { ...@@ -50,6 +57,6 @@ class BlueToothLists {
* 获取搜索到的蓝牙列表 * 获取搜索到的蓝牙列表
* ***/ * ***/
fun getBlueToothList(callBack: BlueToothSearchCallBack? = null) { fun getBlueToothList(callBack: BlueToothSearchCallBack? = null) {
mBlueToothListFragment?.getBlueToothList(callBack) mOuterLifecycleOwner?.let { mBlueToothListFragment?.getBlueToothList(it,callBack) }
} }
} }
\ No newline at end of file
...@@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment ...@@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent import androidx.lifecycle.OnLifecycleEvent
import zs.qimai.com.printer2.callback.BlueToothSearchCallBack import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
...@@ -22,6 +23,7 @@ class RequestBlueToothListReceiverManager : LifecycleObserver { ...@@ -22,6 +23,7 @@ class RequestBlueToothListReceiverManager : LifecycleObserver {
var activity: FragmentActivity? = null var activity: FragmentActivity? = null
var receiver = Receiver() var receiver = Receiver()
var blueToothSearchCallBack: BlueToothSearchCallBack? = null var blueToothSearchCallBack: BlueToothSearchCallBack? = null
private var mOuterLifecycleOwner: LifecycleOwner? = null
var intentFilter = IntentFilter(BluetoothDevice.ACTION_FOUND) var intentFilter = IntentFilter(BluetoothDevice.ACTION_FOUND)
var bluetoothAdapter: BluetoothAdapter? = null var bluetoothAdapter: BluetoothAdapter? = null
...@@ -29,9 +31,9 @@ class RequestBlueToothListReceiverManager : LifecycleObserver { ...@@ -29,9 +31,9 @@ class RequestBlueToothListReceiverManager : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestory() { fun onDestory() {
Log.d(TAG, "onDestory: ") Log.d(TAG, "onDestory: ")
blueToothSearchCallBack = null
this.activity?.unregisterReceiver(receiver) this.activity?.unregisterReceiver(receiver)
this.activity = null this.activity = null
blueToothSearchCallBack = null
bluetoothAdapter?.cancelDiscovery() bluetoothAdapter?.cancelDiscovery()
bluetoothAdapter = null bluetoothAdapter = null
} }
...@@ -42,19 +44,24 @@ class RequestBlueToothListReceiverManager : LifecycleObserver { ...@@ -42,19 +44,24 @@ class RequestBlueToothListReceiverManager : LifecycleObserver {
init() init()
} }
constructor(fragment: Fragment) { constructor(outerLifecycleOwner: LifecycleOwner) {
this.activity = fragment.activity this.mOuterLifecycleOwner = outerLifecycleOwner
if (mOuterLifecycleOwner is FragmentActivity){
this.activity = mOuterLifecycleOwner as FragmentActivity
}else if (mOuterLifecycleOwner is Fragment){
this.activity = (mOuterLifecycleOwner as Fragment).requireActivity()
}
Log.d(TAG, "activity2= :$activity ") Log.d(TAG, "activity2= :$activity ")
init() init()
} }
private fun init() { private fun init() {
this.activity?.lifecycle?.addObserver(this) this.mOuterLifecycleOwner?.lifecycle?.addObserver(this)
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED) intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED) intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED) intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
this?.activity?.registerReceiver(receiver, intentFilter) this.activity?.registerReceiver(receiver, intentFilter)
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
bluetoothAdapter?.cancelDiscovery() bluetoothAdapter?.cancelDiscovery()
bluetoothAdapter?.startDiscovery() bluetoothAdapter?.startDiscovery()
...@@ -69,7 +76,10 @@ class RequestBlueToothListReceiverManager : LifecycleObserver { ...@@ -69,7 +76,10 @@ class RequestBlueToothListReceiverManager : LifecycleObserver {
intent?.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE) intent?.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
bluetoothDevice?.let { bluetoothDevice?.let {
if (!it.name.isNullOrEmpty()) { if (!it.name.isNullOrEmpty()) {
Log.d(TAG, "onReceive:bluetoothDevice.address= ${bluetoothDevice.address} name= ${bluetoothDevice.name}") Log.d(
TAG,
"onReceive:bluetoothDevice.address= ${bluetoothDevice.address} name= ${bluetoothDevice.name}"
)
if (BluetoothAdapter.checkBluetoothAddress(bluetoothDevice.address)) { if (BluetoothAdapter.checkBluetoothAddress(bluetoothDevice.address)) {
blueToothSearchCallBack?.onBlueToothFound(bluetoothDevice) blueToothSearchCallBack?.onBlueToothFound(bluetoothDevice)
} }
......
...@@ -10,6 +10,8 @@ import android.hardware.usb.UsbManager ...@@ -10,6 +10,8 @@ import android.hardware.usb.UsbManager
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import zs.qimai.com.printer2.callback.* import zs.qimai.com.printer2.callback.*
import zs.qimai.com.printer2.fragment.BlueToothLists import zs.qimai.com.printer2.fragment.BlueToothLists
import zs.qimai.com.printer2.lifecycle.ActivityManagers import zs.qimai.com.printer2.lifecycle.ActivityManagers
...@@ -48,15 +50,17 @@ class PrintManagerUtils { ...@@ -48,15 +50,17 @@ class PrintManagerUtils {
} }
} }
fun getSearchBlueToothList(callBack: BlueToothSearchCallBack? = null) { fun getSearchBlueToothList(fragmentActivity: FragmentActivity, callBack: BlueToothSearchCallBack? = null) {
checkIsInit() checkIsInit()
var topActivity = ActivityManagers.getInstance().getTopActivity() BlueToothLists(fragmentActivity).getBlueToothList(callBack)
topActivity?.let { ?: callBack?.searchFailed(ACTIVITY_NOT_FOUND, "获取不到Activity")
BlueToothLists(it).getBlueToothList(callBack)
} ?: callBack?.searchFailed(ACTIVITY_NOT_FOUND, "获取不到Activity")
} }
fun getSearchBlueToothList(fragment: Fragment, callBack: BlueToothSearchCallBack? = null) {
//蓝牙连接 checkIsInit()
BlueToothLists(fragment).getBlueToothList(callBack)
?: callBack?.searchFailed(ACTIVITY_NOT_FOUND, "获取不到Activity")
}
//蓝牙连接
@JvmOverloads @JvmOverloads
@RequiresApi(Build.VERSION_CODES.KITKAT) @RequiresApi(Build.VERSION_CODES.KITKAT)
fun btConnect( fun btConnect(
......
function print1(){
android.printString('hello orld');
var html = `<p>储值编号:{{orderNo}}</p><p>储值时间:{{createTime}}</p><p>操作人员:{{operator}}</p><hr /> <p>活动名称{{ruleName}}</p> <p><span style="text-align:left;width:50%;">支付方式:</span> <span style="text-align:right;width:50%;">{{payDesc}}</span></p> <p> <span style="text-align:left;width:50%;">储值金额:</span><span style="text-align:right;width:50%;">{{rechargeAmount}}</span></p> <p> <span style="text-align:left;font-size:24px;width:50%;">账户余额: </span><span style="text-align:right;font-size:36px;width:50%;">{{balance}} </span></p> <hr /> <p>会员:{{buyerName}}</p> <p>电话:{{mobile}}</p><br /><p style="text-align:center">扫码关注店铺公众号</p><p style="text-align:center">本次储值赠送白金卡,5张10元优惠券</p>`
// let encoding = require('./encoding')
// let TextEncoder = encoding.TextEncoder
// let template = require('./art-template')
var render = template.render(html, {
orderNo: 'SDJL1293780123',
createTime: '2020-10-09 23:23:23',
operator: '王雷',
ruleName: '限时折扣活动',
payDesc: '微信',
rechargeAmount: '¥12.22',
balance: '¥100.22',
buyerName: '小雷',
mobile: '19899999999'
});
// var htmlparser2 = require('./htmlparser2')
var byteArray = [27, 64, 10]
var uint8array = new TextEncoder('gbk', { NONSTANDARD_allowLegacyEncoding: true })
var handler = new htmlparser2.DomHandler(function(error, dom) {
dom.forEach(item => {
if (item.name) {
var children = item.children
if (children.length == 1 && children[0].type == 'text') {
// console.log(uint8array.encode('值编号:SDJL1293780123') + '')
byteArray = byteArray.concat(Array.from(uint8array.encode(children[0].data)))
}
}
})
android.print12(byteArray)
// console.log(byteArray + '')
})
var parser = new htmlparser2.Parser(handler)
// var parser = new htmlparser2.Parser({
// onopentag(name, attributes) {
// console.log(name)
// console.log(attributes)
// // html = html + '<' + name + '>'
// // if (name === 'span') {
// // name = 'p'
// // }
// },
// // ontext(text) {
// // console.log("-->", text);
// // // html = html + '{{value}}'
// // },
// // onclosetag(tagname) {
// // // if (tagname === "script") {
// // // console.log("That's it?!");
// // // }
// // // html = html + '</' + tagname + '>'
// // console.log(tagname, '结尾')
// // },
// });
parser.write(render);
parser.end();
// function transform() {
// return render
// }
// console.log(transform())
// let encoding = require('./encoding')
// let TextEncoder = encoding.TextEncoder
// console.log(TextEncoder)
var uint8array = new TextEncoder(
'gbk', { NONSTANDARD_allowLegacyEncoding: true }).encode('值编号:SDJL1293780123');
// function encodeArrayOfStrings(strings) {
// var encoder, encoded, len, i, bytes, view, offset;
// encoder = new TextEncoder();
// encoded = [];
// len = Uint16Array.BYTES_PER_ELEMENT;
// for (i = 0; i < strings.length; i += 1) {
// len += Uint16Array.BYTES_PER_ELEMENT;
// encoded[i] = new TextEncoder().encode(strings[i]);
// len += encoded[i].byteLength;
// }
// bytes = new Uint16Array(len);
// view = new DataView(bytes.buffer);
// offset = 0;
// view.setUint32(offset, strings.length);
// offset += Uint16Array.BYTES_PER_ELEMENT;
// for (i = 0; i < encoded.length; i += 1) {
// len = encoded[i].byteLength;
// view.setUint32(offset, len);
// offset += Uint16Array.BYTES_PER_ELEMENT;
// bytes.set(encoded[i], offset);
// offset += len;
// }
// return bytes;
// }
// var aa = encodeArrayOfStrings('hello world')
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment