Shane Shane - 3 months ago 8
Android Question

Using Ottos bus for 'notification polling'

On all my views I have an icon that will have a red dot if the user has notifications, so I created a class to constantly (every few minutes) poll and see if they have notifications. Except the

@Subscrtibe
is never getting triggered. One thing that I thought would maybe be the cause is that I start the post before the
HomeActivity
is registered but with the timer I didn't think that would be a problem?

public class NotificationUtils {

private static Timer timer;

private static final int MINUTES = 1000 * 60;
private static Context applicationContext;

public static void startTask(Context context){
checkNotifications();
applicationContext = context;
timer = new Timer();
timer.schedule(task, 0L, MINUTES);
}

public static void killTask(){
timer.cancel();
timer.purge();
}

static TimerTask task = new TimerTask() {
@Override
public void run() {
checkNotifications();
}
};

private static void checkNotifications(){
RestInterface service = RestService.getRequestInstance(applicationContext);
Call<Boolean> call = service.hasNotificatrions(SessionUser.getInstance().getUser().getId());
call.enqueue(new Callback<Boolean>() {
@Override
public void onResponse(Call<Boolean> call, Response<Boolean> response) {
sendNotificationImage(response.body());
}

@Override
public void onFailure(Call<Boolean> call, Throwable t) {
Log.w("TimerTask", "Failed");
}
});
}

private static void sendNotificationImage(boolean hasUnreadNotifications){
if(hasUnreadNotifications) {
BusProvider.getInstance().post(R.drawable.notification_alert_icon);
} else {
BusProvider.getInstance().post(R.drawable.notification_icon);
}
}
}


When a user successfully logs in, I start the polling...

public class LoginActivity extends AppCompatActivity {
....
successfulLogin(){
....
NotificationUtils.startTask(getApplicationContext());
}
}


Then my HomeActivity I register the class and subscribe..

public class HomeActivity extends AppCompatActivity {
....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
BusProvider.getInstance().register(this);
}
....
@Subscribe
public void setNotification(int imageResource){
notificationButton.setImageResource(imageResource);
Log.w("HomeActivity", "Setting resource");
}
}


Edit.. Adding BusProvider class

public final class BusProvider {
private static final Bus bus = new Bus();

public static Bus getInstance(){
return bus;
}

private BusProvider(){}
}

Answer

You should NOT use Java primitive types as event classes. You can use:

public class DisplayNotification {
    private int resourceId

    public DisplayNotification(int resourceId){
        this.resourceId = resourceId;
    }

    public int getResourceId(){
        return this.resourceId;
    }
}

change your function signature to be

@Subscribe
public void setNotification(DisplayNotification event){...}

and post it like this:

BusProvider.getInstance().post(new DisplayNotification (R.drawable.notification_icon));