/year1/Project2/atlas/src/se/geoproject/atlas/services/NotificationService.java
Java | 155 lines | 101 code | 43 blank | 11 comment | 6 complexity | 102b72ca7421cd689e370a939d070d15 MD5 | raw file
- package se.geoproject.atlas.services;
- import java.util.ArrayList;
- import se.geoproject.atlas.R;
- import se.geoproject.atlas.activities.MapActivity;
- import se.geoproject.atlas.database.DBAdapter;
- import se.geoproject.atlas.location.Geocache;
- import se.geoproject.atlas.location.ShowDistance;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.location.Location;
- import android.os.ConditionVariable;
- import android.preference.PreferenceManager;
- /**
- *
- * Based in part on the NotifyingService from:
- * http://code.google.com/p/notime/source/browse/trunk/%20notime%20--username%20asaf.schoen/NotiMe/src/com/NotiMe/NotifyingService.java
- * @author viktor
- */
- public class NotificationService extends LocationAwareService {
-
- private static int THREAD_WAIT_TIME = 5 * 60 * 1000; // Five minutes;
- private static double NOTIFICATION_DISTANCE = 0.5; // 500 m (0.5 kilomiter)
- // This is now actually set in the onStartCommand method
-
- private static NotificationManager notificationManager;
-
- private DBAdapter db;
-
- private Thread thread;
-
- private boolean running;
-
- private ConditionVariable calculateCondition;
-
- private double latitude;
- private double longitude;
-
- @Override
- public void onCreate() {
-
- NotificationService.notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-
- db = new DBAdapter(this);
-
- running = true;
- calculateCondition = new ConditionVariable(false);
-
- thread = new Thread(calculationLoop, "NotificationService");
-
- thread.start();
- super.onCreate();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- int dist = intent.getIntExtra("distance", -1);
-
- if(dist == -1) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-
- if(sp.contains("notification_distance_list")) {
- String distance = sp.getString("notification_distance_list", "-1");
- try {
- dist = Integer.parseInt(distance);
- } catch (NumberFormatException e) {
- // Do nothing, in this case we use the default value (-1)
- }
- }
- }
-
- NOTIFICATION_DISTANCE = dist / 1000.0;
-
- return super.onStartCommand(intent, flags, startId);
- }
-
- @Override
- public void onDestroy() {
-
- // These two commands will terminate the calculation thread. In worst case it will run for one more cycle
- // (if it just started calculating)
- running = false;
- calculateCondition.open();
-
- try {
- // Wait for calculation thread to complete
- thread.join(500);
- } catch (InterruptedException e) {
-
- }
-
- NotificationService.notificationManager.cancelAll();
-
- super.onDestroy();
- }
- @Override
- public void onLocationChanged(Location location) {
-
- longitude = location.getLongitude();
- latitude = location.getLatitude();
- calculateCondition.open();
- }
-
- private void checkForNearbyGeocaches() {
-
- ArrayList<Geocache> geocaches = db.getAllGeocache();
-
- for(Geocache g: geocaches) {
- if(ShowDistance.calculateDistance(latitude, g.getLatitude(), longitude, g.getLongitude()) < NOTIFICATION_DISTANCE) {
- showNotification(g);
- }
- else { // Cancel notification
- NotificationService.notificationManager.cancel(g.hashCode());
- }
- }
- }
-
- private void showNotification(Geocache g) {
- Notification notification = new Notification(R.drawable.atlas_logo, g.getName(), System.currentTimeMillis());
- notification.defaults = 0;
-
- Intent notifyIntent = new Intent(this, MapActivity.class);
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
-
- notification.setLatestEventInfo(getApplicationContext(), getString(R.string.app_name),
- g.getName(), contentIntent);
-
- NotificationService.notificationManager.notify(g.hashCode(), notification);
- }
-
- private final Runnable calculationLoop = new Runnable() {
- @Override
- public void run() {
- while(running) {
-
- checkForNearbyGeocaches();
-
- calculateCondition.block(THREAD_WAIT_TIME); // Block until new location is found, or timeout
- calculateCondition.close();
- }
- NotificationService.this.stopSelf();
- }
-
- };
- }