Reputation: 574
I have a service that runs in the background and every 15 minutes, it will show a notification or dialog. But how can I get it to start and stop OnClick of a FAB? The button shows a Snack Bar OnClick, currently. I want to add If/Else code to start and stop the service. How can I do this?
Here is the service:
public class SafeService extends Service {
private Handler mHandler = new Handler();
private Timer mTimer = null;
public static final int NOTIFICATION_ID = 1;
public static final long NOTIFY_INTERVAL = 900 * 1000; // 15 Minutes
/*^TODO - TEST NOTIFY_INTERVAL FOR ACCURACY^*/
/*^Those are for the timer and handler so the code
can recognise it^ The last one gives how long the timer runs */
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
// Cancels the timer if it already existed.
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
@Override
public void run() {
// Lollipop or Above
if (Build.VERSION.SDK_INT >= 21) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(SafeService.this);
new NotificationCompat.Builder(SafeService.this);
builder.setSmallIcon(R.drawable.smallplaceholder);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder.setContentTitle("Safeguard");
builder.setContentText("Be careful, Trainer! Remember to look up and stay aware of your surroundings!!");
builder.setStyle(new NotificationCompat.BigTextStyle().bigText("Be careful, Trainer! Remember to look up and stay aware of your surroundings!!"));
builder.setPriority(Notification.PRIORITY_HIGH);
builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
//Below Lollipop
} else {
new MaterialDialog.Builder(SafeService.this)
.title(R.string.warning_title)
.content(R.string.warning)
.positiveText(R.string.button_ok)
.show();
}
}
});
}
};
}
Here is the button I want to start and stop the service:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Safeguard is now on!", Snackbar.LENGTH_LONG).show();
//Start service after showing SnackBar
}
});
Upvotes: 0
Views: 119
Reputation: 45432
You can use a Singleton
instance which will bind/unbind from your service, this way, the service will not be unbound if your activity is destroyed by Android :
ServiceSingleton.java
:
public class ServiceSingleton {
private String TAG = ServiceSingleton.class.getSimpleName();
private static ServiceSingleton mInstance;
private Context mContext;
private boolean mBound = false;
private SafeService mService;
private ServiceConnection mServiceConnection = null;
public static ServiceSingleton getInstance(Context context) {
if (mInstance == null)
mInstance = new ServiceSingleton(context);
return mInstance;
}
private ServiceSingleton(Context context) {
this.mContext = context.getApplicationContext();
}
public boolean startNotification() {
if (!mBound) {
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
Log.i(TAG, "onServiceConnected");
mService = ((SafeService.LocalBinder) service).getService();
mService.startNotification();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
Intent intent = new Intent(this, SafeService.class);
mBound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
if (!mBound) {
Log.e(TAG, "Error cant bind to service !");
}
} else {
if (mService != null) {
mService.startNotification();
}
}
return mBound;
}
public void stopNotification() {
if (mBound && mService != null) {
mService.stopNotification();
}
}
public boolean isNotificationStarted() {
if (mBound && mService != null) {
return mService.isNotificationStarted();
}
return false;
}
public void close() {
try {
if (mBound) {
if (mService!=null){
mService.stopNotification();
}
mContext.unbindService(mServiceConnection);
mBound = false;
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
public boolean isBound() {
return mBound;
}
}
In your onCreate()
mSingleton = ServiceSingleton.getInstance();
For your click listener :
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mSingleton.isNotificationStarted()){
mSingleton.startNotification();
}
else {
mSingleton.stopNotification();
}
}
});
stopNotification()
wont unbind service if you want to reuse it, if you want to shut it down call close()
Upvotes: 1