yawers
yawers

Reputation: 223

Android: service 'not yet bound' but onBind() is called?

I am trying to make a button that will change the interruption filter (None, Priority, All) in Android Lollipop. When I press the button, the log says W/NotificationListenerService[NotificationService]: Notification listener service not yet bound. and does not change the interruption filter. I get the "NLS Started" and the "NLS Bound" logs. Why is it giving me this warning? Here is my code:

MainActivity.java:

public class MainActivity extends Activity {
    private NotificationService notifs;
    private ServiceConnection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        notifs = new NotificationService();
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.d("NOTIF", "NLS Started");
                NotificationService.ServiceBinder binder = (NotificationService.ServiceBinder)service;
                notifs = binder.getService();
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d("NOTIF", "NLS Stopped");
            }
        };
        Intent intent = new Intent(this, NotificationService.class);
        startService(intent);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);

        final Button b = (Button) findViewById(R.id.b);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (notifs.getCurrentInterruptionFilter() == NotificationService.INTERRUPTION_FILTER_NONE) {
                    //set all
                    b.setBackground(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_ring_volume));
                    notifs.requestInterruptionFilter(NotificationService.INTERRUPTION_FILTER_ALL);
                } else if (notifs.getCurrentInterruptionFilter() == NotificationListenerService.INTERRUPTION_FILTER_PRIORITY) {
                    //set none
                    b.setBackground(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_ring_off));
                    notifs.requestInterruptionFilter(NotificationService.INTERRUPTION_FILTER_NONE);
                } else {
                    //set priority
                    b.setBackground(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_ring_priority));
                    notifs.requestInterruptionFilter(NotificationService.INTERRUPTION_FILTER_PRIORITY);
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unbindService(connection);
        connection = null;
    }
}

NotificationService.java:

public class NotificationService extends NotificationListenerService {
    private final IBinder binder = new ServiceBinder();
    private boolean isBound = false;

    public NotificationService() {
    }

    public class ServiceBinder extends Binder {
        NotificationService getService() {
            return NotificationService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        isBound = true;
        Log.d("NOTIF", "NLS Bound");
        return binder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) {
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("NOTIF", "Started");
        Toast.makeText(NotificationService.this, "NLS Started", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public boolean isBound() {
        return isBound;
    }
}

Upvotes: 2

Views: 2593

Answers (1)

Bob Snyder
Bob Snyder

Reputation: 38309

Replace the onBind() method in your service with this:

@Override
public IBinder onBind(Intent intent) {
    isBound = true;
    String action = intent.getAction();
    Log.d("NOTIF", "onBind: " + action);

    if (SERVICE_INTERFACE.equals(action)) {
        Log.d("NOTIF", "Bound by system");
        return super.onBind(intent);
    } else {
        Log.d("NOTIF", "Bound by application");
        return binder;
    }
}

Also check that your service is declared in the manifest as shown in the overview of the documentation.

If your service is correctly declared in the manifest, and Notification Access is enabled in Security / Sound & Notification, the system will bind to the service using action NotificationListenerService.SERVICE_INTERFACE. For this bind request, the service must return the binder for NotificationListenerService, which is super.onBind(intent).

Upvotes: 5

Related Questions