Introduction
In this article I will show you how to write example android service which will be restarted after change user preferences. After changes are applied service will show toast with last execution time.
XML Files
First we will write some piece of code that will display preferences and will show them to user. Let's start from define xml with preferences:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Update frequency" >
<ListPreference
android:defaultValue="15 minut"
android:entries="@array/listFrequency"
android:entryValues="@array/listValues"
android:key="Frequency"
android:title="Change update frequency" />
</PreferenceCategory>
</PreferenceScreen>
Here goes entries and entryValues from @array:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="listFrequency">
<item>1 minuta</item>
<item>2 minuty</item>
<item>10 minut</item>
<item>15 minut</item>
<item>30 minut</item>
<item>Wylaczone</item>
</string-array>
<string-array name="listValues">
<item>60000</item>
<item>120000</item>
<item>600000</item>
<item>900000</item>
<item>1800000</item>
<item>0000</item>
</string-array>
</resources>
This xml will look like:
And don't forget to modify AndroidManifest.xml
<application>
.....
<service
android:enabled="true"
android:name=".service.BackgroundService" >
</service>
</application>
<uses-permission android:name="android.permission.VIBRATE" />
Now let's code.
It's time to create Activity which will extend PreferenceActivity class. In this class we add OnSharedPreferenceChangeListener which will be called after change user preferences.
package com.stock_app.home;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.stock_app.R;
import com.stock_app.service.BackgroundService;
public class PreferencesActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(prefchanged);
}
OnSharedPreferenceChangeListener prefchanged = new OnSharedPreferenceChangeListener() {
@Override
// Method for listening changes of SharedPreferences.
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
Intent serviceIntent = new Intent(getBaseContext(),
BackgroundService.class);
// Only if key was Frequency we will restart service.
if (key.equals("Frequency")) {
String value = sharedPreferences.getString("Frequency", "0000");
// If user turned of Service
if (value.equals("0000")) {
stop(serviceIntent);
String message = "Service is shut down.";
Toast myToast = Toast.makeText(getApplicationContext(),
message, Toast.LENGTH_SHORT);
myToast.show();
} else {
// Oherwise restart
stop(serviceIntent);
start(serviceIntent);
}
}
}
};
// Helper methods for start/stop service
private void start(Intent serviceIntent) {
try {
startService(serviceIntent);
} catch (Exception e) {
// If exception thrown means service is running
stopService(serviceIntent);
}
}
private void stop(Intent serviceIntent) {
try {
stopService(serviceIntent);
} catch (Exception e) {
// If exception thrown means service not is running
startService(serviceIntent);
}
}
}
Now it's time for Service:
package com.stock_app.service;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.IBinder;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
public class BackgroundService extends Service {
private static final String TAG = BackgroundService.class.getSimpleName();
private static int NOTIFICATION_ID = 1;
private int icon = (Integer) 0x7f02000d;
private Toast myToast;
private Timer updatingTimer;
public NotificationManager notificationmanager;
public static boolean isGoing = false;
SharedPreferences preferences = null;
private TimerTask notify;
@Override
public void onCreate() {
super.onCreate();
if (!isGoing) {
notify = new TimerTask() {
@Override
public void run() {
checkValues();
}
};
notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
updatingTimer = new Timer();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
updatingTimer.cancel();
notify.cancel();
super.onDestroy();
isGoing = false;
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
String message = "";
isGoing = true;
preferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
String str_frequency = preferences
.getString("Frequency", "1800000");
long frequency = Long.parseLong(str_frequency);
if (str_frequency.equals("60000")) {
message = "Changed to one minute";
} else if (str_frequency.equals("120000")) {
message = "Changed to 2 minutes";
} else if (str_frequency.equals("600000")) {
message = "Changed to 10 minutes";
} else if (str_frequency.equals("900000")) {
message = "Changed to 15 minutes";
} else if (str_frequency.equals("1800000")) {
message = "Changed to 30 minutes";
}
// If running show toast:
if (message != "" && message != "0000") {
myToast = Toast.makeText(getApplicationContext(), message,
Toast.LENGTH_SHORT);
myToast.show();
}
updatingTimer.scheduleAtFixedRate(notify, 1 * 1000, frequency);
} catch (Exception ex) {
Log.i(TAG, ex.toString());
}
}
public void displayNotificationMessage(String message) {
Notification notif = new Notification(icon, message,
System.currentTimeMillis());
// enabling vibrate
boolean checkVibration = preferences
.getBoolean("checkVibration", false);
if (checkVibration)
vibrtationEnabled(notif);
// enabling sound
boolean checkSound = preferences.getBoolean("checkSound", false);
if (checkSound)
soundEnabled(notif);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, BackgroundServiceActivity.class), 0);
notif.setLatestEventInfo(this, "Notification!", message, contentIntent);
notif.defaults |= Notification.DEFAULT_LIGHTS;
notificationmanager.notify(NOTIFICATION_ID, notif);
NOTIFICATION_ID++;
}
public void vibrtationEnabled(Notification notification) {
long[] vibrate = { 0, 100, 200, 300 };
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(vibrate, -1);
}
public static void soundEnabled(Notification notification) {
notification.sound = Uri
.parse("android.resource://com.stock.app/raw/notifsound");
notification.defaults |= Notification.DEFAULT_SOUND;
}
public void checkValues() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND);
Date time = c.getTime();
displayNotificationMessage(sdf.format(time));
}
}
Conclusion
This is a sample code that will make your life easier :) If you want full application source code @me.