1.00
Sub Class_Globals
Private Channel As JavaObject
Private NotificationBuilder As JavaObject
Private SdkLevel As Int
Private ctxt As JavaObject
Private const S_OLD = 0, S_BUILDER = 1, S_CHANNEL = 2 As Int
Private SupportLevel As Int
Private OldNotification As Notification
Private PendingIntentStatic As JavaObject
Private NotificationStatic As JavaObject
Private common As JavaObject
End Sub
'Initializes the builder.
'ChannelId - On Android 8+ notifications are grouped by channels. Some of the features belong to the channel
' and not to the specific notification.
' Note that once a notification channel is created, you cannot change its behavior without uninstalling the app.
' NB6 adds the notification level string to the ChannelId so in most cases you can use the same value for all notifications.
'Channel Name - The channel name that appears when pressing on All Categories button (Android 8+).
'ImportanceLevel - MIN, LOW, DEFAULT, HIGH
'MIN - Minimum interrup. Cannot be used with foreground services.
'LOW - Without sound.
'DEFAULT - With sound.
'HIGH - Might appear as a headup notification.
Public Sub Initialize (ChannelId As String, ChannelName As Object, ImportanceLevel As String) As NB6
ctxt.InitializeContext
PendingIntentStatic.InitializeStatic("android.app.PendingIntent")
NotificationStatic.InitializeStatic("android.app.Notification")
common.InitializeStatic("anywheresoftware.b4a.keywords.Common")
Dim jo As JavaObject
SdkLevel = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
If SdkLevel < 23 Then
SupportLevel = S_OLD
Else if SdkLevel >= 26 Then
SupportLevel = S_CHANNEL
Else
SupportLevel = S_BUILDER
End If
If IsOld Then
OldNotification.Initialize
OldNotification.Icon = "icon"
Else if IsChannel Then
ChannelId = ChannelId & "_" & ImportanceLevel
NotificationBuilder.InitializeNewInstance("android.app.Notification$Builder", Array(ctxt, ChannelId))
Dim im As Map = CreateMap("MIN": 1, "LOW": 2, "DEFAULT": 3, "HIGH": 4)
Dim i As Int = im.Get(ImportanceLevel)
Channel.InitializeNewInstance("android.app.NotificationChannel", Array(ChannelId, Application.LabelName, i))
Else
NotificationBuilder.InitializeNewInstance("android.app.Notification$Builder", Array(ctxt))
Dim pm As Map = CreateMap("MIN": -2, "LOW": -1, "DEFAULT": 0, "HIGH": 1)
Dim p As Int = pm.Get(ImportanceLevel)
NotificationBuilder.RunMethod("setPriority", Array(p))
End If
If ImportanceLevel = "DEFAULT" Or ImportanceLevel = "HIGH" Then
SetDefaults(True, True, True)
Else
SetDefaults(False, True, True)
End If
Return Me
End Sub
'Adds a button action.
'Bmp - Button image. Not always appears.
'Title - Button title (CharSequence)
'Service - The service that will receive the action. <b>Cannot be the Starter service.</b>
'Action - The action in the StartingIntent.
Public Sub AddButtonAction (Bmp As Bitmap, Title As Object, Service As Object, Action As String) As NB6
If IsBuilder = False Then Return Me
Dim ac As Object = CreateAction(Bmp, Title, CreateReceiverPendingIntent(Service, Action))
NotificationBuilder.RunMethod("addAction", Array(ac))
Return Me
End Sub
'Action intent that will be sent when the notification is deleted.
'Service - The service that will receive the action. <b>Cannot be the Starter service.</b>
'Action - The action in the StartingIntent.
Public Sub DeleteAction (Service As Object, Action As String) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setDeleteIntent", Array(CreateReceiverPendingIntent(Service, Action)))
End If
Return Me
End Sub
'Sets the notification icon on old devices. By default the app icon will be used.
Public Sub OldNotificationIcon (ResourceName As String) As NB6
If IsOld Then
OldNotification.Icon = ResourceName
End If
Return Me
End Sub
'Sets the status bar icon. The icon size should be 24 x 24.
Public Sub SmallIcon (Icon As Bitmap) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setSmallIcon", Array(CreateIconFromBitmap(Icon)))
End If
Return Me
End Sub
'Sets the content icon. Should be 256 x 256.
Public Sub LargeIcon (Icon As Bitmap) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setLargeIcon", Array(CreateIconFromBitmap(Icon)))
End If
Return Me
End Sub
'Only plays a sound if the notification is not already displayed.
Public Sub OnlyAlertOnce (Once As Boolean) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setOnlyAlertOnce", Array(Once))
End If
Return Me
End Sub
'Cancels the notification when the user clicks on it.
Public Sub AutoCancel (Cancel As Boolean) As NB6
If IsOld Then
OldNotification.AutoCancel = Cancel
Else
NotificationBuilder.RunMethod("setAutoCancel", Array(Cancel))
End If
Return Me
End Sub
'One of the following values: NONE, SMALL, LARGE
'Not supported by all launchers.
Public Sub BadgeIconType (IconType As String) As NB6
If SdkLevel >= 26 Then
Dim m As Map = CreateMap("LARGE": 2, "NONE": 0, "SMALL": 1)
NotificationBuilder.RunMethod("setBadgeIconType", Array(m.Get(IconType)))
End If
Return Me
End Sub
'Sets the accent color.
Public Sub Color (Clr As Int) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setColor", Array(Clr))
End If
Return Me
End Sub
'Sets a number that might be displayed as a badge.
Public Sub Number (Num As Int) As NB6
If IsOld Then
OldNotification.Number = Num
Else
NotificationBuilder.RunMethod("setNumber", Array(Num))
End If
Return Me
End Sub
'Shows a timestamp
Public Sub ShowWhen (Time As Long) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setShowWhen", Array(True))
NotificationBuilder.RunMethod("setWhen", Array(Time))
End If
Return Me
End Sub
'Shows a progress bar. Cannot be used with SubText.
'Value - Current value.
'MaxValue - Maximum value.
'Indeterminate - Set to true for an indeterminate progress bar.
Public Sub Progress (Value As Int, MaxValue As Int, Indeterminate As Boolean) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setProgress", Array(MaxValue, Value, Indeterminate))
End If
Return Me
End Sub
'Additional text. Occupies the same place as the progress bar so do not use both features.
Public Sub SubText (Text As Object) As NB6
If IsBuilder Then
NotificationBuilder.RunMethod("setSubText", Array(Text))
End If
Return Me
End Sub
'Set which features will be inherited from the system defaults.
'The defaults are also set based on the importance level.
Public Sub SetDefaults (Sound As Boolean, Light As Boolean, Vibrate As Boolean) As NB6
If IsOld Then
OldNotification.Sound = Sound
OldNotification.Light = Light
OldNotification.Vibrate = Vibrate
Else
If IsChannel Then
Channel.RunMethod("enableLights", Array(Light))
Channel.RunMethod("enableVibration", Array(Vibrate))
Else
Dim CurrentDefaults As Int
If Sound Then CurrentDefaults = 1
If Vibrate Then CurrentDefaults = Bit.Or(CurrentDefaults, 2)
If Light Then CurrentDefaults = Bit.Or(CurrentDefaults, 4)
NotificationBuilder.RunMethod("setDefaults", Array(CurrentDefaults))
End If
End If
Return Me
End Sub
'Sets a custom sound.
'The uri must be created with FileProvider.
Public Sub CustomSound (FileProviderUri As Object) As NB6
If IsOld Then Return Me
ctxt.RunMethod("grantUriPermission", Array("com.android.systemui", FileProviderUri, 1))
If IsBuilder Then
NotificationBuilder.RunMethod("setSound", Array(FileProviderUri, NotificationStatic.GetField("AUDIO_ATTRIBUTES_DEFAULT")))
If IsChannel Then
Channel.RunMethod("setSound", Array(FileProviderUri, NotificationStatic.GetField("AUDIO_ATTRIBUTES_DEFAULT")))
End If
End If
Return Me
End Sub
'Possible values: PUBLIC, PRIVATE or SECRET
'Default value is PRIVATE.
'PRIVATE - notification content will not appear above secure lock screen. Title and icon will appear.
'PUBLIC - notification content will apear everywhere.
'SECRET - notification will not appear at all above secure lock screen.
Public Sub Visibility (Value As String) As NB6
If IsBuilder Then
Dim m As Map = CreateMap("PUBLIC": 1, "SECRET": -1, "PRIVATE": 0)
Dim i As Int = m.Get(Value)
NotificationBuilder.RunMethod("setVisibility", Array(i))
End If
Return Me
End Sub
'Creates a "big picture" notification.
Public Sub BigPictureStyle(LargeIconBmp As Bitmap, Picture As Bitmap, ContentTitle As Object, SummaryText As Object) As NB6
If IsBuilder Then
SetStyle("android.app.Notification$BigPictureStyle", _
CreateMap("bigLargeIcon": LargeIconBmp, _
"bigPicture": Picture, _
"setBigContentTitle": ContentTitle, _
"setSummaryText": SummaryText))
End If
Return Me
End Sub
'Creates a "big text" notification.
Public Sub BigTextStyle (ContentTitle As Object, SummaryText As Object, Text As Object) As NB6
If IsBuilder Then
SetStyle("android.app.Notification$BigTextStyle", _
CreateMap("bigText": Text, "setBigContentTitle": ContentTitle, "setSummaryText": SummaryText))
End If
Return Me
End Sub
Private Sub SetStyle(StyleName As String, Props As Map)
Dim style As JavaObject
style.InitializeNewInstance(StyleName, Null)
For Each method As String In Props.Keys
Dim value As Object = Props.Get(method)
If value <> Null Then
style.RunMethod(method, Array(value))
End If
Next
NotificationBuilder.RunMethod("setStyle", Array(style))
End Sub
'Build the notification and returns the notification object.
'ContentTitle - Title (CharSequence)
'ContentText - Body text (CharSequence)
'Tag - Tag that can be intercepted in Activity_Resume when the user clicks on the notificaiton.
'Activity - The activity that will be launched when the user clicks on the notification.
Public Sub Build (ContentTitle As Object, ContentText As Object, Tag As String, Activity As Object) As Notification
If IsOld Then
OldNotification.SetInfo2(ContentTitle, ContentText, Tag, Activity)
Return OldNotification
Else
Dim in As Intent = CreateIntent(Activity, False)
in.Flags = Bit.Or(268435456, 131072) 'FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_REORDER_TO_FRONT
in.PutExtra("Notification_Tag", Tag)
Dim PendingIntent As Object = PendingIntentStatic.RunMethod("getActivity", Array(ctxt, Rnd(0, 0x7fffffff), in, 0))
NotificationBuilder.RunMethodJO("setContentTitle", Array(ContentTitle)).RunMethodJO("setContentText", Array(ContentText))
NotificationBuilder.RunMethod("setContentIntent", Array(PendingIntent))
If IsChannel Then
Dim manager As JavaObject = ctxt.RunMethod("getSystemService", Array("notification"))
manager.RunMethod("createNotificationChannel", Array(Channel))
End If
Return NotificationBuilder.RunMethod("build", Null)
End If
End Sub
Private Sub CreateReceiverPendingIntent (Service As Object, Action As String) As Object
Dim in As Intent = CreateIntent(Service, True)
in.Action = Action
Return PendingIntentStatic.RunMethod("getBroadcast", Array(ctxt, 1, in, 0))
End Sub
Private Sub CreateIntent (Target As Object, Receiver As Boolean) As Intent
Target = common.RunMethod("getComponentClass", Array(Null, Target, Receiver))
Dim in As JavaObject
in.InitializeNewInstance("android.content.Intent", Array(ctxt, Target))
Return in
End Sub
Private Sub CreateAction (Bmp As Bitmap, Title As Object, PendingIntent As Object) As Object
Dim builder As JavaObject
builder.InitializeNewInstance("android.app.Notification$Action$Builder", Array(CreateIconFromBitmap(Bmp), Title, PendingIntent))
Return builder.RunMethod("build", Null)
End Sub
Private Sub CreateIconFromBitmap(bmp As Bitmap) As Object
If bmp = Null Or bmp.IsInitialized = False Then Return 0
Dim icon As JavaObject
Return icon.InitializeStatic("android.graphics.drawable.Icon").RunMethod("createWithBitmap", Array(bmp))
End Sub
Private Sub IsBuilder As Boolean
Return SupportLevel >= S_BUILDER
End Sub
Private Sub IsOld As Boolean
Return SupportLevel = S_OLD
End Sub
Private Sub IsChannel As Boolean
Return SupportLevel = S_CHANNEL
End Sub