Commit f6b3a560 authored by 王雷's avatar 王雷

修改网络请求库异常处理

parent 7820d537
...@@ -37,7 +37,7 @@ repositories { ...@@ -37,7 +37,7 @@ repositories {
} }
group 'com.qmai.android.widget' group 'com.qmai.android.widget'
version '1.1.34-SNAPSHOT' version '1.1.35-SNAPSHOT'
gradlePublish { gradlePublish {
......
...@@ -18,12 +18,13 @@ import com.qmai.android.keyboardview.R ...@@ -18,12 +18,13 @@ import com.qmai.android.keyboardview.R
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class MoneyNumberKeyBoardKeyBoard : KeyboardView { class MoneyNumberKeyBoardKeyBoard : KeyboardView {
private lateinit var editWidget: EditText private var editWidget: EditText? = null
private lateinit var mtextPaint: Paint private lateinit var mtextPaint: Paint
public var btnText = "结账" public var btnText = "结账"
private var defaultActionListener = DefaultKeyBoardActionListener() private var defaultActionListener: DefaultKeyBoardActionListener? =
DefaultKeyBoardActionListener()
enum class Code constructor(var code: Int) { enum class Code constructor(var code: Int) {
DELETE(10), CLEAR(11), SAVE(-11) DELETE(10), CLEAR(11), SAVE(-11)
...@@ -43,12 +44,12 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView { ...@@ -43,12 +44,12 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView {
} }
fun bindEditText(editText: EditText) { fun bindEditText(editText: EditText?) {
editWidget = editText editWidget = editText
defaultActionListener.et = editText defaultActionListener?.et = editText
} }
fun setKeyBoardLister(keyBoardListener: DefaultKeyBoardActionListener) { fun setKeyBoardLister(keyBoardListener: DefaultKeyBoardActionListener?) {
defaultActionListener = keyBoardListener defaultActionListener = keyBoardListener
onKeyboardActionListener = defaultActionListener onKeyboardActionListener = defaultActionListener
} }
...@@ -77,7 +78,7 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView { ...@@ -77,7 +78,7 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView {
val fontMetrics = mtextPaint.fontMetrics val fontMetrics = mtextPaint.fontMetrics
//计算基线 //计算基线
val baseLine = val baseLine =
key.y + (key.height) / 2 -(fontMetrics.bottom - fontMetrics.top) / 2 key.y + (key.height) / 2 - (fontMetrics.bottom - fontMetrics.top) / 2
//绘制文字 //绘制文字
canvas.drawText( canvas.drawText(
btnText, btnText,
...@@ -100,10 +101,10 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView { ...@@ -100,10 +101,10 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView {
canvas.save() canvas.save()
if (key.icon != null) { if (key.icon != null) {
key.icon.setBounds( key.icon.setBounds(
(key.x+key.width/2)-key.icon.intrinsicWidth/2, (key.x + key.width / 2) - key.icon.intrinsicWidth / 2,
key.y +key.height/2-key.icon.intrinsicHeight/2, key.y + key.height / 2 - key.icon.intrinsicHeight / 2,
key.x + key.width/2+key.icon.intrinsicWidth/2 , key.x + key.width / 2 + key.icon.intrinsicWidth / 2,
key.y + key.height/2+key.icon.intrinsicHeight/2 key.y + key.height / 2 + key.icon.intrinsicHeight / 2
) )
//开始绘制 //开始绘制
key.icon.draw(canvas) key.icon.draw(canvas)
...@@ -154,10 +155,10 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView { ...@@ -154,10 +155,10 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView {
editable.delete(editable.length - 1, editable.length) editable.delete(editable.length - 1, editable.length)
} }
} }
20 ->{ 20 -> {
editable.append(".") editable.append(".")
} }
21 ->{ 21 -> {
editable.append("00") editable.append("00")
} }
Code.SAVE.code -> { Code.SAVE.code -> {
...@@ -188,6 +189,7 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView { ...@@ -188,6 +189,7 @@ class MoneyNumberKeyBoardKeyBoard : KeyboardView {
mtextPaint.color = Color.parseColor("#333333") mtextPaint.color = Color.parseColor("#333333")
} }
private fun sp2px(spValue: Float): Float { private fun sp2px(spValue: Float): Float {
return TypedValue.applyDimension( return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, TypedValue.COMPLEX_UNIT_SP,
......
...@@ -8,7 +8,7 @@ android { ...@@ -8,7 +8,7 @@ android {
compileSdkVersion 29 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "com.qimai.android.widget" applicationId "com.qimai.android.widget"
minSdkVersion 19 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
...@@ -24,6 +24,8 @@ android { ...@@ -24,6 +24,8 @@ android {
packagingOptions { packagingOptions {
pickFirst 'lib/armeabi-v7a/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libmarsxlog.so' pickFirst 'lib/armeabi-v7a/libmarsxlog.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libmarsxlog.so'
} }
} }
...@@ -47,6 +49,7 @@ dependencies { ...@@ -47,6 +49,7 @@ dependencies {
implementation 'com.lxj:xpopup:2.0.6-rc1' implementation 'com.lxj:xpopup:2.0.6-rc1'
implementation 'com.google.android.material:material:1.3.0-alpha01' implementation 'com.google.android.material:material:1.3.0-alpha01'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation project(path: ':printer')
// todo test // todo test
// implementation 'com.android.tools.build:gradle:3.1.1' // implementation 'com.android.tools.build:gradle:3.1.1'
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qimai.android.widget"> package="com.qimai.android.widget">
<uses-permission android:name="android.permission.BLUETOOTH" />
<application <application
android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
...@@ -15,12 +18,18 @@ ...@@ -15,12 +18,18 @@
<activity android:name=".CommomPopActivity" /> <activity android:name=".CommomPopActivity" />
<activity android:name=".TopBarActivity" /> <activity android:name=".TopBarActivity" />
<activity android:name="com.qimai.android.widget.MainActivity"> <activity android:name="com.qimai.android.widget.MainActivity">
</activity>
<activity android:name="BtListActivity"/>
<activity android:name=".MainActivityPtinter">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".UsbActivity"/>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.qimai.android.widget
import android.app.Application
import zs.qimai.com.printer2.utils.PrintManagerUtils
class App: Application() {
override fun onCreate() {
super.onCreate()
PrintManagerUtils.getInstance().init(this)
}
}
\ No newline at end of file
package com.qimai.android.widget;
import android.annotation.SuppressLint
import android.bluetooth.BluetoothDevice
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.qimai.android.widget.R
import kotlinx.android.synthetic.main.activity_bt_list.*
import zs.qimai.com.printer2.utils.PrintManagerUtils
import zs.qimai.com.printer2.callback.BlueToothSearchCallBack
import zs.qimai.com.printer2.callback.OnBtConnectCallBack
import zs.qimai.com.printer2.manager.BlueDeviceManager
import zs.qimai.com.printer2.manager.DeviceManager
import java.util.ArrayList
import java.util.HashSet
class BtListActivity : AppCompatActivity(), View.OnClickListener {
@SuppressLint("MissingPermission")
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onClick(p0: View?) {
Log.d(TAG, "onClick: ${datas[p0!!.tag as Int].name}")
PrintManagerUtils.getInstance().btConnect(datas[p0!!.tag as Int].address, object :
OnBtConnectCallBack {
override fun onConnectSuccess(deviceManager: DeviceManager?) {
(deviceManager as?BlueDeviceManager)?.let {
Toast.makeText(
this@BtListActivity,
"连接成功 name = ${it.mBlueToothDevice?.name} 类型是 ${if (deviceManager.mPrintMode==1)"小票" else "标签"}",
Toast.LENGTH_LONG
).show()
//finish()
}
Log.d(TAG, "onConnectSuccess: ")
}
override fun onConnectError(errCode: Int, msg: String?) {
Toast.makeText(
this@BtListActivity,
"连接失败 code= $errCode errmsg= $msg",
Toast.LENGTH_LONG
).show()
Log.d(TAG, "onConnectError: errcode= $errCode errmsg= $msg")
}
override fun onConnectStart() {
Log.d(TAG, "onConnectStart: ")
}
})
}
private val TAG = "BtListActivity"
var adapter: Adapter? = null
var datas: ArrayList<BluetoothDevice> = ArrayList()
var setDatas: HashSet<BluetoothDevice> = HashSet()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bt_list)
Log.d(TAG, "onCreate: ")
PrintManagerUtils.getInstance().getSearchBlueToothList(object : BlueToothSearchCallBack {
override fun onRefuseGrantPermission() {
}
override fun onSearchStart() {
}
override fun searchFailed(code: Int, msg: String?) {
}
override fun onSearchFinish() {
}
override fun onRefuseOpenBtEnable() {
Log.d(TAG, "onRefuseOpenBtEnable: ")
}
override fun onSuccessOpenBtEnable() {
Log.d(TAG, "onSuccessOpenBtEnable: ")
}
override fun onBlueToothFound(bluetoothDevice: BluetoothDevice?) {
//Log.d(TAG, "onBlueToothFound: ")
bluetoothDevice?.let {
var status = setDatas.add(it)
if (status) {
datas.add(it)
}
}
if (adapter == null) {
adapter = Adapter()
rv_list.layoutManager = LinearLayoutManager(this@BtListActivity)
rv_list.adapter = adapter
} else {
adapter?.notifyDataSetChanged()
}
}
})
}
inner class Adapter : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var tv = LayoutInflater.from(parent.context).inflate(R.layout.tv_layout, parent, false)
return ViewHolder(tv)
}
override fun getItemCount(): Int = datas.size
@SuppressLint("MissingPermission")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
(holder.itemView as? TextView)?.apply {
text = datas[position].name
}
holder.itemView.tag = position
holder.itemView.setOnClickListener(this@BtListActivity)
}
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
}
}
}
package com.qimai.android.widget;
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresApi
import com.qimai.android.widget.R
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main_printer.*
import kotlinx.coroutines.*
import zs.qimai.com.printer2.callback.PrintCallBack
import zs.qimai.com.printer2.callback.PrintConnOrDisCallBack
import zs.qimai.com.printer2.callback.UsbPrintConnCallBack
import zs.qimai.com.printer2.callback.UsbSearchCallBack
import zs.qimai.com.printer2.canvas.LabelTemplete
import zs.qimai.com.printer2.canvas.TestPrintTemplate
import zs.qimai.com.printer2.executer.PrintExecutor
import zs.qimai.com.printer2.manager.DeviceManager
import zs.qimai.com.printer2.manager.DeviceManager.Companion.BT
import zs.qimai.com.printer2.manager.DeviceManager.Companion.USB
import zs.qimai.com.printer2.manager.DeviceManagerUtils
import zs.qimai.com.printer2.manager.UsbDeviceManager
import zs.qimai.com.printer2.utils.PrintManagerUtils
class MainActivityPtinter : AppCompatActivity(), PrintConnOrDisCallBack {
private var list = ArrayList<DeviceManager>()
override fun onConectPrint(device: DeviceManager) {
list.add(device)
Log.d(TAG, "onConectPrint: device= $device")
}
override fun onDisPrint(device: DeviceManager) {
list.remove(device)
Log.d(TAG, "onDisPrint: device= $device")
}
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_printer)
DeviceManagerUtils.getInstance().addConnectStatusCallBack(this)
initUsbPrinter()
tv_connect_bt.setOnClickListener {
startActivity(Intent(this, BtListActivity::class.java))
}
tv_print.setOnClickListener {
//PrintExecutor().doPrint(TestPrintTemplate())
// PrintExecutor().doPrint(LabelTemplete())
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()
}
tv_connect_usb.setOnClickListener {
startActivity(Intent(this, UsbActivity::class.java))
}
tv_disconnect_bt.setOnClickListener {
list.forEach {
if (it.mType == BT) {
PrintManagerUtils.getInstance().closeBtConn(it.address!!)
}
}
}
tv_disconnect_usb.setOnClickListener {
list.forEach {
if (it.mType == USB) {
PrintManagerUtils.getInstance().closeUsbConn(it.address!!)
}
}
}
GlobalScope.launch(Dispatchers.IO) {
one()
delay(2000)
two()
}
GlobalScope.launch {
val one = GlobalScope.async {
Log.d(TAG, "onCreate: async1 delay before")
delay(2000)
Log.d(TAG, "onCreate: async1 delay after")
}
GlobalScope.async {
Log.d(TAG, "onCreate: async2 delay before")
delay(2000)
Log.d(TAG, "onCreate: async2 delay after")
}
}
}
private fun initUsbPrinter() {
val usbDevices = mutableMapOf<String, UsbDevice>()
PrintManagerUtils.getInstance()
.getSearchUsbList(object : UsbSearchCallBack {
override fun onSearchStart() {}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onSearchFound(
s: String,
usbDevice: UsbDevice
) {
if (!usbDevice.manufacturerName?.trim().equals("POSIN")) {
usbDevices[s] = usbDevice
}
}
override fun onSearchError(i: Int, s: String?) {}
override fun onSearchFinish() {
usbDevices.forEach { entry ->
PrintManagerUtils.getInstance()
.usbConnect(entry.key, entry.value, object : UsbPrintConnCallBack {
override fun onConnStart() {}
override fun onConnSucess(usbDeviceManager: UsbDeviceManager) {
Log.d("devicesBlue", "lianjie")
Log.d("devicesBlue", "${entry.value.toString()}")
}
override fun onConnFailed(i: Int, s: String) {
Log.d("devicesBlue", "fail")
}
})
}
}
})
}
private suspend fun two() {
withContext(Dispatchers.IO) {
Log.d(TAG, "two: ")
}
}
private suspend fun one() {
withContext(Dispatchers.IO) {
for (i in 0..500000000) {
if (i == 0 || i == 500000000) {
Log.d(TAG, "one: ")
}
}
}
}
override fun onDestroy() {
super.onDestroy()
DeviceManagerUtils.getInstance().removeConnectStatusCallBack(this)
}
}
package com.qimai.android.widget;
import zs.qimai.com.printer2.canvas.PrintTemplate
class PtOrderPrintTemplate:PrintTemplate<Any> {
override fun getPrintData(data: Any): ByteArray? {
return null
}
}
\ No newline at end of file
package com.qimai.android.widget;
import android.hardware.usb.UsbDevice
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_usb.*
import zs.qimai.com.printer2.callback.UsbPrintConnCallBack
import zs.qimai.com.printer2.utils.PrintManagerUtils
import zs.qimai.com.printer2.callback.UsbSearchCallBack
import zs.qimai.com.printer2.callback.UsbSearchCallBack2
import zs.qimai.com.printer2.manager.UsbDeviceManager
class UsbActivity : AppCompatActivity(), View.OnClickListener {
private val TAG = "UsbActivity"
override fun onClick(v: View?) {
(v!!.tag as? String)?.let {
PrintManagerUtils.getInstance().usbConnect(it, datas[it]!!,object: UsbPrintConnCallBack{
override fun onConnStart() {
}
override fun onConnSucess(usbDeviceManager: UsbDeviceManager) {
Log.d(TAG, "onConnSucess: ")
finish()
}
override fun onConnFailed(code: Int, error: String) {
Log.d(TAG, "onConnFailed:code= $code msg= $error")
}
})
}
//datas[v!!.tag as String]?.let { }
}
var datas: MutableMap<String, UsbDevice> = HashMap()
var adapter: Adapter = Adapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_usb)
rv_list.layoutManager = LinearLayoutManager(this@UsbActivity)
rv_list.adapter = adapter
PrintManagerUtils.getInstance().getSearchUsbList(object : UsbSearchCallBack2 {
override fun onSearchFoundAll(devices: HashMap<String, UsbDevice>?) {
Log.d(TAG, "onSearchFoundAll: ")
}
override fun onSearchStart() {
Log.d(TAG, "onSearchStart: ")
}
override fun onSearchFound(address: String, usbDevice: UsbDevice) {
datas[address] = usbDevice
adapter.notifyDataSetChanged()
Log.d(TAG, "onSearchFound: ")
}
override fun onSearchError(errCode: Int, errMsg: String?) {
Log.d(TAG, "onSearchError: ")
}
override fun onSearchFinish() {
Log.d(TAG, "onSearchFinish: ")
}
})
PrintManagerUtils.getInstance().getSearchUsbList(object : UsbSearchCallBack {
override fun onSearchStart() {
Log.d(TAG, "onSearchStart1: ")
}
override fun onSearchFound(address: String, usbDevice: UsbDevice) {
datas[address] = usbDevice
adapter.notifyDataSetChanged()
Log.d(TAG, "onSearchFound1: ")
}
override fun onSearchError(errCode: Int, errMsg: String?) {
Log.d(TAG, "onSearchError1: ")
}
override fun onSearchFinish() {
Log.d(TAG, "onSearchFinish1: ")
}
})
}
inner class Adapter : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var tv = LayoutInflater.from(parent.context).inflate(R.layout.tv_layout, parent, false)
return ViewHolder(tv)
}
override fun getItemCount(): Int = datas.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
(holder.itemView as? TextView)?.apply {
//text = datas[position].name
datas.keys.forEachIndexed { index, s ->
if (index == position) {
text = s + " " + datas.get(s)?.deviceName
holder.itemView.tag = s
}
}
}
holder.itemView.setOnClickListener(this@UsbActivity)
}
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BtListActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="zs.qimai.com.test.MainActivity">
<TextView
android:id="@+id/tv_connect_bt"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="蓝牙连接"
android:textSize="22sp"
android:gravity="center"
android:textColor="#000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_disconnect_bt"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="蓝牙关闭"
android:textSize="22sp"
android:gravity="center"
android:textColor="#000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_connect_usb"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="USB连接"
android:textSize="22sp"
android:gravity="center"
android:textColor="#000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_disconnect_usb"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="USB关闭"
android:textSize="22sp"
android:gravity="center"
android:textColor="#000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_marginTop="10dp"
android:id="@+id/tv_print"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="打印"
android:textSize="22sp"
android:gravity="center"
android:textColor="#000"
/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BtListActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Printer01"
android:textSize="22sp"
android:textColor="#000"
android:gravity="center"
>
</TextView>
\ No newline at end of file
...@@ -55,7 +55,7 @@ repositories { ...@@ -55,7 +55,7 @@ repositories {
mavenCentral() mavenCentral()
} }
group 'com.qmai.android.fetch' group 'com.qmai.android.fetch'
version '1.2.19-SNAPSHOT' version '1.2.23-SNAPSHOT'
gradlePublish { gradlePublish {
......
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.qimai.android.tool_network;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String LIBRARY_PACKAGE_NAME = "com.qimai.android.tool_network";
/**
* @deprecated APPLICATION_ID is misleading in libraries. For the library package name use LIBRARY_PACKAGE_NAME
*/
@Deprecated
public static final String APPLICATION_ID = "com.qimai.android.tool_network";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qimai.android.tool_network"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
\ No newline at end of file
[{"outputType":{"type":"AAPT_FRIENDLY_MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"fetch-debug.aar","fullName":"debug","baseName":"debug"},"path":"AndroidManifest.xml","properties":{"packageId":"com.qimai.android.tool_network","split":""}}]
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/debug/jniLibs"/></dataSet></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/debug/shaders"/></dataSet></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/main/assets"/><source path="/Users/leiwang/project/widget/fetch/build/intermediates/shader_assets/debug/compileDebugShaders/out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/debug/assets"/></dataSet></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">tool_network</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/main/res"/><source path="/Users/leiwang/project/widget/fetch/build/generated/res/rs/debug"/><source path="/Users/leiwang/project/widget/fetch/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/main/res"><file path="/Users/leiwang/project/widget/fetch/src/main/res/values/strings.xml" qualifiers=""><string name="app_name">tool_network</string></file></source><source path="/Users/leiwang/project/widget/fetch/build/generated/res/rs/debug"/><source path="/Users/leiwang/project/widget/fetch/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/leiwang/project/widget/fetch/src/debug/res"/></dataSet><mergedItems/></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qimai.android.tool_network"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
\ No newline at end of file
R_DEF: Internal format may change without notice
local
string app_name
1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.qimai.android.tool_network"
4 android:versionCode="1"
5 android:versionName="1.0" >
6
7 <uses-sdk
8 android:minSdkVersion="19"
8-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
9 android:targetSdkVersion="28" />
9-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
10
11 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
11-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:3:5-78
11-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:3:22-76
12 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
12-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:4:5-81
12-->/Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:4:22-78
13
14</manifest>
[{"outputType":{"type":"MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"fetch-debug.aar","fullName":"debug","baseName":"debug"},"path":"../../library_manifest/debug/AndroidManifest.xml","properties":{"packageId":"com.qimai.android.tool_network","split":""}}]
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">tool_network</string>
</resources>
\ No newline at end of file
This diff is collapsed.
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/download/DownloadInterceptor.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/NoNetCacheInterceptor.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/Response/Status.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/extention/FileExtention.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/adapter/LiveDataCallAdapterFactory.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/HttpLog.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/model/BaseData.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/NetCacheInterceptor.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/Response/Resource.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/extention/ViewModelExtention.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/Response/ApiResponse.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/download/DownloadApi.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/download/DownLoadModel.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/tool/AndroidNetWorkTools.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/download/ProgressListener.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/gson/IntegerDefault0Adapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/convert/StandardGsonResponseBodyConverter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/MultiHostInterceptor.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/tool/NetworkBoundResource.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/Constant.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/SingletonHolder.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/gson/GsonAdapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/retrofit/RetrofitBuilder.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/TokenExpire.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/gson/LongDefault0Adapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/tool/SSLTool.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/gson/StringDefault0Adapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/interceptors/HeaderInterceptor.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/adapter/LiveDataCallAdapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/convert/StandardGsonConvertFactory.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/download/DownLoaderHelper.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/config/OkHttpConfig.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/gson/DoubleDefault0Adapter.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/config/HeaderConfig.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/extention/StringLogExt.kt
/Users/leiwang/project/widget/fetch/src/main/java/com/qimai/android/fetch/annotation/Standard.kt
\ No newline at end of file
36 39
0 3
\ No newline at end of file \ No newline at end of file
-- Merging decision tree log ---
manifest
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
package
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:2:11-51
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
android:versionName
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
android:versionCode
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:1-6:12
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
xmlns:android
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:1:11-69
uses-permission#android.permission.ACCESS_NETWORK_STATE
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:3:5-78
android:name
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:3:22-76
uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:4:5-81
android:name
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml:4:22-78
uses-sdk
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml reason: use-sdk injection requested
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
android:targetSdkVersion
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
android:minSdkVersion
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
ADDED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
INJECTED from /Users/leiwang/project/widget/fetch/src/main/AndroidManifest.xml
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.qmai.android.fetch</groupId> <groupId>com.qmai.android.fetch</groupId>
<artifactId>fetch</artifactId> <artifactId>fetch</artifactId>
<version>1.2.19-SNAPSHOT</version> <version>1.2.23-SNAPSHOT</version>
<packaging>aar</packaging> <packaging>aar</packaging>
<dependencies> <dependencies>
<dependency> <dependency>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<groupId>com.qmai.android.fetch</groupId> <groupId>com.qmai.android.fetch</groupId>
<artifactId>fetch</artifactId> <artifactId>fetch</artifactId>
<versioning> <versioning>
<latest>1.2.19-SNAPSHOT</latest> <latest>1.2.23-SNAPSHOT</latest>
<versions> <versions>
<version>1.2.3-SNAPSHOT</version> <version>1.2.3-SNAPSHOT</version>
<version>1.2.4-SNAPSHOT</version> <version>1.2.4-SNAPSHOT</version>
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
<version>1.2.17-SNAPSHOT</version> <version>1.2.17-SNAPSHOT</version>
<version>1.2.18-SNAPSHOT</version> <version>1.2.18-SNAPSHOT</version>
<version>1.2.19-SNAPSHOT</version> <version>1.2.19-SNAPSHOT</version>
<version>1.2.20-SNAPSHOT</version>
<version>1.2.21-SNAPSHOT</version>
<version>1.2.22-SNAPSHOT</version>
<version>1.2.23-SNAPSHOT</version>
</versions> </versions>
<lastUpdated>20201224065134</lastUpdated> <lastUpdated>20210103151017</lastUpdated>
</versioning> </versioning>
</metadata> </metadata>
...@@ -2,29 +2,29 @@ ...@@ -2,29 +2,29 @@
<metadata modelVersion="1.1.0"> <metadata modelVersion="1.1.0">
<groupId>com.qmai.android.fetch</groupId> <groupId>com.qmai.android.fetch</groupId>
<artifactId>fetch</artifactId> <artifactId>fetch</artifactId>
<version>1.2.19-SNAPSHOT</version> <version>1.2.23-SNAPSHOT</version>
<versioning> <versioning>
<snapshot> <snapshot>
<timestamp>20201224.065112</timestamp> <timestamp>20210103.151014</timestamp>
<buildNumber>1</buildNumber> <buildNumber>1</buildNumber>
</snapshot> </snapshot>
<lastUpdated>20201224065112</lastUpdated> <lastUpdated>20210103151014</lastUpdated>
<snapshotVersions> <snapshotVersions>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>1.2.19-20201224.065112-1</value>
<updated>20201224065112</updated>
</snapshotVersion>
<snapshotVersion> <snapshotVersion>
<extension>aar</extension> <extension>aar</extension>
<value>1.2.19-20201224.065112-1</value> <value>1.2.23-20210103.151014-1</value>
<updated>20201224065112</updated> <updated>20210103151014</updated>
</snapshotVersion> </snapshotVersion>
<snapshotVersion> <snapshotVersion>
<extension>pom</extension> <extension>pom</extension>
<value>1.2.19-20201224.065112-1</value> <value>1.2.23-20210103.151014-1</value>
<updated>20201224065112</updated> <updated>20210103151014</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>sources</classifier>
<extension>jar</extension>
<value>1.2.23-20210103.151014-1</value>
<updated>20210103151014</updated>
</snapshotVersion> </snapshotVersion>
</snapshotVersions> </snapshotVersions>
</versioning> </versioning>
......
...@@ -25,6 +25,8 @@ class StandardGsonResponseBodyConverter<T> constructor( ...@@ -25,6 +25,8 @@ class StandardGsonResponseBodyConverter<T> constructor(
override fun convert(value: ResponseBody): T? { override fun convert(value: ResponseBody): T? {
val reponseString = value.string() val reponseString = value.string()
// throw TOKENExpireException("token过期")
val baseData = gson.fromJson<BaseData<*>>(reponseString, BaseData::class.java) val baseData = gson.fromJson<BaseData<*>>(reponseString, BaseData::class.java)
if (TextUtils.equals("false", baseData.status)) { if (TextUtils.equals("false", baseData.status)) {
value.close() value.close()
......
package com.qimai.android.fetch.extention package com.qimai.android.fetch.extention
import android.text.TextUtils import android.text.TextUtils
import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData import androidx.lifecycle.liveData
...@@ -91,7 +92,7 @@ fun <T> ViewModel.flowSafeCall(request: () -> T) = liveData<Resource<T>> { ...@@ -91,7 +92,7 @@ fun <T> ViewModel.flowSafeCall(request: () -> T) = liveData<Resource<T>> {
} }
fun <T> handleResponseError(throwable: Throwable?): Resource<T> { fun <T> handleResponseError(throwable: Throwable?): Resource<T> {
Log.d(TAG, "handleResponseError: throwable= $throwable")
return when (throwable) { return when (throwable) {
null -> Resource.error("程序出错", null) null -> Resource.error("程序出错", null)
is HttpException -> when (throwable.code()) { is HttpException -> when (throwable.code()) {
......
package com.qimai.android.fetch.interceptors package com.qimai.android.fetch.interceptors
import android.text.TextUtils import android.text.TextUtils
import android.util.Log
import com.qimai.android.fetch.HOST_KEY import com.qimai.android.fetch.HOST_KEY
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import java.io.IOException
/** /**
* @author wangwei * @author wangwei
...@@ -23,7 +25,13 @@ class MultiHostInterceptor(var urlMap: MutableMap<String, HttpUrl>) : Intercepto ...@@ -23,7 +25,13 @@ class MultiHostInterceptor(var urlMap: MutableMap<String, HttpUrl>) : Intercepto
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val originRequest = chain.request() val originRequest = chain.request()
return chain.proceed(processRequest(originRequest)) try{
return chain.proceed(processRequest(originRequest))
}catch(e: IOException){
Log.d("MultiHostInterceptor", "intercept: e= $e")
throw e
}
} }
......
This diff is collapsed.
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