PageRenderTime 51ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/year1/Project2/atlas/src/se/geoproject/atlas/services/NotificationService.java

https://bitbucket.org/pmyllykoski/it-university
Java | 155 lines | 101 code | 43 blank | 11 comment | 6 complexity | 102b72ca7421cd689e370a939d070d15 MD5 | raw file
  1. package se.geoproject.atlas.services;
  2. import java.util.ArrayList;
  3. import se.geoproject.atlas.R;
  4. import se.geoproject.atlas.activities.MapActivity;
  5. import se.geoproject.atlas.database.DBAdapter;
  6. import se.geoproject.atlas.location.Geocache;
  7. import se.geoproject.atlas.location.ShowDistance;
  8. import android.app.Notification;
  9. import android.app.NotificationManager;
  10. import android.app.PendingIntent;
  11. import android.content.Context;
  12. import android.content.Intent;
  13. import android.content.SharedPreferences;
  14. import android.location.Location;
  15. import android.os.ConditionVariable;
  16. import android.preference.PreferenceManager;
  17. /**
  18. *
  19. * Based in part on the NotifyingService from:
  20. * http://code.google.com/p/notime/source/browse/trunk/%20notime%20--username%20asaf.schoen/NotiMe/src/com/NotiMe/NotifyingService.java
  21. * @author viktor
  22. */
  23. public class NotificationService extends LocationAwareService {
  24. private static int THREAD_WAIT_TIME = 5 * 60 * 1000; // Five minutes;
  25. private static double NOTIFICATION_DISTANCE = 0.5; // 500 m (0.5 kilomiter)
  26. // This is now actually set in the onStartCommand method
  27. private static NotificationManager notificationManager;
  28. private DBAdapter db;
  29. private Thread thread;
  30. private boolean running;
  31. private ConditionVariable calculateCondition;
  32. private double latitude;
  33. private double longitude;
  34. @Override
  35. public void onCreate() {
  36. NotificationService.notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  37. db = new DBAdapter(this);
  38. running = true;
  39. calculateCondition = new ConditionVariable(false);
  40. thread = new Thread(calculationLoop, "NotificationService");
  41. thread.start();
  42. super.onCreate();
  43. }
  44. @Override
  45. public int onStartCommand(Intent intent, int flags, int startId) {
  46. int dist = intent.getIntExtra("distance", -1);
  47. if(dist == -1) {
  48. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
  49. if(sp.contains("notification_distance_list")) {
  50. String distance = sp.getString("notification_distance_list", "-1");
  51. try {
  52. dist = Integer.parseInt(distance);
  53. } catch (NumberFormatException e) {
  54. // Do nothing, in this case we use the default value (-1)
  55. }
  56. }
  57. }
  58. NOTIFICATION_DISTANCE = dist / 1000.0;
  59. return super.onStartCommand(intent, flags, startId);
  60. }
  61. @Override
  62. public void onDestroy() {
  63. // These two commands will terminate the calculation thread. In worst case it will run for one more cycle
  64. // (if it just started calculating)
  65. running = false;
  66. calculateCondition.open();
  67. try {
  68. // Wait for calculation thread to complete
  69. thread.join(500);
  70. } catch (InterruptedException e) {
  71. }
  72. NotificationService.notificationManager.cancelAll();
  73. super.onDestroy();
  74. }
  75. @Override
  76. public void onLocationChanged(Location location) {
  77. longitude = location.getLongitude();
  78. latitude = location.getLatitude();
  79. calculateCondition.open();
  80. }
  81. private void checkForNearbyGeocaches() {
  82. ArrayList<Geocache> geocaches = db.getAllGeocache();
  83. for(Geocache g: geocaches) {
  84. if(ShowDistance.calculateDistance(latitude, g.getLatitude(), longitude, g.getLongitude()) < NOTIFICATION_DISTANCE) {
  85. showNotification(g);
  86. }
  87. else { // Cancel notification
  88. NotificationService.notificationManager.cancel(g.hashCode());
  89. }
  90. }
  91. }
  92. private void showNotification(Geocache g) {
  93. Notification notification = new Notification(R.drawable.atlas_logo, g.getName(), System.currentTimeMillis());
  94. notification.defaults = 0;
  95. Intent notifyIntent = new Intent(this, MapActivity.class);
  96. PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
  97. notification.setLatestEventInfo(getApplicationContext(), getString(R.string.app_name),
  98. g.getName(), contentIntent);
  99. NotificationService.notificationManager.notify(g.hashCode(), notification);
  100. }
  101. private final Runnable calculationLoop = new Runnable() {
  102. @Override
  103. public void run() {
  104. while(running) {
  105. checkForNearbyGeocaches();
  106. calculateCondition.block(THREAD_WAIT_TIME); // Block until new location is found, or timeout
  107. calculateCondition.close();
  108. }
  109. NotificationService.this.stopSelf();
  110. }
  111. };
  112. }