Skip to content

Commit e3f206e

Browse files
committed
Update
1 parent c3df94a commit e3f206e

2 files changed

Lines changed: 60 additions & 9 deletions

File tree

app/src/main/java/com/omarea/common/ui/BannerNotificationManager.kt

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,16 @@ object BannerNotificationManager {
4242
val title: String?,
4343
val message: String,
4444
val type: BannerType,
45-
val position: BannerPosition
45+
val position: BannerPosition,
46+
val icon: String?
4647
)
4748

4849
private val queue = ArrayDeque<BannerRequest>()
4950
private var isShowing = false
5051

5152
/**
53+
* @param icon Tên resource drawable/mipmap tùy chỉnh (vd "ic_my_icon"). Nếu bỏ trống hoặc
54+
* không tìm thấy resource tương ứng, mặc định dùng icon của chính app.
5255
* @param onNoActivity gọi khi không có Activity nào đang foreground (app ở background),
5356
* dùng để nơi gọi có thể fallback sang Toast thường hoặc bỏ qua.
5457
*/
@@ -57,14 +60,15 @@ object BannerNotificationManager {
5760
message: String,
5861
type: BannerType = BannerType.INFO,
5962
position: BannerPosition = BannerPosition.TOP,
63+
icon: String? = null,
6064
onNoActivity: (() -> Unit)? = null
6165
) {
6266
if (CurrentActivityHolder.get() == null) {
6367
onNoActivity?.invoke()
6468
return
6569
}
6670
mainHandler.post {
67-
queue.addLast(BannerRequest(title, message, type, position))
71+
queue.addLast(BannerRequest(title, message, type, position, icon))
6872
if (!isShowing) showNext()
6973
}
7074
}
@@ -96,16 +100,16 @@ object BannerNotificationManager {
96100
val titleView = view.findViewById<TextView>(R.id.banner_title)
97101
val messageView = view.findViewById<TextView>(R.id.banner_message)
98102

99-
val (colorRes, iconRes) = when (req.type) {
100-
BannerType.INFO -> R.color.banner_info to R.drawable.ic_banner_info
101-
BannerType.SUCCESS -> R.color.banner_success to R.drawable.ic_banner_success
102-
BannerType.WARNING -> R.color.banner_warning to R.drawable.ic_banner_warning
103-
BannerType.ERROR -> R.color.banner_error to R.drawable.ic_banner_error
103+
val colorRes = when (req.type) {
104+
BannerType.INFO -> R.color.banner_info
105+
BannerType.SUCCESS -> R.color.banner_success
106+
BannerType.WARNING -> R.color.banner_warning
107+
BannerType.ERROR -> R.color.banner_error
104108
}
105109
(bannerRoot.background?.mutate() as? GradientDrawable)?.setColor(
106110
activity.resources.getColor(colorRes, activity.theme)
107111
)
108-
icon.setImageResource(iconRes)
112+
icon.setImageDrawable(resolveIcon(activity, req.icon))
109113

110114
if (!req.title.isNullOrEmpty()) {
111115
titleView.text = req.title
@@ -139,4 +143,44 @@ object BannerNotificationManager {
139143
// rồi xử lý banner tiếp theo trong hàng đợi (nếu có).
140144
mainHandler.postDelayed({ showNext() }, TOAST_LONG_DURATION_MS)
141145
}
146+
147+
/**
148+
* Tìm drawable cho icon theo thứ tự ưu tiên:
149+
* 1. Nếu `name` là đường dẫn file ảnh tồn tại trên máy (vd "/sdcard/.../icon.png") -> decode trực tiếp từ file.
150+
* 2. Nếu `name` là tên resource drawable/mipmap có sẵn trong app -> dùng resource đó.
151+
* 3. Nếu không có gì khớp -> mặc định trả về icon của chính app.
152+
*/
153+
private fun resolveIcon(activity: Activity, name: String?): android.graphics.drawable.Drawable? {
154+
if (!name.isNullOrEmpty()) {
155+
if (name.startsWith("/") || name.startsWith("file://")) {
156+
try {
157+
val path = name.removePrefix("file://")
158+
val file = java.io.File(path)
159+
if (file.exists() && file.isFile) {
160+
val bitmap = android.graphics.BitmapFactory.decodeFile(file.absolutePath)
161+
if (bitmap != null) {
162+
return android.graphics.drawable.BitmapDrawable(activity.resources, bitmap)
163+
}
164+
}
165+
} catch (e: Exception) {
166+
}
167+
} else {
168+
try {
169+
var resId = activity.resources.getIdentifier(name, "drawable", activity.packageName)
170+
if (resId == 0) {
171+
resId = activity.resources.getIdentifier(name, "mipmap", activity.packageName)
172+
}
173+
if (resId != 0) {
174+
return androidx.core.content.ContextCompat.getDrawable(activity, resId)
175+
}
176+
} catch (e: Exception) {
177+
}
178+
}
179+
}
180+
return try {
181+
activity.packageManager.getApplicationIcon(activity.packageName)
182+
} catch (e: Exception) {
183+
null
184+
}
185+
}
142186
}

app/src/main/java/com/tool/tree/BannerReceiver.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ import com.omarea.krscript.config.StringResRef
1717
* --es title "Thành công" \
1818
* --es text "Đã cài đặt module xong" \
1919
* --es type "success" \
20-
* --es position "bottom"
20+
* --es position "bottom" \
21+
* --es icon "ic_my_custom_icon"
2122
*
2223
* Extra "type" nhận 1 trong: info (mặc định) | success | warning | error
2324
* Extra "position" nhận 1 trong: top (mặc định) | bottom
25+
* Extra "icon" (tùy chọn): có thể là
26+
* - đường dẫn file ảnh trên máy, vd "/sdcard/Download/icon.png"
27+
* - hoặc tên resource drawable/mipmap có sẵn trong app, vd "ic_banner_success"
28+
* Bỏ trống hoặc không tìm thấy -> mặc định dùng icon của chính app.
2429
* Nếu app đang ở background (không có Activity foreground), sẽ tự rơi về hiện Toast thường.
2530
*/
2631
class BannerReceiver : BroadcastReceiver() {
@@ -38,12 +43,14 @@ class BannerReceiver : BroadcastReceiver() {
3843
"bottom" -> BannerPosition.BOTTOM
3944
else -> BannerPosition.TOP
4045
}
46+
val icon = intent.getStringExtra("icon")
4147

4248
BannerNotificationManager.show(
4349
title = title,
4450
message = message,
4551
type = type,
4652
position = position,
53+
icon = icon,
4754
onNoActivity = {
4855
// App đang ở background, không có nơi để hiện banner -> fallback Toast
4956
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()

0 commit comments

Comments
 (0)