1+ package com.tencent.iot.explorer.link.demo.util
2+
3+ import android.app.NotificationManager
4+ import android.content.ClipData
5+ import android.content.ClipboardManager
6+ import android.content.Context
7+ import android.graphics.Bitmap
8+ import android.graphics.BitmapFactory
9+ import android.graphics.Canvas
10+ import android.os.Build
11+ import android.os.LocaleList
12+ import android.provider.Settings
13+ import android.text.TextUtils
14+ import android.util.Log
15+ import com.tencent.iot.explorer.link.core.log.L
16+ import java.io.ByteArrayOutputStream
17+ import java.io.IOException
18+ import java.util.*
19+
20+
21+ object Utils {
22+
23+ private fun isDigitsOnly (src : String ): Boolean {
24+ val flag = src.toIntOrNull()
25+ if (flag != null ) {
26+ return true
27+ }
28+ return false
29+ }
30+
31+ // 从字符串中获取第一段连续的数字
32+ fun getFirstSeriesNumFromStr (src : String ): Int {
33+ if (TextUtils .isEmpty(src)) {
34+ return 0
35+ }
36+ var start = - 1
37+ var end = - 1
38+ for ((i, item) in src.withIndex()) {
39+ if (isDigitsOnly(item.toString()) && start < 0 ) {
40+ start = i
41+ } else if (! isDigitsOnly(item.toString()) && start >= 0 ) {
42+ end = i
43+ break // 只进行一次遍历动作
44+ }
45+ }
46+
47+ val retStr: String
48+ if (start < 0 && end < 0 ) {
49+ return 0
50+ } else if (start >= 0 && end < 0 ) {
51+ retStr = src.substring(start)
52+ } else {
53+ retStr = src.substring(start, end)
54+ }
55+
56+ if (isDigitsOnly(retStr)) {
57+ return retStr.toInt()
58+ }
59+
60+ return 0
61+ }
62+
63+ fun getLang (): String {
64+ var local: Locale ?
65+
66+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N ) {
67+ local = LocaleList .getDefault().get(0 )
68+ } else {
69+ local = Locale .getDefault()
70+ }
71+
72+ if (local == null ) {
73+ L .d(" getLang return default lang(zh-CN)" )
74+ return " zh-CN" // 默认时返回中文类型
75+ }
76+
77+ var ret = local.getLanguage().toString() + " -" + local.getCountry().toString()
78+ return ret
79+ }
80+
81+ // 获取 url 字符串参数对应的 value
82+ fun getUrlParamValue (url : String , name : String? ): String? {
83+ val paramsStr = url.substring(url.indexOf(" ?" ) + 1 , url.length)
84+ val split: MutableMap <String , String > = hashMapOf()
85+ val params = paramsStr.split(" &" )
86+ for (paramKV in params) {
87+ val kv = paramKV.split(" =" )
88+ if (kv.size == 2 ) {
89+ split[kv[0 ]] = kv[1 ]
90+ }
91+ }
92+ return split[name]
93+ }
94+
95+ interface SecondsCountDownCallback {
96+ fun currentSeconds (seconds : Int )
97+ fun countDownFinished ()
98+ }
99+
100+ fun startCountBySeconds (max : Int , secondsCountDownCallback : SecondsCountDownCallback ) {
101+ startCountBySeconds(max, 1 , secondsCountDownCallback)
102+ }
103+
104+ // 非单例线程,允许多处使用倒计时功能
105+ private fun startCountBySeconds (max : Int , step : Int , secondsCountDownCallback : SecondsCountDownCallback ) {
106+ if (max <= 0 ) return // 上线为负数或者 0 的时候不进行倒计时的功能
107+
108+ var countDown = 0 ;
109+ Thread { // 倒计时线程
110+ if (secondsCountDownCallback != null ) {
111+ secondsCountDownCallback.currentSeconds(max - countDown)
112+ }
113+ while (countDown < max) {
114+ countDown + = step
115+ Thread .sleep(step.toLong() * 1000 )
116+ if (secondsCountDownCallback != null ) {
117+ secondsCountDownCallback.currentSeconds(max - countDown)
118+ }
119+ }
120+ if (secondsCountDownCallback != null ) {
121+ secondsCountDownCallback.countDownFinished()
122+ }
123+ }.start()
124+ }
125+
126+ fun getStringValueFromXml (context : Context , xmlName : String , keyName : String ): String? {
127+ val dataSp = context.getSharedPreferences(xmlName, Context .MODE_PRIVATE )
128+ return dataSp.getString(keyName, null )
129+ }
130+
131+ fun setXmlStringValue (context : Context , xmlName : String , keyName : String , value : String ) {
132+ val dataSp = context.getSharedPreferences(xmlName, Context .MODE_PRIVATE )
133+ val editor = dataSp.edit()
134+ if (! TextUtils .isEmpty(value)) {
135+ editor.putString(keyName, value)
136+ } else {
137+ editor.remove(keyName)
138+ }
139+ editor.commit()
140+ }
141+
142+ fun clearXmlStringValue (context : Context , xmlName : String , keyName : String ) {
143+ setXmlStringValue(context, xmlName, keyName, " " )
144+ }
145+
146+ /*
147+ * 复制到粘贴板
148+ */
149+ fun copy (context : Context , data : String? ) {
150+ val clipboard = context.getSystemService(Context .CLIPBOARD_SERVICE ) as ClipboardManager
151+ val clipData = ClipData .newPlainText(null , data)
152+ clipboard.setPrimaryClip(clipData)
153+ }
154+
155+ fun isChineseSystem (context : Context ): Boolean {
156+ return context.resources.configuration.locale.language == " zh"
157+ }
158+
159+ fun getAndroidID (context : Context ): String {
160+ val id = Settings .System .getString(context.contentResolver, Settings .System .ANDROID_ID )
161+ return if (TextUtils .isEmpty(id)) " "
162+ else id
163+ }
164+
165+ fun bmpToByteArray (bitmap : Bitmap ? ): ByteArray? {
166+
167+ // 要返回的字符串
168+ var reslut: ByteArray? = null
169+ var baos: ByteArrayOutputStream ? = null
170+ try {
171+ if (bitmap != null ) {
172+ baos = ByteArrayOutputStream ()
173+ /* *
174+ * 压缩只对保存有效果bitmap还是原来的大小
175+ */
176+ bitmap.compress(Bitmap .CompressFormat .JPEG , 100 , baos)
177+ baos.flush()
178+ baos.close()
179+ // 转换为字节数组
180+ reslut = baos.toByteArray()
181+ } else {
182+ return null
183+ }
184+ } catch (e: IOException ) {
185+ e.printStackTrace()
186+ } finally {
187+ try {
188+ if (baos != null ) {
189+ baos.close()
190+ }
191+ } catch (e: IOException ) {
192+ e.printStackTrace()
193+ }
194+ }
195+ return reslut
196+ }
197+
198+ fun getBitmap (context : Context , vectorDrawableId : Int ): Bitmap ? {
199+ var bitmap: Bitmap ? = null
200+ if (Build .VERSION .SDK_INT > Build .VERSION_CODES .LOLLIPOP ) {
201+ val vectorDrawable = context.getDrawable(vectorDrawableId)
202+ bitmap = Bitmap .createBitmap(
203+ vectorDrawable!! .intrinsicWidth,
204+ vectorDrawable.intrinsicHeight, Bitmap .Config .ARGB_8888
205+ )
206+ val canvas = Canvas (bitmap)
207+ vectorDrawable.setBounds(0 , 0 , canvas.getWidth(), canvas.getHeight())
208+ vectorDrawable.draw(canvas)
209+ } else {
210+ bitmap = BitmapFactory .decodeResource(context.resources, vectorDrawableId)
211+ }
212+ return bitmap
213+ }
214+
215+ fun clearMsgNotify (context : Context , noticeId : Int ) {
216+ val notificationManager = context.getSystemService(Context .NOTIFICATION_SERVICE ) as NotificationManager
217+ notificationManager.cancel(noticeId)
218+ }
219+
220+ /* *
221+ * byte[]数组转换为16进制的字符串
222+ *
223+ * @param bytes 要转换的字节数组
224+ * @return 转换后的结果
225+ */
226+ fun bytesToHexString (bytes : ByteArray ): String? {
227+ val sb = StringBuilder ()
228+ for (i in bytes.indices) {
229+ val hex = Integer .toHexString(0xFF and bytes[i].toInt())
230+ if (hex.length == 1 ) {
231+ sb.append(' 0' )
232+ }
233+ sb.append(hex)
234+ }
235+ return sb.toString()
236+ }
237+
238+ fun dp2px (context : Context , dp : Int ): Int {
239+ return (context.resources.displayMetrics.density * dp + 0.5 ).toInt()
240+ }
241+ // @JvmStatic
242+ // fun main(args: Array<String>) {
243+ // }
244+ }
0 commit comments