package anywheresoftware.b4a.objects;
import java.util.HashMap;
import android.app.Service;
import android.content.Intent;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import anywheresoftware.b4a.AbsObjectWrapper;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Hide;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
@Hide
public class NotificationListenerWrapper extends NotificationListenerService{
private static final HashMap<Integer, StatusBarNotification> sbns = new HashMap<Integer, StatusBarNotification>();
public static int index;
public NotificationListener nl;
@Override
public void onCreate() {
super.onCreate();
BA.Log("Notification internal service created");
try {
Class.forName(getPackageName() + ".notificationservice");
} catch (ClassNotFoundException e) {
e.printStackTrace();
BA.LogError("NotificationService not found.");
}
}
private Intent createIntent(String event, StatusBarNotification sbn) throws ClassNotFoundException {
Intent i;
i = new Intent(this, Class.forName(getPackageName() + ".notificationservice"));
i.setAction("b4a_notificationlistener");
addSbnToIntent(sbn, i);
i.putExtra("event", event);
return i;
}
public static void addSbnToIntent(StatusBarNotification sbn, Intent i) {
index++;
i.putExtra("sbn", index);
sbns.put(index, sbn);
}
public static StatusBarNotification getSbnFromIntent(Intent i) {
int sbnI = i.getIntExtra("sbn", -1);
StatusBarNotification sbn = sbns.get(sbnI);
sbns.remove(sbnI);
return sbn;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (intent.hasExtra("b4a_cancel_all"))
cancelAllNotifications();
else if (intent.hasExtra("b4a_cancel")) {
StatusBarNotification sbn = getSbnFromIntent(intent);
cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
}
else if (intent.hasExtra("b4a_getactive")) {
StatusBarNotification[] all = getActiveNotifications();
if (all != null) {
for (StatusBarNotification sbn : all) {
try {
startService(createIntent("posted", sbn));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}
return Service.START_NOT_STICKY;
}
@Override
public void onNotificationPosted(StatusBarNotification arg0) {
try {
startService(createIntent("posted", arg0));
} catch (ClassNotFoundException e) {
BA.printException(e, true);
}
}
@Override
public void onNotificationRemoved(StatusBarNotification arg0) {
try {
startService(createIntent("removed", arg0));
} catch (ClassNotFoundException e) {
BA.printException(e, true);
}
}
/**
* NotificationListener allows you to access the device notifications.
*This is only supported by Android 4.3+.
*See the tutorial in the forum for more information.
*/
@Events(values={"NotificationPosted (SBN As StatusBarNotification)",
"NotificationRemoved (SBN As StatusBarNotification)"})
@Version(1.10f)
@ShortName("NotificationListener")
public static class NotificationListener {
@Hide
public BA ba;
@Hide
public String eventName;
/**
* Initializes the object and sets the subs that will handle the events.
*/
public void Initialize(BA ba, String EventName) {
this.ba = ba;
this.eventName = EventName.toLowerCase(BA.cul);
}
/**
* Handles the intent with the notifications information.
*Returns true if the intent was handled.
*/
public boolean HandleIntent(IntentWrapper StartingIntent) {
if (StartingIntent.IsInitialized() == false)
return false;
if (StartingIntent.getAction().equals("b4a_notificationlistener")) {
String event = (String) StartingIntent.GetExtra("event");
StatusBarNotification sbn = NotificationListenerWrapper.getSbnFromIntent(StartingIntent.getObject());
if (event.equals("posted")) {
ba.raiseEvent(this, eventName + "_notificationposted", AbsObjectWrapper.ConvertToWrapper(
new StatusBarNotificationWrapper(), sbn));
}
else if (event.equals("removed")) {
ba.raiseEvent(this, eventName + "_notificationremoved", AbsObjectWrapper.ConvertToWrapper(
new StatusBarNotificationWrapper(), sbn));
}
return true;
}
return false;
}
/**
* Clears all non-ongoing notifications.
*/
public void ClearAll() {
Intent i = new Intent(BA.applicationContext, NotificationListenerWrapper.class);
i.putExtra("b4a_cancel_all", true);
BA.applicationContext.startService(i);
}
/**
* Clears the given notification (if it is not an ongoing notification).
*/
public void ClearNotification(StatusBarNotificationWrapper SBN) {
Intent i = new Intent(BA.applicationContext, NotificationListenerWrapper.class);
i.putExtra("b4a_cancel", true);
NotificationListenerWrapper.addSbnToIntent(SBN.getObject(), i);
BA.applicationContext.startService(i);
}
/**
* Causes the listener to repost all the active notifications.
*/
public void GetActiveNotifications() {
Intent i = new Intent(BA.applicationContext, NotificationListenerWrapper.class);
i.putExtra("b4a_getactive", true);
BA.applicationContext.startService(i);
}
}
@ShortName("StatusBarNotification")
public static class StatusBarNotificationWrapper extends AbsObjectWrapper<StatusBarNotification> {
/**
* Returns the notification package name.
*/
public String getPackageName() {
return getObject().getPackageName();
}
/**
* Returns the notification id.
*/
public int getId() {
return getObject().getId();
}
/**
* Returns the notification ticker text field.
*/
public String getTickerText() {
CharSequence cs = getObject().getNotification().tickerText;
return cs == null ? "" : cs.toString();
}
/**
* Returns the internal notification object.
*/
public NotificationWrapper getNotification() {
NotificationWrapper nw = new NotificationWrapper();
nw.setObject(getObject().getNotification());
return nw;
}
}
}